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

org.javamoney.moneta.internal.format.ParseContext Maven / Gradle / Ivy

Go to download

JSR 354 provides an API for representing, transporting, and performing comprehensive calculations with Money and Currency. This module implements JSR 354.

There is a newer version: 1.4.1
Show newest version
/*
 * Copyright (c) 2012, 2014, Credit Suisse (Anatole Tresch), Werner Keil and others by the @author tag.
 *
 * 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.
 */
package org.javamoney.moneta.internal.format;

import java.text.ParsePosition;
import java.util.Objects;

import javax.money.CurrencyUnit;
import javax.money.MonetaryAmount;
import javax.money.format.MonetaryAmountFormat;

/**
 * Context passed along to each {@link FormatToken} in-line, when parsing an
 * input stream using a {@link MonetaryAmountFormat}. It allows to inspect the
 * next tokens, the whole input String, or just the current input substring,
 * based on the current parsing position etc.
 *
 * This class is mutable and intended for use by a single thread. A new instance
 * is created for each parse.
 */
final class ParseContext {
    /**
     * The current position of parsing.
     */
    private int index;
    /**
     * The error index position.
     */
    private int errorIndex = -1;
    /**
     * The full input.
     */
    private final CharSequence originalInput;
    /**
     * The currency parsed, used for creation of the {@link MonetaryAmount}.
     */
    private CurrencyUnit parsedCurrency;
    /**
     * The numeric part of the {@link MonetaryAmount} parsed.
     */
    private Number parsedNumber;
    /**
     * The parse error message.
     */
    private String errorMessage;

    /**
     * Creates a new {@link ParseContext} with the given input.
     *
     * @param text The test to be parsed.
     */
    public ParseContext(CharSequence text) {
        this.originalInput = text;
        if(text==null) {
            throw new IllegalArgumentException("text is required");
        }
    }

    /**
     * Method allows to determine if the item being parsed is available from the
     * {@link ParseContext}.
     *
     * @return true, if the item is available.
     */
    public boolean isComplete() {
        return parsedNumber!=null && parsedCurrency!=null;
    }

    /**
     * Get the parsed item.
     *
     * @return the item parsed.
     */
    public Number getParsedNumber() {
        return parsedNumber;
    }

    /**
     * Consumes the given token. If the current residual text to be parsed
     * starts with the parsing index is increased by {@code token.size()}.
     *
     * @param token The token expected.
     * @return true, if the token could be consumed and the index was increased
     * by {@code token.size()}.
     */
    public boolean consume(String token) {
        if (getInput().toString().startsWith(token)) {
            index += token.length();
            return true;
        }
        return false;
    }

    /**
     * Tries to consume one single character.
     *
     * @param c the next character being expected.
     * @return true, if the character matched and the index could be increased
     * by one.
     */
    public boolean consume(char c) {
        if (originalInput.charAt(index) == c) {
            index++;
            return true;
        }
        return false;
    }

    /**
     * Skips all whitespaces until a non whitespace character is occurring. If
     * the next character is not whitespace this method does nothing.
     *
     * @return the new parse index after skipping any whitespaces.
     * @see Character#isWhitespace(char)
     */
    public int skipWhitespace() {
        for (int i = index; i < originalInput.length(); i++) {
            if (Character.isWhitespace(originalInput.charAt(i))) {
                index++;
            } else {
                break;
            }
        }
        return index;
    }

    /**
     * Gets the error index.
     *
     * @return the error index, negative if no error
     */
    public int getErrorIndex() {
        return errorIndex;
    }

    /**
     * Sets the error index.
     *
     * @param index the error index
     */
    public void setErrorIndex(int index) {
        this.errorIndex = index;
    }

    /**
     * Get the stored error message.
     *
     * @return the stored error message, or null.
     */
    public String getErrorMessage() {
        return this.errorMessage;
    }

    /**
     * Sets the error index from the current index.
     */
    public void setError() {
        this.errorIndex = index;
    }

    /**
     * Gets the current parse position.
     *
     * @return the current parse position within the input.
     */
    public int getIndex() {
        return index;
    }

    /**
     * Gets the residual input text starting from the current parse position.
     *
     * @return the residual input text
     */
    public CharSequence getInput() {
        return originalInput.subSequence(index, originalInput.length());
    }

    /**
     * Gets the full input text.
     *
     * @return the full input.
     */
    public String getOriginalInput() {
        return originalInput.toString();
    }

    /**
     * Resets this instance; this will resetToFallback the parsing position, the error
     * index and also all containing results.
     */
    public void reset() {
        this.index = 0;
        this.errorIndex = -1;
        this.parsedNumber = null;
        this.parsedCurrency = null;
    }

    /**
     * Sets the parsed numeric value into the context.
     *
     * @param number The result number
     */
    public void setParsedNumber(Number number) {
        this.parsedNumber = number;
    }

    /**
     * Set the parsed currency into the context.
     *
     * @param currency The parsed currency
     */
    public void setParsedCurrency(CurrencyUnit currency) {
        this.parsedCurrency = currency;
    }

    /**
     * Checks if the parse has found an error.
     *
     * @return whether a parse error has occurred
     */
    public boolean hasError() {
        return errorIndex >= 0;
    }

    /**
     * Checks if the text has been fully parsed such that there is no more text
     * to parse.
     *
     * @return true if fully parsed
     */
    public boolean isFullyParsed() {
        return index == this.originalInput.length();
    }

    /**
     * This method skips all whitespaces and returns the full text, until
     * another whitespace area or the end of the input is reached. The method
     * will not update any index pointers.
     *
     * @return the next token found, or null.
     */
    public String lookupNextToken() {
        skipWhitespace();
        int start = index;
        for (int end = index; end < originalInput.length(); end++) {
            if (Character.isWhitespace(originalInput.charAt(end))) {
                if (end > start) {
                    return originalInput.subSequence(start, end).toString();
                }
                return null;
            }
        }
        if (start < originalInput.length()) {
            return originalInput.subSequence(start, originalInput.length())
                    .toString();
        }
        return null;
    }

    /**
     * Converts the indexes to a parse position.
     *
     * @return the parse position, never null
     */
    public ParsePosition toParsePosition() {
        return new ParsePosition(index);
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return "ParseContext [index=" + index + ", errorIndex=" + errorIndex
                + ", originalInput='" + originalInput + "', parsedNumber="
                + parsedNumber + "', parsedCurrency=" + parsedCurrency
                + ']';
    }

    public CurrencyUnit getParsedCurrency() {
        return parsedCurrency;
    }

    public void setErrorMessage(String message) {
        Objects.requireNonNull(message);
        this.errorMessage = message;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy