jsonxmlstreamreader.java

来自「resetful样式的ws样例,一种面向资源的webservices服务」· Java 代码 · 共 704 行 · 第 1/2 页

JAVA
704
字号
/* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. *  * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. *  * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License").  You * may not use this file except in compliance with the License. You can obtain * a copy of the License at https://jersey.dev.java.net/CDDL+GPL.html * or jersey/legal/LICENSE.txt.  See the License for the specific * language governing permissions and limitations under the License. *  * When distributing the software, include this License Header Notice in each * file and include the License file at jersey/legal/LICENSE.txt. * Sun designates this particular file as subject to the "Classpath" exception * as provided by Sun in the GPL Version 2 section of the License file that * accompanied this code.  If applicable, add the following below the License * Header, with the fields enclosed by brackets [] replaced by your own * identifying information: "Portions Copyrighted [year] * [name of copyright owner]" *  * Contributor(s): *  * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license."  If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above.  However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */package com.sun.jersey.impl.json.reader;import java.io.IOException;import java.io.Reader;import java.util.ArrayList;import java.util.LinkedList;import java.util.List;import java.util.Queue;import java.util.logging.Level;import java.util.logging.Logger;import javax.xml.namespace.NamespaceContext;import javax.xml.namespace.QName;import javax.xml.stream.Location;import javax.xml.stream.XMLStreamException;import javax.xml.stream.XMLStreamReader;/** * * @author japod */public class JsonXmlStreamReader implements XMLStreamReader {            private enum LaState {         START,         END,         AFTER_OBJ_START_BRACE,         BEFORE_OBJ_NEXT_KV_PAIR,         BEFORE_COLON_IN_KV_PAIR,         BEFORE_VALUE_IN_KV_PAIR,         AFTER_OBJ_KV_PAIR,         AFTER_ARRAY_START_BRACE,         BEFORE_NEXT_ARRAY_ELEM,         AFTER_ARRAY_ELEM    };        static class MyLocation implements Location {                int charOffset = -1;        int column = -1;        int line = -1;                MyLocation(final int charOffset, final int column, final int line) {            this.charOffset = charOffset;            this.column = column;            this.line = line;        }                MyLocation(final JsonLexer lexer) {            this(lexer.getCharOffset(), lexer.getColumn(), lexer.getLineNumber());        }        public int getCharacterOffset() {            return charOffset;        }        public int getColumnNumber() {            return column;        }        public int getLineNumber() {            return line;        }        public String getPublicId() {            return null;        }        public String getSystemId() {            return null;        }            }        private static final Logger LOGGER = Logger.getLogger(JsonXmlStreamReader.class.getName());           boolean jsonRootUnwrapping;    JsonLexer lexer;    JsonToken lastToken;        private static final class ProcessingState {        String lastName;        LaState state;        JsonReaderXmlEvent eventToReadAttributesFor;                ProcessingState() {            this(LaState.START);        }                ProcessingState(LaState state) {            this(state, null);        }                ProcessingState(LaState state, String name) {            this.state = state;            this.lastName = name;        }    }        final Queue<JsonReaderXmlEvent> eventQueue = new LinkedList<JsonReaderXmlEvent>();        List<ProcessingState> processingStack;    int depth;    public JsonXmlStreamReader(Reader reader) throws IOException {        this(reader, false);    }        public JsonXmlStreamReader(Reader reader, boolean jsonRootUnwrapping) throws IOException {        this.jsonRootUnwrapping = jsonRootUnwrapping;        lexer = new JsonLexer(reader);         depth = 0;        processingStack = new ArrayList<ProcessingState>();        processingStack.add(new ProcessingState());        readNext();    }        void colon() throws IOException {        JsonToken token = nextToken();        if (token.tokenType != JsonToken.COLON) {            throw new IOException("Colon expected instead of \"" + token.tokenText + "\"");        }    }        JsonToken nextToken() throws IOException {        JsonToken result = lexer.yylex();        //System.out.println("token=" + result + " depth=" + depth + " state=" + processingStack.elementAt(depth).state);        return result;    }        private void valueRead() {        if (LaState.BEFORE_VALUE_IN_KV_PAIR == processingStack.get(depth).state) {            processingStack.get(depth).state = LaState.AFTER_OBJ_KV_PAIR;        } else if (LaState.BEFORE_NEXT_ARRAY_ELEM == processingStack.get(depth).state) {            processingStack.get(depth).state = LaState.AFTER_ARRAY_ELEM;        } else if (LaState.AFTER_ARRAY_START_BRACE == processingStack.get(depth).state) {            processingStack.get(depth).state = LaState.AFTER_ARRAY_ELEM;        }    }        private void readNext() throws IOException {        readNext(false);    }        private void readNext(boolean checkAttributesOnly) throws IOException {        if (!checkAttributesOnly) {            eventQueue.poll();        }        //boolean attributesStarted = false;        while (eventQueue.isEmpty() || checkAttributesOnly) {            lastToken = nextToken();            if ((null == lastToken) || (LaState.END == processingStack.get(depth).state)){                if (jsonRootUnwrapping) {                    generateEEEvent(processingStack.get(depth).lastName);                }                eventQueue.add(new EndDocumentEvent(new MyLocation(lexer)));                break;            }            switch (processingStack.get(depth).state) {                case START:                    if (0 == depth) {                        eventQueue.add(new StartDocumentEvent(new MyLocation(lexer)));                        processingStack.get(depth).state = LaState.AFTER_OBJ_START_BRACE;                        if (jsonRootUnwrapping) {                            processingStack.get(depth).lastName = "rootObject";                            StartElementEvent event = generateSEEvent(processingStack.get(depth).lastName);                            processingStack.get(depth).eventToReadAttributesFor = event;                        }                        switch (lastToken.tokenType) {                            case JsonToken.START_OBJECT:                                processingStack.add(new ProcessingState(LaState.AFTER_OBJ_START_BRACE));                                depth++;                                break;                            case JsonToken.START_ARRAY:                                processingStack.add(new ProcessingState(LaState.AFTER_ARRAY_START_BRACE));                                depth++;                                break;                            case JsonToken.STRING:                            case JsonToken.NUMBER:                            case JsonToken.TRUE:                            case JsonToken.FALSE:                            case JsonToken.NULL:                                eventQueue.add(new CharactersEvent(lastToken.tokenText, new MyLocation(lexer)));                                processingStack.get(depth).state = LaState.END;                                break;                            default:                            // TODO: handle problem                        }                    }                    // TODO: if JsonToken.START_OBJECT != lastToken then problem                    processingStack.get(depth).state = LaState.AFTER_OBJ_START_BRACE;                    break;                case AFTER_OBJ_START_BRACE:                    switch (lastToken.tokenType) {                        case JsonToken.STRING:                            if (lastToken.tokenText.startsWith("@")) { // eat attributes                                //attributesStarted = true;                                String attrName = lastToken.tokenText;                                colon();                                lastToken = nextToken();                                // TODO process attr value                                if (JsonToken.STRING != lastToken.tokenType) {                                    throw new IOException("Attribute value expected instead of \"" + lastToken.tokenText + "\"");                                }                                if (null != processingStack.get(depth - 1).eventToReadAttributesFor) {                                    processingStack.get(depth - 1).eventToReadAttributesFor.addAttribute(                                            attrName.substring(1), lastToken.tokenText);                                }                                lastToken = nextToken();                                switch (lastToken.tokenType) {                                    case JsonToken.END_OBJECT:                                        generateEEEvent(processingStack.get(depth).lastName);                                        processingStack.remove(depth);                                        depth--;                                        break;                                    case JsonToken.COMMA:                                        break;                                    default:                                        throw new IOException("\'\"\', or \'}\' expected instead of \"" + lastToken.tokenText + "\"");                                }                            } else { // non attribute                                StartElementEvent event =                                        generateSEEvent(lastToken.tokenText);                                processingStack.get(depth).eventToReadAttributesFor = event;                                checkAttributesOnly = false;                                processingStack.get(depth).lastName = lastToken.tokenText;                                colon();                                processingStack.get(depth).state = LaState.BEFORE_VALUE_IN_KV_PAIR;                            }                            break;                        case JsonToken.END_OBJECT: // empty object/element                            generateEEEvent(processingStack.get(depth).lastName);                            checkAttributesOnly = false;                            processingStack.remove(depth);                            depth--;                            break;                        default:                        // TODO: handle problem                    }                    break;                case BEFORE_OBJ_NEXT_KV_PAIR:                    switch (lastToken.tokenType) {                        case JsonToken.STRING:                            StartElementEvent event =                                    generateSEEvent(lastToken.tokenText);                            processingStack.get(depth).eventToReadAttributesFor = event;                            processingStack.get(depth).lastName = lastToken.tokenText;                            colon();                            processingStack.get(depth).state = LaState.BEFORE_VALUE_IN_KV_PAIR;                            break;                        default:                        // TODO: handle problem                    }                    break;                case BEFORE_VALUE_IN_KV_PAIR:                    switch (lastToken.tokenType) {                        case JsonToken.START_OBJECT:                            processingStack.add(new ProcessingState(LaState.AFTER_OBJ_START_BRACE));                            depth++;                            break;                        case JsonToken.START_ARRAY:                            processingStack.add(new ProcessingState(LaState.AFTER_ARRAY_START_BRACE));                            depth++;                            break;                        case JsonToken.STRING:                        case JsonToken.NUMBER:                        case JsonToken.TRUE:                        case JsonToken.FALSE:                        case JsonToken.NULL:                            eventQueue.add(new CharactersEvent(lastToken.tokenText, new MyLocation(lexer)));                            processingStack.get(depth).state = LaState.AFTER_OBJ_KV_PAIR;                            break;                        default:                        // TODO: handle problem                    }                    break; // AFTER_ARRAY_ELEM                case AFTER_OBJ_KV_PAIR:                    switch (lastToken.tokenType) {                        case JsonToken.COMMA:                            processingStack.get(depth).state = LaState.BEFORE_OBJ_NEXT_KV_PAIR;                            generateEEEvent(processingStack.get(depth).lastName);                            break; // STRING                        case JsonToken.END_OBJECT: // empty object/element                            generateEEEvent(processingStack.get(depth).lastName);                            processingStack.remove(depth);                            depth--;                            valueRead();                            break; // END_OBJECT                        default:                        // TODO: handle problem                    }                    break; // AFTER_OBJ_KV_PAIR                case AFTER_ARRAY_START_BRACE:                    switch (lastToken.tokenType) {                        case JsonToken.START_OBJECT:                            processingStack.add(new ProcessingState(LaState.AFTER_OBJ_START_BRACE));                            processingStack.get(depth).eventToReadAttributesFor = processingStack.get(depth - 1).eventToReadAttributesFor;                            depth++;                            break;                        case JsonToken.START_ARRAY:                            processingStack.add(new ProcessingState(LaState.AFTER_ARRAY_START_BRACE));                            depth++;                            break;                        case JsonToken.END_ARRAY:                            processingStack.remove(depth);                            depth--;                            valueRead();                            break;                        case JsonToken.STRING:                            eventQueue.add(new CharactersEvent(lastToken.tokenText, new MyLocation(lexer)));                            processingStack.get(depth).state = LaState.AFTER_ARRAY_ELEM;                            break;                        default:                        // TODO: handle problem

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?