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

org.wildfly.plugin.tools.bootablejar.Expression Maven / Gradle / Ivy

/*
 * Copyright The WildFly Authors
 * SPDX-License-Identifier: Apache-2.0
 */

package org.wildfly.plugin.tools.bootablejar;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.jboss.dmr.ValueExpression;

/**
 * A simple expression parser which only parses the possible keys and default values.
 *
 * @author James R. Perkins
 */
class Expression {

    private static final int INITIAL = 0;
    private static final int GOT_DOLLAR = 1;
    private static final int GOT_OPEN_BRACE = 2;
    private static final int RESOLVED = 3;
    private static final int DEFAULT = 4;

    private final List keys;
    private final String defaultValue;

    private Expression(final Collection keys, final String defaultValue) {
        this.keys = new ArrayList<>(keys);
        this.defaultValue = defaultValue;
    }

    /**
     * Creates a collection of expressions based on the value.
     *
     * @param value the expression value
     *
     * @return the expression keys and default value for each expression found within the value
     */
    static Collection parse(final ValueExpression value) {
        return parseExpression(value.getExpressionString());
    }

    /**
     * Creates a collection of expressions based on the value.
     *
     * @param expression the expression value
     *
     * @return the expression keys and default value for each expression found within the value
     */
    static Collection parse(final String expression) {
        return parseExpression(expression);
    }

    /**
     * All the keys associated with this expression.
     *
     * @return the keys
     */
    List getKeys() {
        return Collections.unmodifiableList(keys);
    }

    /**
     * Checks if there is a default value.
     *
     * @return {@code true} if the default value is not {@code null}, otherwise {@code false}
     */
    boolean hasDefault() {
        return defaultValue != null;
    }

    /**
     * Returns the default value which may be {@code null}.
     *
     * @return the default value
     */
    String getDefaultValue() {
        return defaultValue;
    }

    void appendTo(final StringBuilder builder) {
        builder.append("${");
        final Iterator iter = keys.iterator();
        while (iter.hasNext()) {
            builder.append(iter.next());
            if (iter.hasNext()) {
                builder.append(',');
            }
        }
        if (hasDefault()) {
            builder.append(':').append(defaultValue);
        }
        builder.append('}');
    }

    @Override
    public String toString() {
        final StringBuilder builder = new StringBuilder();
        appendTo(builder);
        return builder.toString();
    }

    private static Collection parseExpression(final String expression) {
        final Collection result = new ArrayList<>();
        final Collection keys = new ArrayList<>();
        final StringBuilder key = new StringBuilder();
        String defaultValue = null;
        final char[] chars = expression.toCharArray();
        final int len = chars.length;
        int state = 0;
        int start = -1;
        int nameStart = -1;
        for (int i = 0; i < len; i++) {
            char ch = chars[i];
            switch (state) {
                case INITIAL: {
                    if (ch == '$') {
                        state = GOT_DOLLAR;
                    }
                    continue;
                }
                case GOT_DOLLAR: {
                    if (ch == '{') {
                        start = i + 1;
                        nameStart = start;
                        state = GOT_OPEN_BRACE;
                    } else {
                        // invalid; emit and resume
                        state = INITIAL;
                    }
                    continue;
                }
                case GOT_OPEN_BRACE: {
                    switch (ch) {
                        case ':':
                        case '}':
                        case ',': {
                            final String name = expression.substring(nameStart, i).trim();
                            if ("/".equals(name)) {
                                state = ch == '}' ? INITIAL : RESOLVED;
                                continue;
                            } else if (":".equals(name)) {
                                state = ch == '}' ? INITIAL : RESOLVED;
                                continue;
                            }
                            key.append(name);
                            if (ch == '}') {
                                state = INITIAL;
                                if (key.length() > 0) {
                                    keys.add(key.toString());
                                    key.setLength(0);
                                }
                                result.add(new Expression(keys, defaultValue));
                                defaultValue = null;
                                keys.clear();
                                continue;
                            } else if (ch == ',') {
                                if (key.length() > 0) {
                                    keys.add(key.toString());
                                    key.setLength(0);
                                }
                                nameStart = i + 1;
                                continue;
                            } else {
                                start = i + 1;
                                state = DEFAULT;
                                if (key.length() > 0) {
                                    keys.add(key.toString());
                                    key.setLength(0);
                                }
                                continue;
                            }
                        }
                        default: {
                            continue;
                        }
                    }
                }
                case RESOLVED: {
                    if (ch == '}') {
                        state = INITIAL;
                        if (!keys.isEmpty()) {
                            result.add(new Expression(keys, defaultValue));
                            defaultValue = null;
                            keys.clear();
                        }
                    }
                    continue;
                }
                case DEFAULT: {
                    if (ch == '}') {
                        state = INITIAL;
                        defaultValue = expression.substring(start, i);
                        if (key.length() > 0) {
                            keys.add(key.toString());
                            key.setLength(0);
                        }
                        if (!keys.isEmpty()) {
                            result.add(new Expression(keys, defaultValue));
                            defaultValue = null;
                            keys.clear();
                        }
                    }
                    continue;
                }
                default:
                    throw new IllegalStateException();
            }
        }
        if (key.length() > 0) {
            keys.add(key.toString());
            result.add(new Expression(keys, defaultValue));
        }
        return result;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy