in odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTimeOffset.java [59:141]
protected <T> T internalValueOfString(final String value, final EdmLiteralKind literalKind, final EdmFacets facets,
final Class<T> returnType) throws EdmSimpleTypeException {
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() > 16 && value.toLowerCase().startsWith("datetimeoffset'") && value.endsWith("'")) {
return internalValueOfString(value.substring(15, value.length() - 1), EdmLiteralKind.DEFAULT, facets,
returnType);
} else {
throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
}
}
Calendar dateTimeValue = null;
long millis = 0;
if (literalKind == EdmLiteralKind.JSON) {
final Matcher matcher = JSON_PATTERN.matcher(value);
if (matcher.matches()) {
try {
millis = Long.parseLong(matcher.group(1));
} catch (final NumberFormatException e) {
throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value), e);
}
String timeZone = "GMT";
if (matcher.group(2) != null) {
final int offsetInMinutes = Integer.parseInt(matcher.group(3));
if (offsetInMinutes >= 24 * 60) {
throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
}
if (offsetInMinutes != 0) {
timeZone += matcher.group(2) + String.valueOf(offsetInMinutes / 60)
+ ":" + String.format("%02d", offsetInMinutes % 60);
// Convert the local-time milliseconds to UTC.
millis -= ("+".equals(matcher.group(2)) ? 1 : -1) * offsetInMinutes * 60 * 1000;
}
}
dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone(timeZone));
}
}
int nanoSeconds = 0;
if (dateTimeValue == null) {
final Matcher matcher = PATTERN.matcher(value);
if (!matcher.matches()) {
throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
}
final String timeZoneOffset =
matcher.group(1) != null && matcher.group(2) != null && !matcher.group(2).matches("[-+]0+:0+") ? matcher
.group(2) : null;
dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT" + timeZoneOffset));
if (dateTimeValue.get(Calendar.ZONE_OFFSET) == 0 && timeZoneOffset != null) {
throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
}
dateTimeValue.clear();
final Timestamp timestamp = EdmDateTime.getInstance().internalValueOfString(
value.substring(0, matcher.group(1) == null ? value.length() : matcher.start(1)),
EdmLiteralKind.DEFAULT, facets, Timestamp.class);
millis = timestamp.getTime() - dateTimeValue.get(Calendar.ZONE_OFFSET);
nanoSeconds = timestamp.getNanos();
if (nanoSeconds % (1000 * 1000) != 0 && !returnType.isAssignableFrom(Timestamp.class)) {
throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
}
}
if (returnType.isAssignableFrom(Calendar.class)) {
dateTimeValue.clear();
dateTimeValue.setTimeInMillis(millis);
return returnType.cast(dateTimeValue);
} else 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(Timestamp.class)) {
Timestamp timestamp = new Timestamp(millis);
if (literalKind != EdmLiteralKind.JSON) {
timestamp.setNanos(nanoSeconds);
}
return returnType.cast(timestamp);
} else {
throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType));
}
}