private int handleStateTransition()

in xstream/src/java/com/thoughtworks/xstream/io/json/AbstractJsonWriter.java [311:598]


    private int handleStateTransition(int currentState, final int requiredState, final String elementToAdd,
            final String valueToAdd) {
        final int size = stack.size();
        final Class<?> currentType = stack.peek().type;
        final boolean isArray = size > 1 && isArray(currentType);
        final boolean isArrayElement = size > 1 && isArray(stack.get(size - 2).type);
        switch (currentState) {
        case STATE_ROOT:
            if (requiredState == STATE_START_OBJECT) {
                currentState = handleStateTransition(STATE_START_ELEMENTS, STATE_START_OBJECT, elementToAdd, null);
                return requiredState;
            }
            throw new IllegalWriterStateException(currentState, requiredState, elementToAdd);

        case STATE_END_OBJECT:
            switch (requiredState) {
            case STATE_START_OBJECT:
                currentState = handleStateTransition(currentState, STATE_NEXT_ELEMENT, null, null);
                currentState = handleStateTransition(currentState, STATE_START_OBJECT, elementToAdd, null);
                return requiredState;
            case STATE_NEXT_ELEMENT:
                nextElement();
                return requiredState;
            case STATE_ROOT:
                if (((mode & DROP_ROOT_MODE) == 0 || size > 2) && (mode & EXPLICIT_MODE) == 0) {
                    endObject();
                }
                return requiredState;
            default:
                throw new IllegalWriterStateException(currentState, requiredState, elementToAdd);
            }

        case STATE_START_OBJECT:
            switch (requiredState) {
            case STATE_SET_VALUE:
            case STATE_START_OBJECT:
            case STATE_ROOT:
            case STATE_NEXT_ELEMENT:
                if (!isArrayElement || (mode & EXPLICIT_MODE) != 0) {
                    currentState = handleStateTransition(currentState, STATE_START_ATTRIBUTES, null, null);
                    currentState = handleStateTransition(currentState, STATE_END_ATTRIBUTES, null, null);
                }
                currentState = STATE_START_ELEMENTS;

                switch (requiredState) {
                case STATE_SET_VALUE:
                    currentState = handleStateTransition(currentState, STATE_SET_VALUE, null, valueToAdd);
                    break;
                case STATE_START_OBJECT:
                    currentState = handleStateTransition(currentState, STATE_START_OBJECT, elementToAdd, null);
                    break;
                case STATE_ROOT:
                case STATE_NEXT_ELEMENT:
                    currentState = handleStateTransition(currentState, STATE_SET_VALUE, null, null);
                    currentState = handleStateTransition(currentState, requiredState, null, null);
                    break;
                }
                return requiredState;
            case STATE_START_ATTRIBUTES:
                if ((mode & EXPLICIT_MODE) != 0) {
                    startArray();
                }
                return requiredState;
            case STATE_NEXT_ATTRIBUTE:
                if ((mode & EXPLICIT_MODE) != 0 || !isArray) {
                    currentState = handleStateTransition(currentState, STATE_START_ATTRIBUTES, null, null);
                    currentState = handleStateTransition(currentState, STATE_NEXT_ATTRIBUTE, elementToAdd, valueToAdd);
                    return requiredState;
                } else {
                    return STATE_START_OBJECT;
                }
            default:
                throw new IllegalWriterStateException(currentState, requiredState, elementToAdd);
            }

        case STATE_NEXT_ELEMENT:
            switch (requiredState) {
            case STATE_START_OBJECT:
                nextElement();
                if (!isArrayElement && (mode & EXPLICIT_MODE) == 0) {
                    addLabel(encodeNode(elementToAdd));
                    if ((mode & EXPLICIT_MODE) == 0 && isArray) {
                        startArray();
                    }
                    return requiredState;
                }
                break;
            case STATE_ROOT:
                currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null);
                currentState = handleStateTransition(currentState, STATE_ROOT, null, null);
                return requiredState;
            case STATE_NEXT_ELEMENT:
            case STATE_END_OBJECT:
                currentState = handleStateTransition(currentState, STATE_END_ELEMENTS, null, null);
                currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null);
                if ((mode & EXPLICIT_MODE) == 0 && !isArray) {
                    endObject();
                }
                return requiredState;
            case STATE_END_ELEMENTS:
                if ((mode & EXPLICIT_MODE) == 0 && isArray) {
                    endArray();
                }
                return requiredState;
            default:
                throw new IllegalWriterStateException(currentState, requiredState, elementToAdd);
            }
            //$FALL-THROUGH$
        case STATE_START_ELEMENTS:
            switch (requiredState) {
            case STATE_START_OBJECT:
                if ((mode & DROP_ROOT_MODE) == 0 || size > 2) {
                    if (!isArrayElement || (mode & EXPLICIT_MODE) != 0) {
                        if (!"".equals(valueToAdd)) {
                            startObject();
                        }
                        addLabel(encodeNode(elementToAdd));
                    }
                    if ((mode & EXPLICIT_MODE) != 0) {
                        startArray();
                    }
                }
                if ((mode & EXPLICIT_MODE) == 0) {
                    if (isArray) {
                        startArray();
                    }
                }
                return requiredState;
            case STATE_SET_VALUE:
                if ((mode & STRICT_MODE) != 0 && size == 2) {
                    throw new ConversionException("Single value cannot be root element");
                }
                if (valueToAdd == null) {
                    if (currentType == Mapper.Null.class) {
                        addValue("null", Type.NULL);
                    } else if ((mode & EXPLICIT_MODE) == 0 && !isArray) {
                        startObject();
                        endObject();
                    }
                } else {
                    if ((mode & IEEE_754_MODE) != 0 && (currentType == long.class || currentType == Long.class)) {
                        final long longValue = Long.parseLong(valueToAdd);
                        // JavaScript supports a maximum of 2^53
                        if (longValue > 9007199254740992L || longValue < -9007199254740992L) {
                            addValue(valueToAdd, Type.STRING);
                        } else {
                            addValue(valueToAdd, getType(currentType));
                        }
                    } else {
                        addValue(valueToAdd, getType(currentType));
                    }
                }
                return requiredState;
            case STATE_END_ELEMENTS:
            case STATE_NEXT_ELEMENT:
                if ((mode & EXPLICIT_MODE) == 0) {
                    if (isArray) {
                        endArray();
                    } else {
                        endObject();
                    }
                }
                return requiredState;
            default:
                throw new IllegalWriterStateException(currentState, requiredState, elementToAdd);
            }

        case STATE_END_ELEMENTS:
            switch (requiredState) {
            case STATE_END_OBJECT:
                if ((mode & EXPLICIT_MODE) != 0) {
                    endArray();
                    endArray();
                    endObject();
                }
                return requiredState;
            default:
                throw new IllegalWriterStateException(currentState, requiredState, elementToAdd);
            }

        case STATE_START_ATTRIBUTES:
            switch (requiredState) {
            case STATE_NEXT_ATTRIBUTE:
                if (elementToAdd != null) {
                    final String name = ((mode & EXPLICIT_MODE) == 0 ? "@" : "") + elementToAdd;
                    startObject();
                    addLabel(encodeAttribute(name));
                    addValue(valueToAdd, Type.STRING);
                }
                return requiredState;
            }
            //$FALL-THROUGH$
        case STATE_NEXT_ATTRIBUTE:
            switch (requiredState) {
            case STATE_END_ATTRIBUTES:
                if ((mode & EXPLICIT_MODE) != 0) {
                    if (currentState == STATE_NEXT_ATTRIBUTE) {
                        endObject();
                    }
                    endArray();
                    nextElement();
                    startArray();
                }
                return requiredState;
            case STATE_NEXT_ATTRIBUTE:
                if (!isArray || (mode & EXPLICIT_MODE) != 0) {
                    nextElement();
                    final String name = ((mode & EXPLICIT_MODE) == 0 ? "@" : "") + elementToAdd;
                    addLabel(encodeAttribute(name));
                    addValue(valueToAdd, Type.STRING);
                }
                return requiredState;
            case STATE_SET_VALUE:
            case STATE_START_OBJECT:
                currentState = handleStateTransition(currentState, STATE_END_ATTRIBUTES, null, null);
                currentState = handleStateTransition(currentState, STATE_START_ELEMENTS, null, null);
                switch (requiredState) {
                case STATE_SET_VALUE:
                    if ((mode & EXPLICIT_MODE) == 0) {
                        addLabel(encodeNode("$"));
                    }
                    currentState = handleStateTransition(currentState, STATE_SET_VALUE, null, valueToAdd);
                    if ((mode & EXPLICIT_MODE) == 0) {
                        endObject();
                    }
                    break;
                case STATE_START_OBJECT:
                    currentState = handleStateTransition(currentState, STATE_START_OBJECT, elementToAdd, (mode
                        & EXPLICIT_MODE) == 0 ? "" : null);
                    break;
                case STATE_END_OBJECT:
                    currentState = handleStateTransition(currentState, STATE_SET_VALUE, null, null);
                    currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null);
                    break;
                }
                return requiredState;
            case STATE_NEXT_ELEMENT:
                currentState = handleStateTransition(currentState, STATE_END_ATTRIBUTES, null, null);
                currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null);
                return requiredState;
            case STATE_ROOT:
                currentState = handleStateTransition(currentState, STATE_END_ATTRIBUTES, null, null);
                currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null);
                currentState = handleStateTransition(currentState, STATE_ROOT, null, null);
                return requiredState;
            default:
                throw new IllegalWriterStateException(currentState, requiredState, elementToAdd);
            }

        case STATE_END_ATTRIBUTES:
            switch (requiredState) {
            case STATE_START_ELEMENTS:
                if ((mode & EXPLICIT_MODE) == 0) {
                    nextElement();
                }
                break;
            case STATE_END_OBJECT:
                currentState = handleStateTransition(STATE_START_ELEMENTS, STATE_END_ELEMENTS, null, null);
                currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null);
                break;
            default:
                throw new IllegalWriterStateException(currentState, requiredState, elementToAdd);
            }
            return requiredState;

        case STATE_SET_VALUE:
            switch (requiredState) {
            case STATE_END_ELEMENTS:
                if ((mode & EXPLICIT_MODE) == 0 && isArray) {
                    endArray();
                }
                return requiredState;
            case STATE_NEXT_ELEMENT:
                currentState = handleStateTransition(currentState, STATE_END_ELEMENTS, null, null);
                currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null);
                return requiredState;
            case STATE_ROOT:
                currentState = handleStateTransition(currentState, STATE_END_ELEMENTS, null, null);
                currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null);
                currentState = handleStateTransition(currentState, STATE_ROOT, null, null);
                return requiredState;
            default:
                throw new IllegalWriterStateException(currentState, requiredState, elementToAdd);
            }
        }

        throw new IllegalWriterStateException(currentState, requiredState, elementToAdd);
    }