Search in sources :

Example 1 with FunctionTree

use of com.cinchapi.ccl.syntax.FunctionTree in project concourse by cinchapi.

the class Convert method stringToJava.

/**
 * Analyze {@code value} and convert it to the appropriate Java primitive or
 * Object.
 * <p>
 * <h1>Conversion Rules</h1>
 * <ul>
 * <li><strong>String</strong> - the value is converted to a string if it
 * starts and ends with matching single (') or double ('') quotes.
 * Alternatively, the value is converted to a string if it cannot be
 * converted to another type</li>
 * <li><strong>{@link ResolvableLink}</strong> - the value is converted to a
 * ResolvableLink if it is a properly formatted specification returned from
 * the {@link #stringToResolvableLinkSpecification(String, String)} method
 * (<strong>NOTE: </strong> this is a rare case)</li>
 * <li><strong>{@link Link}</strong> - the value is converted to a Link if
 * it is an int or long that is prepended by an '@' sign (i.e. @1234)</li>
 * <li><strong>Boolean</strong> - the value is converted to a Boolean if it
 * is equal to 'true', or 'false' regardless of case</li>
 * <li><strong>Double</strong> - the value is converted to a double if and
 * only if it is a decimal number that is immediately followed by a single
 * capital "D" (e.g. 3.14D)</li>
 * <li><strong>Tag</strong> - the value is converted to a Tag if it starts
 * and ends with matching (`) quotes</li>
 * <li><strong>Integer, Long, Float</strong> - the value is converted to a
 * non double number depending upon whether it is a standard integer (e.g.
 * less than {@value java.lang.Integer#MAX_VALUE}), a long, or a floating
 * point decimal</li>
 * <li><strong>Function</strong> - the value is converted to a
 * {@link Function} if it is not quoted and can be parsed as such by the
 * {@link ConcourseCompiler}.</li>
 * </ul>
 * </p>
 *
 * @param value
 * @return the converted value
 */
public static Object stringToJava(String value) {
    if (value.isEmpty()) {
        return value;
    }
    char first = value.charAt(0);
    char last = value.charAt(value.length() - 1);
    Long record;
    if (AnyStrings.isWithinQuotes(value, TAG_MARKER)) {
        // keep value as string since its between single or double quotes
        return value.substring(1, value.length() - 1);
    } else if (first == '@' && (record = Longs.tryParse(value.substring(1, value.length()))) != null) {
        return Link.to(record);
    } else if (first == '@' && last == '@' && STRING_RESOLVABLE_LINK_REGEX.matcher(value).matches()) {
        String ccl = value.substring(1, value.length() - 1);
        return ResolvableLink.create(ccl);
    } else if (value.equalsIgnoreCase("true")) {
        return true;
    } else if (value.equalsIgnoreCase("false")) {
        return false;
    } else if (first == TAG_MARKER && last == TAG_MARKER) {
        return Tag.create(value.substring(1, value.length() - 1));
    } else if (first == '|' && last == '|') {
        value = value.substring(1, value.length() - 1);
        String[] toks = value.split("\\|");
        Timestamp timestamp;
        if (toks.length == 1) {
            // #value is a timestring that intends to rely on either one of
            // the built-in DateTimeFormatters or the natural language
            // translation in order to figure out the microseconds with
            // which to create the Timestamp
            timestamp = Timestamp.fromMicros(NaturalLanguage.parseMicros(value));
        } else {
            // #value looks like timestring|format in which case the second
            // part is the DateTimeFormatter to use for getting the
            // microseconds with which to create the Timestamp
            // Valid formatting options can be found at
            // http://www.joda.org/joda-time/apidocs/org/joda/time/format/DateTimeFormat.html
            DateTimeFormatter formatter = DateTimeFormat.forPattern(toks[1]);
            timestamp = Timestamp.parse(toks[0], formatter);
        }
        return timestamp;
    } else {
        if (last == ')') {
            // cannot serve as a evaluation value
            try {
                FunctionTree tree = (FunctionTree) ConcourseCompiler.get().parse(value);
                FunctionValueSymbol symbol = (FunctionValueSymbol) tree.root();
                return symbol.function();
            } catch (Exception e) {
            /* ignore */
            }
        }
        try {
            return MoreObjects.firstNonNull(AnyStrings.tryParseNumber(value), value);
        } catch (NumberFormatException e) {
            return value;
        }
    }
}
Also used : FunctionTree(com.cinchapi.ccl.syntax.FunctionTree) FunctionValueSymbol(com.cinchapi.ccl.grammar.FunctionValueSymbol) Timestamp(com.cinchapi.concourse.Timestamp) DateTimeFormatter(org.joda.time.format.DateTimeFormatter) JsonParseException(com.google.gson.JsonParseException) IOException(java.io.IOException)

Aggregations

FunctionValueSymbol (com.cinchapi.ccl.grammar.FunctionValueSymbol)1 FunctionTree (com.cinchapi.ccl.syntax.FunctionTree)1 Timestamp (com.cinchapi.concourse.Timestamp)1 JsonParseException (com.google.gson.JsonParseException)1 IOException (java.io.IOException)1 DateTimeFormatter (org.joda.time.format.DateTimeFormatter)1