devdaily home | apple | java | perl | unix | directory | blog

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.
 */
package org.apache.axis2.databinding.utils;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.util.ArrayList;
import java.util.List;

/** A state machine that reads arrays with simple content. returns a string array */
public class SimpleArrayReaderStateMachine implements States, Constants {

    private QName elementNameToTest = null;
    private int currentState = INIT_STATE;
    private boolean nillable = false;

    private boolean canbeAbsent = false;

    private List list = new ArrayList();

    /** @return an array of strings */
    public String[] getTextArray() {
        return (String[])list.toArray(new String[list.size()]);
    }


    public void setNillable() {
        nillable = true;
    }

    public boolean isCanbeAbsent() {
        return canbeAbsent;
    }

    public void setCanbeAbsent(boolean canbeAbsent) {
        this.canbeAbsent = canbeAbsent;
    }

    /**
     * Resets the state machine. Once the reset is called the state machine is good enough for a
     * fresh run
     */
    public void reset() {
        elementNameToTest = null;
        currentState = INIT_STATE;
        nillable = false;
        list = new ArrayList();
    }

    public void setElementNameToTest(QName elementNameToTest) {
        this.elementNameToTest = elementNameToTest;
    }

    /**
     * public read method - reads a given reader to extract the text value
     *
     * @param reader
     */
    public void read(XMLStreamReader reader) throws XMLStreamException {

        do {
            updateState(reader);

            //test for the nillable attribute
            if (currentState == START_ELEMENT_FOUND_STATE &&
                    nillable) {
                if (TRUE.equals(reader.getAttributeValue(XSI_NAMESPACE, NIL))) {
                    list.add(null);
                    //force the state to be null found
                    currentState = NULLED_STATE;
                }
            }

            if (currentState == TEXT_FOUND_STATE) {
                //read the text value and store it in the list
                list.add(reader.getText());
            }
            //increment the parser only if the  state is
            //not finished
            if (currentState != FINISHED_STATE
                    && currentState != ILLEGAL_STATE) {
                reader.next();
            }

        } while (currentState != FINISHED_STATE
                && currentState != ILLEGAL_STATE);

        if (currentState == ILLEGAL_STATE) {
            throw new RuntimeException("Illegal state!");
        }

    }


    private void updateState(XMLStreamReader reader) throws XMLStreamException {
        int event = reader.getEventType();

        switch (currentState) {

            case INIT_STATE:
                if (event == XMLStreamConstants.START_DOCUMENT) {
                    currentState = STARTED_STATE;
                } else if (event == XMLStreamConstants.START_ELEMENT) {
                    if (elementNameToTest.equals(reader.getName())) {
                        currentState = START_ELEMENT_FOUND_STATE;
                    } else {
                        //we found a start element that does not have
                        //the name of the element

                        currentState = canbeAbsent ?
                                FINISHED_STATE :
                                STARTED_STATE;
                    }
                } else if (event == XMLStreamConstants.END_ELEMENT) {
                    // an end element is found at the init state
                    // we should break the process here ?
                    if (!elementNameToTest.equals(reader.getName())) {
                        currentState = FINISHED_STATE;
                    }
                }
                break;

            case STARTED_STATE:
                if (event == XMLStreamConstants.END_ELEMENT) {
                    if (elementNameToTest.equals(reader.getName())) {
                        currentState = ILLEGAL_STATE;
                    } else {
                        currentState = FINISHED_STATE;
                    }
                } else if (event == XMLStreamConstants.START_ELEMENT) {
                    QName name = reader.getName();
                    if (elementNameToTest.equals(name)) {
                        currentState = START_ELEMENT_FOUND_STATE;
                    }
                }
                break;

            case START_ELEMENT_FOUND_STATE:
                if (event == XMLStreamConstants.CHARACTERS) {
                    currentState = TEXT_FOUND_STATE;
                }
                break;

            case TEXT_FOUND_STATE:
                if (event == XMLStreamConstants.END_ELEMENT) {
                    if (elementNameToTest.equals(reader.getName())) {
                        currentState = END_ELEMENT_FOUND_STATE;
                    } else {
                        currentState = ILLEGAL_STATE;
                    }
                } else if (event == XMLStreamConstants.CHARACTERS) {
                    //another char event -
                    //so append it to the current text
                }
                break;
            case NULLED_STATE:
                //read upto the end and set the state to END_ELEMENT_FOUND_STATE
                while (event != XMLStreamConstants.END_ELEMENT) {
                    event = reader.next();
                }
                currentState = END_ELEMENT_FOUND_STATE;
                break;
            case END_ELEMENT_FOUND_STATE:
                if (event == XMLStreamConstants.START_ELEMENT) {
                    //restart the parsing
                    if (elementNameToTest.equals(reader.getName())) {
                        currentState = START_ELEMENT_FOUND_STATE;
                    } else {
                        currentState = FINISHED_STATE;
                    }
                    //another end element found after end-element
                } else if (event == XMLStreamConstants.END_ELEMENT) {
                    currentState = FINISHED_STATE;
                    //end  document found
                }
                break;
            default:

                //characters found - if this is a characters event that was in the correct place then
                //it would have been handled already. we need to check whether this is a ignorable
                //whitespace and if not push the state machine to a illegal state.
                if (event == XMLStreamConstants.CHARACTERS) {
                    if (reader.getText().trim().length() == 0) {
                        //the text is empty - don't change the state
                    } else {
                        //we do NOT handle mixed content
                        currentState = ILLEGAL_STATE;
                    }

                } else {
                    currentState = ILLEGAL_STATE;
                }

        }

    }


}




Copyright 1998-2008 Alvin Alexander
All Rights Reserved.
 
devdaily.com is based in louisville, kentucky, and this web site is hosted by godaddy.com