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;
}
}
}
Aggregations