protected T internalValueOfString()

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