in odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTime.java [54:156]
protected <T> T internalValueOfString(final String value, final EdmLiteralKind literalKind, final EdmFacets facets,
final Class<T> returnType) throws EdmSimpleTypeException {
// In JSON, we allow also the XML literal form, so there is on purpose
// no exception if the JSON pattern does not match.
if (literalKind == EdmLiteralKind.JSON) {
final Matcher matcher = JSON_PATTERN.matcher(value);
if (matcher.matches()) {
long millis;
try {
millis = Long.parseLong(matcher.group(1));
} catch (final NumberFormatException e) {
throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value), e);
}
if (returnType.isAssignableFrom(Long.class)) {
return returnType.cast(millis);
} else if (returnType.isAssignableFrom(Date.class)) {
return returnType.cast(new Date(millis));
} else if (returnType.isAssignableFrom(Calendar.class)) {
Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
dateTimeValue.clear();
dateTimeValue.setTimeInMillis(millis);
return returnType.cast(dateTimeValue);
} else {
throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType));
}
}
}
Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
dateTimeValue.clear();
String valueString;
if (literalKind == EdmLiteralKind.URI) {
//OLINGO-883 prefix is case insensitve so we need to check with lower case if we want to use startsWith()
if (value.length() > 10 && value.toLowerCase().startsWith("datetime'") && value.endsWith("'")) {
valueString = value.substring(9, value.length() - 1);
} else {
throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
}
} else {
valueString = value;
}
final Matcher matcher = PATTERN.matcher(valueString);
if (!matcher.matches()) {
throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
}
dateTimeValue.set(
Short.parseShort(matcher.group(1)),
Byte.parseByte(matcher.group(2)) - 1, // month is zero-based
Byte.parseByte(matcher.group(3)),
Byte.parseByte(matcher.group(4)),
Byte.parseByte(matcher.group(5)),
matcher.group(6) == null ? 0 : Byte.parseByte(matcher.group(6)));
int nanoSeconds = 0;
if (matcher.group(7) != null) {
if (matcher.group(7).length() == 1 || matcher.group(7).length() > 10) {
throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
}
final String decimals = matcher.group(8);
if (facets != null && facets.getPrecision() != null && facets.getPrecision() < decimals.length()) {
throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_FACETS_NOT_MATCHED.addContent(value, facets));
}
nanoSeconds = Integer.parseInt(decimals + "000000000".substring(decimals.length()));
if (!(returnType.isAssignableFrom(Timestamp.class))) {
if (nanoSeconds % (1000 * 1000) == 0) {
dateTimeValue.set(Calendar.MILLISECOND, nanoSeconds / (1000 * 1000));
} else {
throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
}
}
}
// The Calendar class does not check any values until a get method is called,
// so we do just that to validate the fields set above, not because we want
// to return something else. For strict checks, the lenient mode is switched
// off temporarily.
dateTimeValue.setLenient(false);
try {
dateTimeValue.get(Calendar.MILLISECOND);
} catch (final IllegalArgumentException e) {
throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value), e);
}
dateTimeValue.setLenient(true);
if (returnType.isAssignableFrom(Calendar.class)) {
return returnType.cast(dateTimeValue);
} else if (returnType.isAssignableFrom(Long.class)) {
return returnType.cast(dateTimeValue.getTimeInMillis());
} else if (returnType.isAssignableFrom(Date.class)) {
return returnType.cast(dateTimeValue.getTime());
} else if (returnType.isAssignableFrom(Timestamp.class)) {
Timestamp timestamp = new Timestamp(dateTimeValue.getTimeInMillis());
if (literalKind != EdmLiteralKind.JSON) {
timestamp.setNanos(nanoSeconds);
}
return returnType.cast(timestamp);
} else {
throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType));
}
}