You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2013/12/06 15:51:49 UTC
[13/21] [OLINGO-77] Refactored java package names
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/82ae6060/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/AbstractPrimitiveType.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/AbstractPrimitiveType.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/AbstractPrimitiveType.java
new file mode 100644
index 0000000..50fadbe
--- /dev/null
+++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/AbstractPrimitiveType.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata4.commons.core.edm.primitivetype;
+
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.odata4.commons.api.edm.helper.FullQualifiedName;
+
+/**
+ * Abstract implementation of the EDM primitive-type interface.
+ */
+abstract class AbstractPrimitiveType implements EdmPrimitiveType {
+
+ protected String uriPrefix = "";
+ protected String uriSuffix = "";
+
+ @Override
+ public boolean isCompatible(final EdmPrimitiveType primitiveType) {
+ return equals(primitiveType);
+ }
+
+ @Override
+ public boolean validate(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale,
+ final Boolean isUnicode) {
+ try {
+ valueOfString(value, isNullable, maxLength, precision, scale, isUnicode, getDefaultType());
+ return true;
+ } catch (final EdmPrimitiveTypeException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public final <T> T valueOfString(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode, final Class<T> returnType)
+ throws EdmPrimitiveTypeException {
+ if (value == null) {
+ if (isNullable != null && !isNullable) {
+ throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_NULL_NOT_ALLOWED");
+ }
+ return null;
+ }
+ return internalValueOfString(value, isNullable, maxLength, precision, scale, isUnicode, returnType);
+ }
+
+ protected abstract <T> T internalValueOfString(String value,
+ Boolean isNullable, Integer maxLength, Integer precision, Integer scale, Boolean isUnicode,
+ Class<T> returnType) throws EdmPrimitiveTypeException;
+
+ @Override
+ public final String valueToString(final Object value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ if (value == null) {
+ if (isNullable != null && !isNullable) {
+ throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.VALUE_NULL_NOT_ALLOWED");
+ }
+ return null;
+ }
+ return internalValueToString(value, isNullable, maxLength, precision, scale, isUnicode);
+ }
+
+ protected abstract <T> String internalValueToString(T value,
+ Boolean isNullable, Integer maxLength, Integer precision, Integer scale,
+ Boolean isUnicode) throws EdmPrimitiveTypeException;
+
+ @Override
+ public String toUriLiteral(final String literal) {
+ return literal == null ? null :
+ uriPrefix.isEmpty() && uriSuffix.isEmpty() ? literal : uriPrefix + literal + uriSuffix;
+ }
+
+ @Override
+ public String fromUriLiteral(final String literal) throws EdmPrimitiveTypeException {
+ if (literal == null) {
+ return null;
+ } else if (uriPrefix.isEmpty() && uriSuffix.isEmpty()) {
+ return literal;
+ } else if (literal.length() >= uriPrefix.length() + uriSuffix.length()
+ && literal.startsWith(uriPrefix) && literal.endsWith(uriSuffix)) {
+ return literal.substring(uriPrefix.length(), literal.length() - uriSuffix.length());
+ } else {
+ throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(literal)");
+ }
+ }
+
+ @Override
+ public String toString() {
+ return new FullQualifiedName(getNamespace(), getName()).getFullQualifiedNameAsString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/82ae6060/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmBinary.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmBinary.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmBinary.java
new file mode 100644
index 0000000..12d980c
--- /dev/null
+++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmBinary.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata4.commons.core.edm.primitivetype;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveTypeException;
+
+/**
+ * Implementation of the EDM primitive type Binary.
+ */
+class EdmBinary extends SingletonPrimitiveType {
+
+ private static final EdmBinary instance = new EdmBinary();
+ {
+ uriPrefix = "binary'";
+ uriSuffix = "'";
+ }
+
+ public static EdmBinary getInstance() {
+ return instance;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return byte[].class;
+ }
+
+ @Override
+ public boolean validate(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) {
+ return value == null ?
+ isNullable == null || isNullable :
+ Base64.isBase64(value) && validateMaxLength(value, maxLength);
+ }
+
+ private static boolean validateMaxLength(final String value, final Integer maxLength) {
+ return maxLength == null ? true :
+ // Every three bytes are represented as four base-64 characters.
+ // Additionally, there could be up to two padding "=" characters
+ // if the number of bytes is not a multiple of three.
+ maxLength >= value.length() * 3 / 4 - (value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0);
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
+ if (!Base64.isBase64(value)) {
+ throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
+ }
+ if (!validateMaxLength(value, maxLength)) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_FACETS_NOT_MATCHED.addContent(value, facets)");
+ }
+
+ final byte[] result = Base64.decodeBase64(value);
+
+ if (returnType.isAssignableFrom(byte[].class)) {
+ return returnType.cast(result);
+ } else if (returnType.isAssignableFrom(Byte[].class)) {
+ Byte[] byteArray = new Byte[result.length];
+ for (int i = 0; i < result.length; i++) {
+ byteArray[i] = result[i];
+ }
+ return returnType.cast(byteArray);
+ } else {
+ throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType)");
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ byte[] byteArrayValue;
+ if (value instanceof byte[]) {
+ byteArrayValue = (byte[]) value;
+ } else if (value instanceof Byte[]) {
+ final int length = ((Byte[]) value).length;
+ byteArrayValue = new byte[length];
+ for (int i = 0; i < length; i++) {
+ byteArrayValue[i] = ((Byte[]) value)[i].byteValue();
+ }
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
+ }
+
+ if (maxLength != null && byteArrayValue.length > maxLength) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_FACETS_NOT_MATCHED.addContent(value, facets)");
+ }
+
+ return Base64.encodeBase64URLSafeString(byteArrayValue);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/82ae6060/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmBoolean.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmBoolean.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmBoolean.java
new file mode 100644
index 0000000..1ef5c82
--- /dev/null
+++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmBoolean.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata4.commons.core.edm.primitivetype;
+
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveTypeException;
+
+/**
+ * Implementation of the EDM primitive type Boolean.
+ */
+final class EdmBoolean extends SingletonPrimitiveType {
+
+ private static final EdmBoolean instance = new EdmBoolean();
+
+ public static EdmBoolean getInstance() {
+ return instance;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return Boolean.class;
+ }
+
+ @Override
+ public boolean validate(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) {
+ return value == null ? isNullable == null || isNullable : validateLiteral(value);
+ }
+
+ private static boolean validateLiteral(final String value) {
+ return "true".equals(value) || "false".equals(value);
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
+ if (validateLiteral(value)) {
+ if (returnType.isAssignableFrom(Boolean.class)) {
+ return returnType.cast(Boolean.valueOf("true".equals(value)));
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType)");
+ }
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ if (value instanceof Boolean) {
+ return Boolean.toString((Boolean) value);
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/82ae6060/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmByte.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmByte.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmByte.java
new file mode 100644
index 0000000..4f0154a
--- /dev/null
+++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmByte.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata4.commons.core.edm.primitivetype;
+
+import java.math.BigInteger;
+
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveTypeException;
+
+/**
+ * Implementation of the EDM primitive type Byte.
+ */
+final class EdmByte extends SingletonPrimitiveType {
+
+ private static final EdmByte instance = new EdmByte();
+
+ public static EdmByte getInstance() {
+ return instance;
+ }
+
+ @Override
+ public boolean isCompatible(final EdmPrimitiveType primitiveType) {
+ return primitiveType instanceof Uint7
+ || primitiveType instanceof EdmByte;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return Short.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
+ Short valueShort;
+ try {
+ valueShort = Short.parseShort(value);
+ } catch (final NumberFormatException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)", e);
+ }
+ if (valueShort < 0 || valueShort >= 1 << Byte.SIZE) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
+ }
+
+ try {
+ return EdmInt64.convertNumber(valueShort, returnType);
+ } catch (final IllegalArgumentException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType), e");
+ } catch (final ClassCastException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType), e");
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) {
+ if (((Number) value).longValue() >= 0 && ((Number) value).longValue() < 1 << Byte.SIZE) {
+ return value.toString();
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_ILLEGAL_CONTENT.addContent(value)");
+ }
+ } else if (value instanceof BigInteger) {
+ if (((BigInteger) value).compareTo(BigInteger.ZERO) >= 0
+ && ((BigInteger) value).compareTo(BigInteger.valueOf(1 << Byte.SIZE)) < 0) {
+ return value.toString();
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_ILLEGAL_CONTENT.addContent(value)");
+ }
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/82ae6060/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDate.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDate.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDate.java
new file mode 100644
index 0000000..97694fb
--- /dev/null
+++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDate.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata4.commons.core.edm.primitivetype;
+
+import java.util.Calendar;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveTypeException;
+
+/**
+ * Implementation of the EDM primitive type Date.
+ */
+final class EdmDate extends SingletonPrimitiveType {
+
+ private static final Pattern PATTERN = Pattern.compile(
+ "(-?\\p{Digit}{4,})-(\\p{Digit}{2})-(\\p{Digit}{2})");
+ private static final EdmDate instance = new EdmDate();
+
+ public static EdmDate getInstance() {
+ return instance;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return Calendar.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
+ Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ dateTimeValue.clear();
+
+ final Matcher matcher = PATTERN.matcher(value);
+ if (!matcher.matches()) {
+ throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
+ }
+
+ dateTimeValue.set(
+ Integer.parseInt(matcher.group(1)),
+ Byte.parseByte(matcher.group(2)) - 1, // month is zero-based
+ Byte.parseByte(matcher.group(3)));
+
+ try {
+ return EdmDateTimeOffset.convertDateTime(dateTimeValue, returnType);
+ } catch (final IllegalArgumentException e) {
+ throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value), e");
+ } catch (final ClassCastException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType), e");
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ final Calendar dateTimeValue = EdmDateTimeOffset.createDateTime(value);
+
+ StringBuilder result = new StringBuilder(10); // Ten characters are enough for "normal" dates.
+ final int year = dateTimeValue.get(Calendar.YEAR);
+ if (year < 0 || year >= 10000) {
+ result.append(year);
+ } else {
+ EdmDateTimeOffset.appendTwoDigits(result, (year / 100) % 100);
+ EdmDateTimeOffset.appendTwoDigits(result, year % 100);
+ }
+ result.append('-');
+ EdmDateTimeOffset.appendTwoDigits(result, dateTimeValue.get(Calendar.MONTH) + 1); // month is zero-based
+ result.append('-');
+ EdmDateTimeOffset.appendTwoDigits(result, dateTimeValue.get(Calendar.DAY_OF_MONTH));
+ return result.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/82ae6060/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDateTimeOffset.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDateTimeOffset.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDateTimeOffset.java
new file mode 100644
index 0000000..05fe3c9
--- /dev/null
+++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDateTimeOffset.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata4.commons.core.edm.primitivetype;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveTypeException;
+
+/**
+ * Implementation of the EDM primitive type DateTimeOffset.
+ */
+final class EdmDateTimeOffset extends SingletonPrimitiveType {
+
+ private static final Pattern PATTERN = Pattern.compile(
+ "(-?\\p{Digit}{4,})-(\\p{Digit}{2})-(\\p{Digit}{2})"
+ + "T(\\p{Digit}{2}):(\\p{Digit}{2})(?::(\\p{Digit}{2})(\\.(\\p{Digit}{0,3}?)0*)?)?"
+ + "(Z|([-+]\\p{Digit}{2}:\\p{Digit}{2}))?");
+ private static final EdmDateTimeOffset instance = new EdmDateTimeOffset();
+
+ public static EdmDateTimeOffset getInstance() {
+ return instance;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return Calendar.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
+ final Matcher matcher = PATTERN.matcher(value);
+ if (!matcher.matches()) {
+ throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
+ }
+
+ final String timeZoneOffset = matcher.group(9) != null && matcher.group(10) != null
+ && !matcher.group(10).matches("[-+]0+:0+") ? matcher.group(10) : null;
+ Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT" + timeZoneOffset));
+ if (dateTimeValue.get(Calendar.ZONE_OFFSET) == 0 && timeZoneOffset != null) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
+ }
+ dateTimeValue.clear();
+
+ 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)));
+
+ if (matcher.group(7) != null) {
+ if (matcher.group(7).length() == 1 || matcher.group(7).length() > 13) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
+ }
+ final String decimals = matcher.group(8);
+ if (decimals.length() > (precision == null ? 0 : precision)) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_FACETS_NOT_MATCHED.addContent(value, facets)");
+ }
+ final String milliSeconds = decimals + "000".substring(decimals.length());
+ dateTimeValue.set(Calendar.MILLISECOND, Short.parseShort(milliSeconds));
+ }
+
+ try {
+ return convertDateTime(dateTimeValue, returnType);
+ } catch (final IllegalArgumentException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value), e");
+ } catch (final ClassCastException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType), e");
+ }
+ }
+
+ /**
+ * Converts a {@link Calendar} value into the requested return type if possible.
+ * @param dateTimeValue the value
+ * @param returnType the class of the returned value; it must be one of {@link Calendar}, {@link Long}, or
+ * {@link Date}
+ * @return the converted value
+ * @throws IllegalArgumentException if the Calendar value is not valid
+ * @throws ClassCastException if the return type is not allowed
+ */
+ protected static <T> T convertDateTime(final Calendar dateTimeValue, final Class<T> returnType)
+ throws IllegalArgumentException, ClassCastException {
+ // The Calendar class does not check any values until a get method is called,
+ // so we do just that to validate the fields that may have been set,
+ // not because we want to return something else.
+ // For strict checks, the lenient mode is switched off.
+ dateTimeValue.setLenient(false);
+
+ if (returnType.isAssignableFrom(Calendar.class)) {
+ // Ensure that all fields are recomputed.
+ dateTimeValue.get(Calendar.MILLISECOND); // may throw IllegalArgumentException
+ // Reset the lenient mode to its default.
+ dateTimeValue.setLenient(true);
+ return returnType.cast(dateTimeValue);
+ } else if (returnType.isAssignableFrom(Long.class)) {
+ return returnType.cast(dateTimeValue.getTimeInMillis()); // may throw IllegalArgumentException
+ } else if (returnType.isAssignableFrom(Date.class)) {
+ return returnType.cast(dateTimeValue.getTime()); // may throw IllegalArgumentException
+ } else {
+ throw new ClassCastException("unsupported return type " + returnType.getSimpleName());
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ final Calendar dateTimeValue = createDateTime(value);
+
+ StringBuilder result = new StringBuilder(23); // 23 characters are enough for millisecond precision.
+ final int year = dateTimeValue.get(Calendar.YEAR);
+ appendTwoDigits(result, year / 100);
+ appendTwoDigits(result, year % 100);
+ result.append('-');
+ appendTwoDigits(result, dateTimeValue.get(Calendar.MONTH) + 1); // month is zero-based
+ result.append('-');
+ appendTwoDigits(result, dateTimeValue.get(Calendar.DAY_OF_MONTH));
+ result.append('T');
+ appendTwoDigits(result, dateTimeValue.get(Calendar.HOUR_OF_DAY));
+ result.append(':');
+ appendTwoDigits(result, dateTimeValue.get(Calendar.MINUTE));
+ result.append(':');
+ appendTwoDigits(result, dateTimeValue.get(Calendar.SECOND));
+
+ try {
+ appendMilliseconds(result, dateTimeValue.get(Calendar.MILLISECOND), precision);
+ } catch (final IllegalArgumentException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_FACETS_NOT_MATCHED.addContent(value, facets), e");
+ }
+
+ final int offsetInMinutes = (dateTimeValue.get(Calendar.ZONE_OFFSET)
+ + dateTimeValue.get(Calendar.DST_OFFSET)) / 60 / 1000;
+ final int offsetHours = offsetInMinutes / 60;
+ final int offsetMinutes = Math.abs(offsetInMinutes % 60);
+ final String offsetString = offsetInMinutes == 0 ? "Z" : String.format("%+03d:%02d", offsetHours, offsetMinutes);
+ result.append(offsetString);
+
+ return result.toString();
+ }
+
+ /**
+ * Creates a date/time value from the given value.
+ * @param value the value as {@link Calendar}, {@link Date}, or {@link Long}
+ * @return the value as {@link Calendar}
+ * @throws EdmPrimitiveTypeException if the type of the value is not supported
+ */
+ protected static <T> Calendar createDateTime(final T value) throws EdmPrimitiveTypeException {
+ Calendar dateTimeValue;
+ if (value instanceof Date) {
+ // Although java.util.Date, as stated in its documentation,
+ // "is intended to reflect coordinated universal time (UTC)",
+ // its toString() method uses the default time zone. And so do we.
+ dateTimeValue = Calendar.getInstance();
+ dateTimeValue.setTime((Date) value);
+ } else if (value instanceof Calendar) {
+ dateTimeValue = (Calendar) ((Calendar) value).clone();
+ } else if (value instanceof Long) {
+ dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ dateTimeValue.setTimeInMillis((Long) value);
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
+ }
+ return dateTimeValue;
+ }
+
+ /**
+ * Appends the given number to the given string builder,
+ * assuming that the number has at most two digits, performance-optimized.
+ * @param result a {@link StringBuilder}
+ * @param number an integer that must satisfy <code>0 <= number <= 99</code>
+ */
+ protected static void appendTwoDigits(final StringBuilder result, final int number) {
+ result.append((char) ('0' + number / 10));
+ result.append((char) ('0' + number % 10));
+ }
+
+ /**
+ * Appends the given number of milliseconds to the given string builder,
+ * assuming that the number has at most three digits, performance-optimized.
+ * @param result a {@link StringBuilder}
+ * @param milliseconds an integer that must satisfy <code>0 <= milliseconds <= 999</code>
+ * @param precision the upper limit for decimal digits (optional, defaults to zero)
+ */
+ protected static void appendMilliseconds(final StringBuilder result, final long milliseconds,
+ final Integer precision) throws IllegalArgumentException {
+ final int digits = milliseconds % 1000 == 0 ? 0 : milliseconds % 100 == 0 ? 1 : milliseconds % 10 == 0 ? 2 : 3;
+ if (digits > 0) {
+ result.append('.');
+ for (int d = 100; d > 0; d /= 10) {
+ final byte digit = (byte) (milliseconds % (d * 10) / d);
+ if (digit > 0 || milliseconds % d > 0) {
+ result.append((char) ('0' + digit));
+ }
+ }
+
+ if (precision == null || precision < digits) {
+ throw new IllegalArgumentException();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/82ae6060/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDecimal.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDecimal.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDecimal.java
new file mode 100644
index 0000000..8d600f3
--- /dev/null
+++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDecimal.java
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata4.commons.core.edm.primitivetype;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveTypeException;
+
+/**
+ * Implementation of the EDM primitive type Decimal.
+ */
+final class EdmDecimal extends SingletonPrimitiveType {
+
+ private static final Pattern PATTERN = Pattern.compile("(?:\\+|-)?(?:0*(\\p{Digit}+?))(?:\\.(\\p{Digit}+?)0*)?");
+ private static final EdmDecimal instance = new EdmDecimal();
+
+ public static EdmDecimal getInstance() {
+ return instance;
+ }
+
+ @Override
+ public boolean isCompatible(final EdmPrimitiveType primitiveType) {
+ return primitiveType instanceof Uint7
+ || primitiveType instanceof EdmByte
+ || primitiveType instanceof EdmSByte
+ || primitiveType instanceof EdmInt16
+ || primitiveType instanceof EdmInt32
+ || primitiveType instanceof EdmInt64
+ || primitiveType instanceof EdmSingle
+ || primitiveType instanceof EdmDouble
+ || primitiveType instanceof EdmDecimal;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return BigDecimal.class;
+ }
+
+ @Override
+ public boolean validate(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) {
+ return value == null ?
+ isNullable == null || isNullable :
+ validateLiteral(value) && validatePrecisionAndScale(value, precision, scale);
+ }
+
+ private static boolean validateLiteral(final String value) {
+ return PATTERN.matcher(value).matches();
+ }
+
+ private static final boolean validatePrecisionAndScale(final String value, final Integer precision,
+ final Integer scale) {
+ final Matcher matcher = PATTERN.matcher(value);
+ matcher.matches();
+ final int significantIntegerDigits = matcher.group(1).equals("0") ? 0 : matcher.group(1).length();
+ final int decimals = matcher.group(2) == null ? 0 : matcher.group(2).length();
+ return (precision == null || precision >= significantIntegerDigits + decimals)
+ && (decimals <= (scale == null ? 0 : scale));
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
+ if (!validateLiteral(value)) {
+ throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
+ }
+ if (!validatePrecisionAndScale(value, precision, scale)) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_FACETS_NOT_MATCHED.addContent(value, facets)");
+ }
+
+ try {
+ return convertDecimal(new BigDecimal(value), returnType);
+ } catch (final IllegalArgumentException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType), e");
+ } catch (final ClassCastException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType), e");
+ }
+ }
+
+ /**
+ * Converts a {@link BigDecimal} value into the requested return type if possible.
+ * @param value the value
+ * @param returnType the class of the returned value; it must be one of {@link BigDecimal}, {@link Double},
+ * {@link Float}, {@link BigInteger}, {@link Long}, {@link Integer}, {@link Short}, or {@link Byte}
+ * @return the converted value
+ * @throws IllegalArgumentException if the conversion is not possible
+ * or would lead to loss of data
+ * @throws ClassCastException if the return type is not allowed
+ */
+ protected static <T> T convertDecimal(final BigDecimal value, final Class<T> returnType)
+ throws IllegalArgumentException, ClassCastException {
+ if (returnType.isAssignableFrom(BigDecimal.class)) {
+ return returnType.cast(value);
+ } else if (returnType.isAssignableFrom(Double.class)) {
+ final double doubleValue = value.doubleValue();
+ if (BigDecimal.valueOf(doubleValue).compareTo(value) == 0) {
+ return returnType.cast(doubleValue);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ } else if (returnType.isAssignableFrom(Float.class)) {
+ final Float floatValue = value.floatValue();
+ if (BigDecimal.valueOf(floatValue).compareTo(value) == 0) {
+ return returnType.cast(floatValue);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ } else {
+ try {
+ if (returnType.isAssignableFrom(BigInteger.class)) {
+ return returnType.cast(value.toBigIntegerExact());
+ } else if (returnType.isAssignableFrom(Long.class)) {
+ return returnType.cast(value.longValueExact());
+ } else if (returnType.isAssignableFrom(Integer.class)) {
+ return returnType.cast(value.intValueExact());
+ } else if (returnType.isAssignableFrom(Short.class)) {
+ return returnType.cast(value.shortValueExact());
+ } else if (returnType.isAssignableFrom(Byte.class)) {
+ return returnType.cast(value.byteValueExact());
+ } else {
+ throw new ClassCastException("unsupported return type " + returnType.getSimpleName());
+ }
+ } catch (final ArithmeticException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ String result;
+ if (value instanceof Long || value instanceof Integer || value instanceof Short
+ || value instanceof Byte || value instanceof BigInteger) {
+ result = value.toString();
+ final int digits = result.startsWith("-") ? result.length() - 1 : result.length();
+ if (precision != null && precision < digits) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_FACETS_NOT_MATCHED.addContent(value, facets)");
+ }
+
+ } else if (value instanceof Double || value instanceof Float || value instanceof BigDecimal) {
+ BigDecimal bigDecimalValue;
+ try {
+ bigDecimalValue = value instanceof Double ? BigDecimal.valueOf((Double) value) :
+ value instanceof Float ? BigDecimal.valueOf((Float) value) : (BigDecimal) value;
+ } catch (final NumberFormatException e) {
+ throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.VALUE_ILLEGAL_CONTENT.addContent(value)", e);
+ }
+
+ final int digits = bigDecimalValue.scale() >= 0 ?
+ Math.max(bigDecimalValue.precision(), bigDecimalValue.scale()) :
+ bigDecimalValue.precision() - bigDecimalValue.scale();
+ if ((precision == null || precision >= digits) && (bigDecimalValue.scale() <= (scale == null ? 0 : scale))) {
+ result = bigDecimalValue.toPlainString();
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_FACETS_NOT_MATCHED.addContent(value, facets)");
+ }
+
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
+ }
+
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/82ae6060/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDouble.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDouble.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDouble.java
new file mode 100644
index 0000000..f3e5890
--- /dev/null
+++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDouble.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata4.commons.core.edm.primitivetype;
+
+import java.math.BigDecimal;
+import java.util.regex.Pattern;
+
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveTypeException;
+
+/**
+ * Implementation of the EDM primitive type Double.
+ */
+final class EdmDouble extends SingletonPrimitiveType {
+
+ protected static final String NEGATIVE_INFINITY = "-INF";
+ protected static final String POSITIVE_INFINITY = "INF";
+ protected static final String NaN = "NaN";
+ private static final Pattern PATTERN = Pattern.compile(
+ "(?:\\+|-)?\\p{Digit}{1,17}(?:\\.\\p{Digit}{1,17})?(?:(?:E|e)(?:\\+|-)?\\p{Digit}{1,3})?");
+ private static final EdmDouble instance = new EdmDouble();
+
+ public static EdmDouble getInstance() {
+ return instance;
+ }
+
+ @Override
+ public boolean isCompatible(final EdmPrimitiveType primitiveType) {
+ return primitiveType instanceof Uint7
+ || primitiveType instanceof EdmByte
+ || primitiveType instanceof EdmSByte
+ || primitiveType instanceof EdmInt16
+ || primitiveType instanceof EdmInt32
+ || primitiveType instanceof EdmInt64
+ || primitiveType instanceof EdmSingle
+ || primitiveType instanceof EdmDouble;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return Double.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
+ Double result = null;
+ BigDecimal bigDecimalValue = null;
+ // Handle special values first.
+ if (value.equals(NEGATIVE_INFINITY)) {
+ result = Double.NEGATIVE_INFINITY;
+ } else if (value.equals(POSITIVE_INFINITY)) {
+ result = Double.POSITIVE_INFINITY;
+ } else if (value.equals(NaN)) {
+ result = Double.NaN;
+ } else {
+ // Now only "normal" numbers remain.
+ if (!PATTERN.matcher(value).matches()) {
+ throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
+ }
+
+ // The number format is checked above, so we don't have to catch NumberFormatException.
+ bigDecimalValue = new BigDecimal(value);
+ result = bigDecimalValue.doubleValue();
+ // "Real" infinite values have been treated already above, so we can throw an exception
+ // if the conversion to a double results in an infinite value.
+ if (result.isInfinite() || BigDecimal.valueOf(result).compareTo(bigDecimalValue) != 0) {
+ throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
+ }
+ }
+
+ if (returnType.isAssignableFrom(Double.class)) {
+ return returnType.cast(result);
+ } else if (result.isInfinite() || result.isNaN()) {
+ if (returnType.isAssignableFrom(Float.class)) {
+ return returnType.cast(result.floatValue());
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType)");
+ }
+ } else {
+ try {
+ return EdmDecimal.convertDecimal(bigDecimalValue, returnType);
+ } catch (final IllegalArgumentException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType), e");
+ } catch (final ClassCastException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType), e");
+ }
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ if (value instanceof Long) {
+ if (Math.abs((Long) value) < 1L << 51) {
+ return value.toString();
+ } else {
+ throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.VALUE_ILLEGAL_CONTENT.addContent(value)");
+ }
+ } else if (value instanceof Integer || value instanceof Short || value instanceof Byte) {
+ return value.toString();
+ } else if (value instanceof Double) {
+ return (Double) value == Double.NEGATIVE_INFINITY ? NEGATIVE_INFINITY :
+ (Double) value == Double.POSITIVE_INFINITY ? POSITIVE_INFINITY : value.toString();
+ } else if (value instanceof Float) {
+ return (Float) value == Float.NEGATIVE_INFINITY ? NEGATIVE_INFINITY :
+ (Float) value == Float.POSITIVE_INFINITY ? POSITIVE_INFINITY : value.toString();
+ } else if (value instanceof BigDecimal) {
+ final double doubleValue = ((BigDecimal) value).doubleValue();
+ if (!Double.isInfinite(doubleValue) && BigDecimal.valueOf(doubleValue).compareTo((BigDecimal) value) == 0) {
+ return ((BigDecimal) value).toString();
+ } else {
+ throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.VALUE_ILLEGAL_CONTENT.addContent(value)");
+ }
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/82ae6060/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDuration.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDuration.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDuration.java
new file mode 100644
index 0000000..5ea4fa1
--- /dev/null
+++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmDuration.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata4.commons.core.edm.primitivetype;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveTypeException;
+
+final class EdmDuration extends SingletonPrimitiveType {
+
+ private static final Pattern PATTERN = Pattern.compile(
+ "[-+]?P(?:(\\p{Digit}+)D)?(?:T(?:(\\p{Digit}+)H)?(?:(\\p{Digit}+)M)?"
+ + "(?:(\\p{Digit}+(?:\\.(?:\\p{Digit}+?)0*)?)S)?)?");
+ private static final EdmDuration instance = new EdmDuration();
+ {
+ uriPrefix = "duration'";
+ uriSuffix = "'";
+ }
+
+ public static EdmDuration getInstance() {
+ return instance;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return BigDecimal.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
+ final Matcher matcher = PATTERN.matcher(value);
+ if (!matcher.matches()
+ || matcher.group(1) == null && matcher.group(2) == null && matcher.group(3) == null
+ && matcher.group(4) == null) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(literal)");
+ }
+
+ BigDecimal result = (matcher.group(1) == null ? BigDecimal.ZERO :
+ new BigDecimal(matcher.group(1)).multiply(BigDecimal.valueOf(24 * 60 * 60)))
+ .add(matcher.group(2) == null ? BigDecimal.ZERO :
+ new BigDecimal(matcher.group(2)).multiply(BigDecimal.valueOf(60 * 60)))
+ .add(matcher.group(3) == null ? BigDecimal.ZERO :
+ new BigDecimal(matcher.group(3)).multiply(BigDecimal.valueOf(60)))
+ .add(matcher.group(4) == null ? BigDecimal.ZERO : new BigDecimal(matcher.group(4)));
+
+ if (result.scale() <= (precision == null ? 0 : precision)) {
+ result = value.startsWith("-") ? result.negate() : result;
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_FACETS_NOT_MATCHED.addContent(literal, facets)");
+ }
+
+ try {
+ return EdmDecimal.convertDecimal(result, returnType);
+ } catch (final IllegalArgumentException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType), e");
+ } catch (final ClassCastException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType), e");
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ BigDecimal valueDecimal;
+ if (value instanceof BigDecimal) {
+ valueDecimal = (BigDecimal) value;
+ } else if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) {
+ valueDecimal = BigDecimal.valueOf(((Number) value).longValue());
+ } else if (value instanceof BigInteger) {
+ valueDecimal = new BigDecimal((BigInteger) value);
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
+ }
+
+ if (valueDecimal.scale() > (precision == null ? 0 : precision)) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_FACETS_NOT_MATCHED.addContent(value, facets)");
+ }
+
+ StringBuilder result = new StringBuilder();
+ if (valueDecimal.signum() == -1) {
+ result.append('-');
+ valueDecimal = valueDecimal.negate();
+ }
+ result.append('P');
+ BigInteger seconds = valueDecimal.toBigInteger();
+ final BigInteger days = seconds.divide(BigInteger.valueOf(24 * 60 * 60));
+ if (!days.equals(BigInteger.ZERO)) {
+ result.append(days.toString());
+ result.append('D');
+ }
+ result.append('T');
+ seconds = seconds.subtract(days.multiply(BigInteger.valueOf(24 * 60 * 60)));
+ final BigInteger hours = seconds.divide(BigInteger.valueOf(60 * 60));
+ if (!hours.equals(BigInteger.ZERO)) {
+ result.append(hours.toString());
+ result.append('H');
+ }
+ seconds = seconds.subtract(hours.multiply(BigInteger.valueOf(60 * 60)));
+ final BigInteger minutes = seconds.divide(BigInteger.valueOf(60));
+ if (!minutes.equals(BigInteger.ZERO)) {
+ result.append(minutes.toString());
+ result.append('M');
+ }
+ result.append(valueDecimal.remainder(BigDecimal.valueOf(60)).toPlainString());
+ result.append('S');
+
+ return result.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/82ae6060/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmEnum.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmEnum.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmEnum.java
new file mode 100644
index 0000000..d88a3b2
--- /dev/null
+++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmEnum.java
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata4.commons.core.edm.primitivetype;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata4.commons.api.edm.EdmEnumType;
+import org.apache.olingo.odata4.commons.api.edm.EdmMember;
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.odata4.commons.api.edm.constants.EdmTypeKind;
+
+/**
+ * Implementation of the EDM enum type.
+ * @see EdmEnumType
+ */
+final class EdmEnum extends AbstractPrimitiveType implements EdmEnumType {
+
+ private final String namespace;
+ private final String name;
+ private final String fullName;
+ private final EdmPrimitiveType underlyingType;
+ private final List<EdmMember> members;
+ private final Boolean isFlags;
+
+ public EdmEnum(final String namespace, final String name,
+ final EdmPrimitiveType underlyingType, final List<EdmMember> members, final Boolean isFlags) {
+ this.namespace = namespace;
+ this.name = name;
+ fullName = namespace + '.' + name;
+ uriPrefix = fullName + '\'';
+ uriSuffix = "'";
+ this.underlyingType = underlyingType;
+ this.members = members;
+ this.isFlags = isFlags;
+ }
+
+ @Override
+ public String getNamespace() {
+ return namespace;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public EdmTypeKind getKind() {
+ return EdmTypeKind.ENUM;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return underlyingType.getDefaultType();
+ }
+
+ @Override
+ public EdmMember getMember(final String name) {
+ for (EdmMember member : members) {
+ if (member.getName().equals(name)) {
+ return member;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public List<String> getMemberNames() {
+ List<String> names = new ArrayList<String>();
+ for (final EdmMember member : members) {
+ names.add(member.getName());
+ }
+ return names;
+ }
+
+ @Override
+ public EdmPrimitiveType getUnderlyingType() {
+ return underlyingType;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
+ try {
+ return EdmInt64.convertNumber(parseEnumValue(value), returnType);
+ } catch (final IllegalArgumentException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType), e");
+ } catch (final ClassCastException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType), e");
+ }
+ }
+
+ protected Long parseEnumValue(final String value) throws EdmPrimitiveTypeException {
+ Long result = null;
+ for (final String memberValue : value.split(",", isFlags ? -1 : 1)) {
+ Long memberValueLong = null;
+ for (final EdmMember member : members) {
+ if (member.getName().equals(memberValue) || member.getValue().equals(memberValue)) {
+ memberValueLong = Long.decode(member.getValue());
+ }
+ }
+ if (memberValueLong == null) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
+ }
+ result = result == null ? memberValueLong : result | memberValueLong;
+ }
+ return result;
+ }
+
+ @Override
+ protected String internalValueToString(final Object value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) {
+ return constructEnumValue(((Number) value).longValue());
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
+ }
+ }
+
+ protected String constructEnumValue(final long value) throws EdmPrimitiveTypeException {
+ long remaining = value;
+ StringBuilder result = new StringBuilder();
+
+ for (final EdmMember member : members) {
+ final long memberValue = Long.parseLong(member.getValue());
+ if ((memberValue & remaining) == memberValue) {
+ if (result.length() > 0) {
+ result.append(',');
+ }
+ result.append(member.getName());
+ remaining ^= memberValue;
+ }
+ }
+
+ if (remaining != 0) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_ILLEGAL_CONTENT.addContent(value)");
+ }
+ return result.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/82ae6060/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmGuid.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmGuid.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmGuid.java
new file mode 100644
index 0000000..90cd9a1
--- /dev/null
+++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmGuid.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata4.commons.core.edm.primitivetype;
+
+import java.util.UUID;
+
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveTypeException;
+
+/**
+ * Implementation of the EDM primitive type Guid.
+ */
+final class EdmGuid extends SingletonPrimitiveType {
+
+ private static final String PATTERN = "\\p{XDigit}{8}-\\p{XDigit}{4}-\\p{XDigit}{4}-\\p{XDigit}{4}-\\p{XDigit}{12}";
+ private static final EdmGuid instance = new EdmGuid();
+
+ public static EdmGuid getInstance() {
+ return instance;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return UUID.class;
+ }
+
+ @Override
+ public boolean validate(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) {
+ return value == null ? isNullable == null || isNullable : validateLiteral(value);
+ }
+
+ private boolean validateLiteral(final String value) {
+ return value.matches(PATTERN);
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode,
+ final Class<T> returnType) throws EdmPrimitiveTypeException {
+ UUID result;
+ if (validateLiteral(value)) {
+ result = UUID.fromString(value);
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
+ }
+
+ if (returnType.isAssignableFrom(UUID.class)) {
+ return returnType.cast(result);
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType)");
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ if (value instanceof UUID) {
+ return ((UUID) value).toString();
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/82ae6060/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmInt16.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmInt16.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmInt16.java
new file mode 100644
index 0000000..9ecac4d
--- /dev/null
+++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmInt16.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata4.commons.core.edm.primitivetype;
+
+import java.math.BigInteger;
+
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveTypeException;
+
+/**
+ * Implementation of the EDM primitive type Int16.
+ */
+final class EdmInt16 extends SingletonPrimitiveType {
+
+ private static final EdmInt16 instance = new EdmInt16();
+
+ public static EdmInt16 getInstance() {
+ return instance;
+ }
+
+ @Override
+ public boolean isCompatible(final EdmPrimitiveType primitiveType) {
+ return primitiveType instanceof Uint7
+ || primitiveType instanceof EdmByte
+ || primitiveType instanceof EdmSByte
+ || primitiveType instanceof EdmInt16;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return Short.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
+ Short valueShort;
+ try {
+ valueShort = Short.parseShort(value);
+ } catch (final NumberFormatException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)", e);
+ }
+
+ try {
+ return EdmInt64.convertNumber(valueShort, returnType);
+ } catch (final IllegalArgumentException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType), e");
+ } catch (final ClassCastException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType), e");
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ if (value instanceof Byte || value instanceof Short) {
+ return value.toString();
+ } else if (value instanceof Integer || value instanceof Long) {
+ if (((Number) value).longValue() >= Short.MIN_VALUE
+ && ((Number) value).longValue() <= Short.MAX_VALUE) {
+ return value.toString();
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_ILLEGAL_CONTENT.addContent(value)");
+ }
+ } else if (value instanceof BigInteger) {
+ if (((BigInteger) value).bitLength() < Short.SIZE) {
+ return value.toString();
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_ILLEGAL_CONTENT.addContent(value)");
+ }
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/82ae6060/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmInt32.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmInt32.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmInt32.java
new file mode 100644
index 0000000..44750cf
--- /dev/null
+++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmInt32.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata4.commons.core.edm.primitivetype;
+
+import java.math.BigInteger;
+
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveTypeException;
+
+/**
+ * Implementation of the EDM primitive type Int32.
+ */
+final class EdmInt32 extends SingletonPrimitiveType {
+
+ private static final EdmInt32 instance = new EdmInt32();
+
+ public static EdmInt32 getInstance() {
+ return instance;
+ }
+
+ @Override
+ public boolean isCompatible(final EdmPrimitiveType primitiveType) {
+ return primitiveType instanceof Uint7
+ || primitiveType instanceof EdmByte
+ || primitiveType instanceof EdmSByte
+ || primitiveType instanceof EdmInt16
+ || primitiveType instanceof EdmInt32;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return Integer.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
+ Integer valueInteger;
+ try {
+ valueInteger = Integer.parseInt(value);
+ } catch (final NumberFormatException e) {
+ throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)", e);
+ }
+
+ try {
+ return EdmInt64.convertNumber(valueInteger, returnType);
+ } catch (final IllegalArgumentException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType), e");
+ } catch (final ClassCastException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType), e");
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ if (value instanceof Byte || value instanceof Short || value instanceof Integer) {
+ return value.toString();
+ } else if (value instanceof Long) {
+ if ((Long) value >= Integer.MIN_VALUE && (Long) value <= Integer.MAX_VALUE) {
+ return value.toString();
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_ILLEGAL_CONTENT.addContent(value)");
+ }
+ } else if (value instanceof BigInteger) {
+ if (((BigInteger) value).bitLength() < Integer.SIZE) {
+ return value.toString();
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_ILLEGAL_CONTENT.addContent(value)");
+ }
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/82ae6060/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmInt64.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmInt64.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmInt64.java
new file mode 100644
index 0000000..1f23d91
--- /dev/null
+++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmInt64.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata4.commons.core.edm.primitivetype;
+
+import java.math.BigInteger;
+
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveTypeException;
+
+/**
+ * Implementation of the EDM primitive type Int64.
+ */
+final class EdmInt64 extends SingletonPrimitiveType {
+
+ private static final EdmInt64 instance = new EdmInt64();
+
+ public static EdmInt64 getInstance() {
+ return instance;
+ }
+
+ @Override
+ public boolean isCompatible(final EdmPrimitiveType primitiveType) {
+ return primitiveType instanceof Uint7
+ || primitiveType instanceof EdmByte
+ || primitiveType instanceof EdmSByte
+ || primitiveType instanceof EdmInt16
+ || primitiveType instanceof EdmInt32
+ || primitiveType instanceof EdmInt64;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return Long.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
+ Long valueLong;
+ try {
+ valueLong = Long.parseLong(value);
+ } catch (final NumberFormatException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)", e);
+ }
+
+ try {
+ return convertNumber(valueLong, returnType);
+ } catch (final IllegalArgumentException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType), e");
+ } catch (final ClassCastException e) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType), e");
+ }
+ }
+
+ /**
+ * Converts a whole {@link Number} value into the requested return type if possible.
+ * @param value the value
+ * @param returnType the class of the returned value; it must be one of {@link BigInteger}, {@link Long},
+ * {@link Integer}, {@link Short}, or {@link Byte}
+ * @return the converted value
+ * @throws IllegalArgumentException if the conversion is not possible
+ * @throws ClassCastException if the return type is not allowed
+ */
+ protected static <T> T convertNumber(final Number value, final Class<T> returnType) throws IllegalArgumentException,
+ ClassCastException {
+ if (returnType.isAssignableFrom(Long.class)) {
+ return returnType.cast(value.longValue());
+ } else if (returnType.isAssignableFrom(BigInteger.class)) {
+ return returnType.cast(BigInteger.valueOf(value.longValue()));
+ } else if (returnType.isAssignableFrom(Byte.class)) {
+ if (value.longValue() >= Byte.MIN_VALUE && value.longValue() <= Byte.MAX_VALUE) {
+ return returnType.cast(value.byteValue());
+ } else {
+ throw new IllegalArgumentException();
+ }
+ } else if (returnType.isAssignableFrom(Short.class)) {
+ if (value.longValue() >= Short.MIN_VALUE && value.longValue() <= Short.MAX_VALUE) {
+ return returnType.cast(value.shortValue());
+ } else {
+ throw new IllegalArgumentException();
+ }
+ } else if (returnType.isAssignableFrom(Integer.class)) {
+ if (value.longValue() >= Integer.MIN_VALUE && value.longValue() <= Integer.MAX_VALUE) {
+ return returnType.cast(value.intValue());
+ } else {
+ throw new IllegalArgumentException();
+ }
+ } else {
+ throw new ClassCastException("unsupported return type " + returnType.getSimpleName());
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) {
+ return value.toString();
+ } else if (value instanceof BigInteger) {
+ if (((BigInteger) value).bitLength() < Long.SIZE) {
+ return value.toString();
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_ILLEGAL_CONTENT.addContent(value)");
+ }
+ } else {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/82ae6060/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmNull.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmNull.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmNull.java
new file mode 100644
index 0000000..8d4d4d6
--- /dev/null
+++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/odata4/commons/core/edm/primitivetype/EdmNull.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata4.commons.core.edm.primitivetype;
+
+import org.apache.olingo.odata4.commons.api.edm.EdmPrimitiveTypeException;
+
+//TODO: Is this class still necessary?
+/**
+ * Implementation of the simple type Null.
+ */
+final class EdmNull extends SingletonPrimitiveType {
+
+ private static final EdmNull instance = new EdmNull();
+
+ public static EdmNull getInstance() {
+ return instance;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return this == obj || obj == null;
+ }
+
+ @Override
+ public int hashCode() {
+ return 0;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return null;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
+ return null;
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value,
+ final Boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ return null;
+ }
+
+ @Override
+ public String toUriLiteral(final String literal) {
+ return "null";
+ }
+
+ @Override
+ public String fromUriLiteral(final String literal) throws EdmPrimitiveTypeException {
+ return null;
+ }
+}