You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2013/07/26 13:22:26 UTC
[21/51] [partial] initial commit
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmImpl.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmImpl.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmImpl.java
new file mode 100644
index 0000000..9023704
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmImpl.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * 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.odata2.core.edm;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.edm.EdmAssociation;
+import org.apache.olingo.odata2.api.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.edm.EdmEntityContainer;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmServiceMetadata;
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.exception.ODataException;
+
+/**
+ * @author SAP AG
+ */
+public abstract class EdmImpl implements Edm {
+
+ private Map<String, EdmEntityContainer> edmEntityContainers;
+ private Map<FullQualifiedName, EdmEntityType> edmEntityTypes;
+ private Map<FullQualifiedName, EdmComplexType> edmComplexTypes;
+ private Map<FullQualifiedName, EdmAssociation> edmAssociations;
+
+ protected EdmServiceMetadata edmServiceMetadata;
+
+ public EdmImpl(final EdmServiceMetadata edmServiceMetadata) {
+ edmEntityContainers = new HashMap<String, EdmEntityContainer>();
+ edmEntityTypes = new HashMap<FullQualifiedName, EdmEntityType>();
+ edmComplexTypes = new HashMap<FullQualifiedName, EdmComplexType>();
+ edmAssociations = new HashMap<FullQualifiedName, EdmAssociation>();
+ this.edmServiceMetadata = edmServiceMetadata;
+ }
+
+ @Override
+ public EdmEntityContainer getEntityContainer(final String name) throws EdmException {
+ if (edmEntityContainers.containsKey(name)) {
+ return edmEntityContainers.get(name);
+ }
+
+ EdmEntityContainer edmEntityContainer = null;
+
+ try {
+ edmEntityContainer = createEntityContainer(name);
+ if (edmEntityContainer != null) {
+ if (name == null && edmEntityContainers.containsKey(edmEntityContainer.getName())) {
+ //ensure that the same default entity container is stored in the HashMap under null and its name
+ edmEntityContainer = edmEntityContainers.get(edmEntityContainer.getName());
+ edmEntityContainers.put(name, edmEntityContainer);
+ } else if (edmEntityContainers.containsKey(null) && edmEntityContainers.get(null) != null && name.equals(edmEntityContainers.get(null).getName())) {
+ //ensure that the same default entity container is stored in the HashMap under null and its name
+ edmEntityContainer = edmEntityContainers.get(null);
+ edmEntityContainers.put(name, edmEntityContainer);
+ } else {
+ edmEntityContainers.put(name, edmEntityContainer);
+ }
+ }
+ } catch (ODataException e) {
+ throw new EdmException(EdmException.COMMON, e);
+ }
+
+ return edmEntityContainer;
+ }
+
+ @Override
+ public EdmEntityType getEntityType(final String namespace, final String name) throws EdmException {
+ FullQualifiedName fqName = new FullQualifiedName(namespace, name);
+ if (edmEntityTypes.containsKey(fqName)) {
+ return edmEntityTypes.get(fqName);
+ }
+
+ EdmEntityType edmEntityType = null;
+
+ try {
+ edmEntityType = createEntityType(fqName);
+ if (edmEntityType != null) {
+ edmEntityTypes.put(fqName, edmEntityType);
+ }
+ } catch (ODataException e) {
+ throw new EdmException(EdmException.COMMON, e);
+ }
+
+ return edmEntityType;
+ }
+
+ @Override
+ public EdmComplexType getComplexType(final String namespace, final String name) throws EdmException {
+ FullQualifiedName fqName = new FullQualifiedName(namespace, name);
+ if (edmComplexTypes.containsKey(fqName)) {
+ return edmComplexTypes.get(fqName);
+ }
+
+ EdmComplexType edmComplexType = null;
+
+ try {
+ edmComplexType = createComplexType(fqName);
+ if (edmComplexType != null) {
+ edmComplexTypes.put(fqName, edmComplexType);
+ }
+ } catch (ODataException e) {
+ throw new EdmException(EdmException.COMMON, e);
+ }
+
+ return edmComplexType;
+ }
+
+ @Override
+ public EdmAssociation getAssociation(final String namespace, final String name) throws EdmException {
+ FullQualifiedName fqName = new FullQualifiedName(namespace, name);
+ if (edmAssociations.containsKey(fqName)) {
+ return edmAssociations.get(fqName);
+ }
+
+ EdmAssociation edmAssociation = null;
+
+ try {
+ edmAssociation = createAssociation(fqName);
+ if (edmAssociation != null) {
+ edmAssociations.put(fqName, edmAssociation);
+ }
+ } catch (ODataException e) {
+ throw new EdmException(EdmException.COMMON, e);
+ }
+
+ return edmAssociation;
+ }
+
+ @Override
+ public EdmServiceMetadata getServiceMetadata() {
+ return edmServiceMetadata;
+ }
+
+ @Override
+ public EdmEntityContainer getDefaultEntityContainer() throws EdmException {
+ return getEntityContainer(null);
+ }
+
+ protected abstract EdmEntityContainer createEntityContainer(String name) throws ODataException;
+
+ protected abstract EdmEntityType createEntityType(FullQualifiedName fqName) throws ODataException;
+
+ protected abstract EdmComplexType createComplexType(FullQualifiedName fqName) throws ODataException;
+
+ protected abstract EdmAssociation createAssociation(FullQualifiedName fqName) throws ODataException;
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmInt16.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmInt16.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmInt16.java
new file mode 100644
index 0000000..b632179
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmInt16.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * 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.odata2.core.edm;
+
+import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+
+/**
+ * Implementation of the EDM simple type Int16.
+ * @author SAP AG
+ */
+public class EdmInt16 extends AbstractSimpleType {
+
+ private static final EdmInt16 instance = new EdmInt16();
+
+ public static EdmInt16 getInstance() {
+ return instance;
+ }
+
+ @Override
+ public boolean isCompatible(final EdmSimpleType simpleType) {
+ return simpleType instanceof Bit
+ || simpleType instanceof Uint7
+ || simpleType instanceof EdmByte
+ || simpleType instanceof EdmSByte
+ || simpleType instanceof EdmInt16;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return Short.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value, final EdmLiteralKind literalKind, final EdmFacets facets, final Class<T> returnType) throws EdmSimpleTypeException {
+ Short valueShort;
+ try {
+ valueShort = Short.parseShort(value);
+ } catch (final NumberFormatException e) {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value), e);
+ }
+
+ if (returnType.isAssignableFrom(Short.class)) {
+ return returnType.cast(valueShort);
+ } else if (returnType.isAssignableFrom(Byte.class)) {
+ if (valueShort >= Byte.MIN_VALUE && valueShort <= Byte.MAX_VALUE) {
+ return returnType.cast(valueShort.byteValue());
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType));
+ }
+ } else if (returnType.isAssignableFrom(Integer.class)) {
+ return returnType.cast(valueShort.intValue());
+ } else if (returnType.isAssignableFrom(Long.class)) {
+ return returnType.cast(valueShort.longValue());
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType));
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value, final EdmLiteralKind literalKind, final EdmFacets facets) throws EdmSimpleTypeException {
+ 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 EdmSimpleTypeException(EdmSimpleTypeException.VALUE_ILLEGAL_CONTENT.addContent(value));
+ }
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass()));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmInt32.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmInt32.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmInt32.java
new file mode 100644
index 0000000..8d3b729
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmInt32.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * 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.odata2.core.edm;
+
+import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+
+/**
+ * Implementation of the EDM simple type Int32.
+ * @author SAP AG
+ */
+public class EdmInt32 extends AbstractSimpleType {
+
+ private static final EdmInt32 instance = new EdmInt32();
+
+ public static EdmInt32 getInstance() {
+ return instance;
+ }
+
+ @Override
+ public boolean isCompatible(final EdmSimpleType simpleType) {
+ return simpleType instanceof Bit
+ || simpleType instanceof Uint7
+ || simpleType instanceof EdmByte
+ || simpleType instanceof EdmSByte
+ || simpleType instanceof EdmInt16
+ || simpleType instanceof EdmInt32;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return Integer.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value, final EdmLiteralKind literalKind, final EdmFacets facets, final Class<T> returnType) throws EdmSimpleTypeException {
+ Integer valueInteger;
+ try {
+ valueInteger = Integer.parseInt(value);
+ } catch (final NumberFormatException e) {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value), e);
+ }
+
+ if (returnType.isAssignableFrom(Integer.class)) {
+ return returnType.cast(valueInteger);
+ } else if (returnType.isAssignableFrom(Byte.class)) {
+ if (valueInteger >= Byte.MIN_VALUE && valueInteger <= Byte.MAX_VALUE) {
+ return returnType.cast(valueInteger.byteValue());
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType));
+ }
+ } else if (returnType.isAssignableFrom(Short.class)) {
+ if (valueInteger >= Short.MIN_VALUE && valueInteger <= Short.MAX_VALUE) {
+ return returnType.cast(valueInteger.shortValue());
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType));
+ }
+ } else if (returnType.isAssignableFrom(Long.class)) {
+ return returnType.cast(valueInteger.longValue());
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType));
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value, final EdmLiteralKind literalKind, final EdmFacets facets) throws EdmSimpleTypeException {
+ 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 EdmSimpleTypeException(EdmSimpleTypeException.VALUE_ILLEGAL_CONTENT.addContent(value));
+ }
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass()));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmInt64.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmInt64.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmInt64.java
new file mode 100644
index 0000000..03b0825
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmInt64.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * 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.odata2.core.edm;
+
+import java.math.BigInteger;
+
+import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+
+/**
+ * Implementation of the EDM simple type Int64.
+ * @author SAP AG
+ */
+public class EdmInt64 extends AbstractSimpleType {
+
+ private static final EdmInt64 instance = new EdmInt64();
+
+ public static EdmInt64 getInstance() {
+ return instance;
+ }
+
+ @Override
+ public boolean isCompatible(final EdmSimpleType simpleType) {
+ return simpleType instanceof Bit
+ || simpleType instanceof Uint7
+ || simpleType instanceof EdmByte
+ || simpleType instanceof EdmSByte
+ || simpleType instanceof EdmInt16
+ || simpleType instanceof EdmInt32
+ || simpleType instanceof EdmInt64;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return Long.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value, final EdmLiteralKind literalKind, final EdmFacets facets, final Class<T> returnType) throws EdmSimpleTypeException {
+ Long valueLong;
+ try {
+ if (literalKind == EdmLiteralKind.URI) {
+ if (value.endsWith("L") || value.endsWith("l")) {
+ valueLong = Long.parseLong(value.substring(0, value.length() - 1));
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
+ }
+ } else {
+ valueLong = Long.parseLong(value);
+ }
+ } catch (final NumberFormatException e) {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value), e);
+ }
+
+ if (returnType.isAssignableFrom(Long.class)) {
+ return returnType.cast(valueLong);
+ } else if (returnType.isAssignableFrom(Byte.class)) {
+ if (valueLong >= Byte.MIN_VALUE && valueLong <= Byte.MAX_VALUE) {
+ return returnType.cast(valueLong.byteValue());
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType));
+ }
+ } else if (returnType.isAssignableFrom(Short.class)) {
+ if (valueLong >= Short.MIN_VALUE && valueLong <= Short.MAX_VALUE) {
+ return returnType.cast(valueLong.shortValue());
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType));
+ }
+ } else if (returnType.isAssignableFrom(Integer.class)) {
+ if (valueLong >= Integer.MIN_VALUE && valueLong <= Integer.MAX_VALUE) {
+ return returnType.cast(valueLong.intValue());
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType));
+ }
+ } else if (returnType.isAssignableFrom(BigInteger.class)) {
+ return returnType.cast(BigInteger.valueOf(valueLong));
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType));
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value, final EdmLiteralKind literalKind, final EdmFacets facets) throws EdmSimpleTypeException {
+ 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 EdmSimpleTypeException(EdmSimpleTypeException.VALUE_ILLEGAL_CONTENT.addContent(value));
+ }
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass()));
+ }
+ }
+
+ @Override
+ public String toUriLiteral(final String literal) {
+ return literal + "L";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmNull.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmNull.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmNull.java
new file mode 100644
index 0000000..8f84704
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmNull.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * 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.odata2.core.edm;
+
+import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+
+/**
+ * Implementation of the simple type Null.
+ * @author SAP AG
+ */
+public class EdmNull extends AbstractSimpleType {
+
+ 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 EdmLiteralKind literalKind, final EdmFacets facets, final Class<T> returnType) throws EdmSimpleTypeException {
+ return null;
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value, final EdmLiteralKind literalKind, final EdmFacets facets) throws EdmSimpleTypeException {
+ return null;
+ }
+
+ @Override
+ public String toUriLiteral(final String literal) {
+ return "null";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmSByte.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmSByte.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmSByte.java
new file mode 100644
index 0000000..fffdeb9
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmSByte.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * 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.odata2.core.edm;
+
+import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+
+/**
+ * Implementation of the EDM simple type SByte.
+ * @author SAP AG
+ */
+public class EdmSByte extends AbstractSimpleType {
+
+ private static final EdmSByte instance = new EdmSByte();
+
+ public static EdmSByte getInstance() {
+ return instance;
+ }
+
+ @Override
+ public boolean isCompatible(final EdmSimpleType simpleType) {
+ return simpleType instanceof Bit
+ || simpleType instanceof Uint7
+ || simpleType instanceof EdmSByte;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return Byte.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value, final EdmLiteralKind literalKind, final EdmFacets facets, final Class<T> returnType) throws EdmSimpleTypeException {
+ Byte valueByte;
+ try {
+ valueByte = Byte.parseByte(value);
+ } catch (final NumberFormatException e) {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value), e);
+ }
+
+ if (returnType.isAssignableFrom(Byte.class)) {
+ return returnType.cast(valueByte);
+ } else if (returnType.isAssignableFrom(Short.class)) {
+ return returnType.cast(valueByte.shortValue());
+ } else if (returnType.isAssignableFrom(Integer.class)) {
+ return returnType.cast(valueByte.intValue());
+ } else if (returnType.isAssignableFrom(Long.class)) {
+ return returnType.cast(valueByte.longValue());
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType));
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value, final EdmLiteralKind literalKind, final EdmFacets facets) throws EdmSimpleTypeException {
+ if (value instanceof Byte) {
+ return value.toString();
+ } else if (value instanceof Short || value instanceof Integer || value instanceof Long) {
+ if (((Number) value).longValue() >= Byte.MIN_VALUE && ((Number) value).longValue() <= Byte.MAX_VALUE) {
+ return value.toString();
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_ILLEGAL_CONTENT.addContent(value));
+ }
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass()));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmSimpleTypeFacadeImpl.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmSimpleTypeFacadeImpl.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmSimpleTypeFacadeImpl.java
new file mode 100644
index 0000000..08c8c9c
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmSimpleTypeFacadeImpl.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * 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.odata2.core.edm;
+
+import org.apache.olingo.odata2.api.edm.EdmLiteral;
+import org.apache.olingo.odata2.api.edm.EdmLiteralException;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeFacade;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+/**
+ * @author SAP AG
+ */
+public class EdmSimpleTypeFacadeImpl implements EdmSimpleTypeFacade {
+
+ @Override
+ public EdmLiteral parseUriLiteral(final String uriLiteral) throws EdmLiteralException {
+ if (uriLiteral == null || "null".equals(uriLiteral)) {
+ return new EdmLiteral(getEdmSimpleType(EdmSimpleTypeKind.Null), uriLiteral);
+ }
+
+ if ("true".equals(uriLiteral) || "false".equals(uriLiteral)) {
+ return new EdmLiteral(getEdmSimpleType(EdmSimpleTypeKind.Boolean), uriLiteral);
+ }
+
+ if (uriLiteral.length() >= 2
+ && uriLiteral.startsWith("'") && uriLiteral.endsWith("'")) {
+ try {
+ final EdmSimpleType type = getEdmSimpleType(EdmSimpleTypeKind.String);
+ return new EdmLiteral(type, type.valueOfString(uriLiteral, EdmLiteralKind.URI, null, String.class));
+ } catch (EdmSimpleTypeException e) {
+ throw new EdmLiteralException(EdmLiteralException.LITERALFORMAT.addContent(uriLiteral), e);
+ }
+ }
+
+ if (uriLiteral.matches("-?\\p{Digit}+")) {
+ try {
+ final int i = getEdmSimpleType(EdmSimpleTypeKind.Int32).valueOfString(uriLiteral, EdmLiteralKind.URI, null, Integer.class);
+ if (i == 0 || i == 1) {
+ return new EdmLiteral(getInternalEdmSimpleTypeByString("Bit"), uriLiteral);
+ }
+ if (i >= 0 && i <= Byte.MAX_VALUE) {
+ return new EdmLiteral(getInternalEdmSimpleTypeByString("Uint7"), uriLiteral);
+ }
+ if (i >= Byte.MIN_VALUE && i < 0) {
+ return new EdmLiteral(getEdmSimpleType(EdmSimpleTypeKind.SByte), uriLiteral);
+ } else if (i > Byte.MAX_VALUE && i <= 255) {
+ return new EdmLiteral(getEdmSimpleType(EdmSimpleTypeKind.Byte), uriLiteral);
+ } else if (i >= Short.MIN_VALUE && i <= Short.MAX_VALUE) {
+ return new EdmLiteral(getEdmSimpleType(EdmSimpleTypeKind.Int16), uriLiteral);
+ } else {
+ return new EdmLiteral(getEdmSimpleType(EdmSimpleTypeKind.Int32), uriLiteral);
+ }
+ } catch (EdmSimpleTypeException e) {
+ throw new EdmLiteralException(EdmLiteralException.LITERALFORMAT.addContent(uriLiteral), e);
+ }
+ }
+
+ if (uriLiteral.endsWith("L") || uriLiteral.endsWith("l")) {
+ return createEdmLiteral(EdmSimpleTypeKind.Int64, uriLiteral, 0, 1);
+ }
+ if (uriLiteral.endsWith("M") || uriLiteral.endsWith("m")) {
+ return createEdmLiteral(EdmSimpleTypeKind.Decimal, uriLiteral, 0, 1);
+ }
+ if (uriLiteral.endsWith("D") || uriLiteral.endsWith("d")) {
+ return createEdmLiteral(EdmSimpleTypeKind.Double, uriLiteral, 0, 1);
+ }
+ if (uriLiteral.equals("-INF") || uriLiteral.equals("INF") || uriLiteral.equals("NaN")) {
+ return new EdmLiteral(getEdmSimpleType(EdmSimpleTypeKind.Single), uriLiteral);
+ }
+ if (uriLiteral.endsWith("F") || uriLiteral.endsWith("f")) {
+ return createEdmLiteral(EdmSimpleTypeKind.Single, uriLiteral, 0, 1);
+ }
+
+ if (uriLiteral.startsWith("datetime'")) {
+ return createEdmLiteral(EdmSimpleTypeKind.DateTime, uriLiteral, 9, 1);
+ }
+ if (uriLiteral.startsWith("datetimeoffset'")) {
+ return createEdmLiteral(EdmSimpleTypeKind.DateTimeOffset, uriLiteral, 15, 1);
+ }
+ if (uriLiteral.startsWith("guid'")) {
+ return createEdmLiteral(EdmSimpleTypeKind.Guid, uriLiteral, 5, 1);
+ }
+ if (uriLiteral.startsWith("time'")) {
+ return createEdmLiteral(EdmSimpleTypeKind.Time, uriLiteral, 5, 1);
+ }
+
+ if (uriLiteral.startsWith("X'") || uriLiteral.startsWith("binary'")) {
+ try {
+ final EdmSimpleType type = getEdmSimpleType(EdmSimpleTypeKind.Binary);
+ final byte[] value = type.valueOfString(uriLiteral, EdmLiteralKind.URI, null, byte[].class);
+ return new EdmLiteral(type, type.valueToString(value, EdmLiteralKind.DEFAULT, null));
+ } catch (EdmSimpleTypeException e) {
+ throw new EdmLiteralException(EdmLiteralException.LITERALFORMAT.addContent(uriLiteral), e);
+ }
+ }
+
+ throw new EdmLiteralException(EdmLiteralException.UNKNOWNLITERAL.addContent(uriLiteral));
+ }
+
+ private static EdmLiteral createEdmLiteral(final EdmSimpleTypeKind typeKind, final String literal, final int prefixLength, final int suffixLength) throws EdmLiteralException {
+ final EdmSimpleType type = getEdmSimpleType(typeKind);
+ if (type.validate(literal, EdmLiteralKind.URI, null)) {
+ return new EdmLiteral(type, literal.substring(prefixLength, literal.length() - suffixLength));
+ } else {
+ throw new EdmLiteralException(EdmLiteralException.LITERALFORMAT.addContent(literal));
+ }
+ }
+
+ @Override
+ public EdmSimpleType getEdmSimpleTypeInstance(final EdmSimpleTypeKind typeKind) {
+ return getEdmSimpleType(typeKind);
+ }
+
+ public static EdmSimpleType getEdmSimpleType(final EdmSimpleTypeKind typeKind) {
+
+ switch (typeKind) {
+ case Binary:
+ return EdmBinary.getInstance();
+ case Boolean:
+ return EdmBoolean.getInstance();
+ case Byte:
+ return EdmByte.getInstance();
+ case DateTime:
+ return EdmDateTime.getInstance();
+ case DateTimeOffset:
+ return EdmDateTimeOffset.getInstance();
+ case Decimal:
+ return EdmDecimal.getInstance();
+ case Double:
+ return EdmDouble.getInstance();
+ case Guid:
+ return EdmGuid.getInstance();
+ case Int16:
+ return EdmInt16.getInstance();
+ case Int32:
+ return EdmInt32.getInstance();
+ case Int64:
+ return EdmInt64.getInstance();
+ case SByte:
+ return EdmSByte.getInstance();
+ case Single:
+ return EdmSingle.getInstance();
+ case String:
+ return EdmString.getInstance();
+ case Time:
+ return EdmTime.getInstance();
+ case Null:
+ return EdmNull.getInstance();
+ default:
+ throw new ODataRuntimeException("Invalid Type " + typeKind);
+ }
+ }
+
+ public static EdmSimpleType getInternalEdmSimpleTypeByString(final String edmSimpleType) {
+ if ("Bit".equals(edmSimpleType)) {
+ return Bit.getInstance();
+ } else if ("Uint7".equals(edmSimpleType)) {
+ return Uint7.getInstance();
+ } else {
+ throw new ODataRuntimeException("Invalid internal Type " + edmSimpleType);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmSingle.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmSingle.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmSingle.java
new file mode 100644
index 0000000..5e33fd6
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmSingle.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * 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.odata2.core.edm;
+
+import java.math.BigDecimal;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+
+/**
+ * Implementation of the EDM simple type Single.
+ * @author SAP AG
+ */
+public class EdmSingle extends AbstractSimpleType {
+
+ // value-range limitations according to the CSDL document
+ private static final int MAX_PRECISION = 7;
+ private static final int MAX_SCALE = 38;
+
+ private static final Pattern PATTERN = Pattern.compile(
+ "(?:\\+|-)?\\p{Digit}{1,7}(?:\\.\\p{Digit}{1,7})?(?:(?:E|e)(?:\\+|-)?\\p{Digit}{1,2})?(F|f)?");
+ private static final EdmSingle instance = new EdmSingle();
+
+ public static EdmSingle getInstance() {
+ return instance;
+ }
+
+ @Override
+ public boolean isCompatible(final EdmSimpleType simpleType) {
+ return simpleType instanceof Bit
+ || simpleType instanceof Uint7
+ || simpleType instanceof EdmByte
+ || simpleType instanceof EdmSByte
+ || simpleType instanceof EdmInt16
+ || simpleType instanceof EdmInt32
+ || simpleType instanceof EdmInt64
+ || simpleType instanceof EdmSingle;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return Float.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value, final EdmLiteralKind literalKind, final EdmFacets facets, final Class<T> returnType) throws EdmSimpleTypeException {
+ String valueString = value;
+ Float result = null;
+ // Handle special values first.
+ if (value.equals("-INF")) {
+ result = Float.NEGATIVE_INFINITY;
+ } else if (value.equals("INF")) {
+ result = Float.POSITIVE_INFINITY;
+ } else if (value.equals("NaN")) {
+ result = Float.NaN;
+ } else {
+ // Now only "normal" numbers remain.
+ final Matcher matcher = PATTERN.matcher(value);
+ if (!matcher.matches()
+ || (literalKind == EdmLiteralKind.URI) == (matcher.group(1) == null)) {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
+ }
+
+ if (literalKind == EdmLiteralKind.URI) {
+ valueString = value.substring(0, value.length() - 1);
+ }
+
+ // The number format is checked above, so we don't have to catch NumberFormatException.
+ result = Float.valueOf(valueString);
+ // "Real" infinite values have been treated already above, so we can throw an exception
+ // if the conversion to a float results in an infinite value.
+ if (result.isInfinite()) {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
+ }
+ }
+
+ if (returnType.isAssignableFrom(Float.class)) {
+ return returnType.cast(result);
+ } else if (returnType.isAssignableFrom(Double.class)) {
+ if (result.isInfinite() || result.isNaN()) {
+ return returnType.cast(result.doubleValue());
+ } else {
+ return returnType.cast(Double.valueOf(valueString));
+ }
+ } else if (result.isInfinite() || result.isNaN()) {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType));
+ } else {
+ try {
+ final BigDecimal valueBigDecimal = new BigDecimal(valueString);
+ if (returnType.isAssignableFrom(BigDecimal.class)) {
+ return returnType.cast(valueBigDecimal);
+ } else if (returnType.isAssignableFrom(Long.class)) {
+ return returnType.cast(valueBigDecimal.longValueExact());
+ } else if (returnType.isAssignableFrom(Integer.class)) {
+ return returnType.cast(valueBigDecimal.intValueExact());
+ } else if (returnType.isAssignableFrom(Short.class)) {
+ return returnType.cast(valueBigDecimal.shortValueExact());
+ } else if (returnType.isAssignableFrom(Byte.class)) {
+ return returnType.cast(valueBigDecimal.byteValueExact());
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType));
+ }
+
+ } catch (final ArithmeticException e) {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType), e);
+ }
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value, final EdmLiteralKind literalKind, final EdmFacets facets) throws EdmSimpleTypeException {
+ if (value instanceof Long || value instanceof Integer) {
+ if (Math.abs(((Number) value).longValue()) < Math.pow(10, MAX_PRECISION)) {
+ return value.toString();
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_ILLEGAL_CONTENT.addContent(value));
+ }
+ } else if (value instanceof Short || value instanceof Byte) {
+ return value.toString();
+ } else if (value instanceof Double) {
+ if (((Double) value).isInfinite()) {
+ return value.toString().toUpperCase(Locale.ROOT).substring(0, value.toString().length() - 5);
+ } else if (Float.isInfinite(((Double) value).floatValue())) {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_ILLEGAL_CONTENT.addContent(value));
+ } else {
+ return Float.toString(((Double) value).floatValue());
+ }
+ } else if (value instanceof Float) {
+ final String result = value.toString();
+ return ((Float) value).isInfinite() ? result.toUpperCase(Locale.ROOT).substring(0, value.toString().length() - 5) : result;
+ } else if (value instanceof BigDecimal) {
+ if (((BigDecimal) value).precision() <= MAX_PRECISION && Math.abs(((BigDecimal) value).scale()) <= MAX_SCALE) {
+ return ((BigDecimal) value).toString();
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_ILLEGAL_CONTENT.addContent(value));
+ }
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass()));
+ }
+ }
+
+ @Override
+ public String toUriLiteral(final String literal) {
+ return literal.equals("-INF") || literal.equals("INF") || literal.equals("NaN") ?
+ literal : literal + "F";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmString.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmString.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmString.java
new file mode 100644
index 0000000..43eda7e
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmString.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * 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.odata2.core.edm;
+
+import java.util.regex.Pattern;
+
+import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+
+/**
+ * Implementation of the EDM simple type String.
+ * @author SAP AG
+ */
+public class EdmString extends AbstractSimpleType {
+
+ private static final Pattern PATTERN_ASCII = Pattern.compile("\\p{ASCII}*");
+ private static final EdmString instance = new EdmString();
+
+ public static EdmString getInstance() {
+ return instance;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return String.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value, final EdmLiteralKind literalKind, final EdmFacets facets, final Class<T> returnType) throws EdmSimpleTypeException {
+ String result;
+ if (literalKind == EdmLiteralKind.URI) {
+ if (value.length() >= 2 && value.startsWith("'") && value.endsWith("'")) {
+ result = (value.substring(1, value.length() - 1)).replace("''", "'");
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
+ }
+ } else {
+ result = value;
+ }
+
+ if (facets != null
+ && (facets.isUnicode() != null && !facets.isUnicode() && !PATTERN_ASCII.matcher(result).matches()
+ || facets.getMaxLength() != null && facets.getMaxLength() < result.length())) {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_FACETS_NOT_MATCHED.addContent(value, facets));
+ }
+
+ if (returnType.isAssignableFrom(String.class)) {
+ return returnType.cast(result);
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType));
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value, final EdmLiteralKind literalKind, final EdmFacets facets) throws EdmSimpleTypeException {
+ final String result = value instanceof String ? (String) value : String.valueOf(value);
+
+ if (facets != null
+ && (facets.isUnicode() != null && !facets.isUnicode() && !PATTERN_ASCII.matcher(result).matches()
+ || facets.getMaxLength() != null && facets.getMaxLength() < result.length())) {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_FACETS_NOT_MATCHED.addContent(value, facets));
+ }
+
+ return result;
+ }
+
+ @Override
+ public String toUriLiteral(final String literal) throws EdmSimpleTypeException {
+ final int length = literal.length();
+
+ StringBuilder uriLiteral = new StringBuilder(length + 2);
+ uriLiteral.append('\'');
+ for (int i = 0; i < length; i++) {
+ final char c = literal.charAt(i);
+ if (c == '\'') {
+ uriLiteral.append(c);
+ }
+ uriLiteral.append(c);
+ }
+ uriLiteral.append('\'');
+ return uriLiteral.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmTime.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmTime.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmTime.java
new file mode 100644
index 0000000..304aecb
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmTime.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * 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.odata2.core.edm;
+
+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.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+
+/**
+ * <p>Implementation of the EDM simple type Time.</p>
+ * <p>Arguably, this type is intended to represent a time of day, not an instance in time.
+ * The time value is interpreted and formatted as local time.</p>
+ * <p>Formatting simply ignores the year, month, and day parts of time instances.
+ * Parsing returns a Calendar object where all unused fields have been cleared.</p>
+ * @author SAP AG
+ */
+public class EdmTime extends AbstractSimpleType {
+
+ private static final Pattern PATTERN = Pattern.compile(
+ "PT(?:(\\p{Digit}{1,2})H)?(?:(\\p{Digit}{1,4})M)?(?:(\\p{Digit}{1,5})(?:\\.(\\p{Digit}+?)0*)?S)?");
+ private static final EdmTime instance = new EdmTime();
+
+ public static EdmTime getInstance() {
+ return instance;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return Calendar.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value, final EdmLiteralKind literalKind, final EdmFacets facets, final Class<T> returnType) throws EdmSimpleTypeException {
+ Calendar valueCalendar;
+ if (literalKind == EdmLiteralKind.URI) {
+ if (value.length() > 6 && value.startsWith("time'") && value.endsWith("'")) {
+ valueCalendar = parseLiteral(value.substring(5, value.length() - 1), facets);
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
+ }
+ } else {
+ valueCalendar = parseLiteral(value, facets);
+ }
+
+ if (returnType.isAssignableFrom(Calendar.class)) {
+ return returnType.cast(valueCalendar);
+ } else if (returnType.isAssignableFrom(Long.class)) {
+ return returnType.cast(valueCalendar.getTimeInMillis());
+ } else if (returnType.isAssignableFrom(Date.class)) {
+ return returnType.cast(valueCalendar.getTime());
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType));
+ }
+ }
+
+ private Calendar parseLiteral(final String literal, final EdmFacets facets) throws EdmSimpleTypeException {
+ final Matcher matcher = PATTERN.matcher(literal);
+ if (!matcher.matches()
+ || (matcher.group(1) == null && matcher.group(2) == null && matcher.group(3) == null)) {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(literal));
+ }
+
+ Calendar dateTimeValue = Calendar.getInstance();
+ dateTimeValue.clear();
+
+ if (matcher.group(1) != null) {
+ dateTimeValue.set(Calendar.HOUR_OF_DAY, Integer.parseInt(matcher.group(1)));
+ }
+ if (matcher.group(2) != null) {
+ dateTimeValue.set(Calendar.MINUTE, Integer.parseInt(matcher.group(2)));
+ }
+ if (matcher.group(3) != null) {
+ dateTimeValue.set(Calendar.SECOND, Integer.parseInt(matcher.group(3)));
+ }
+
+ if (matcher.group(4) != null) {
+ if (facets == null || facets.getPrecision() == null || facets.getPrecision() >= matcher.group(4).length()) {
+ if (matcher.group(4).length() <= 3) {
+ dateTimeValue.set(Calendar.MILLISECOND,
+ Short.parseShort(matcher.group(4) + "000".substring(0, 3 - matcher.group(4).length())));
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(literal));
+ }
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_FACETS_NOT_MATCHED.addContent(literal, facets));
+ }
+ }
+
+ if (dateTimeValue.get(Calendar.DAY_OF_YEAR) == 1) {
+ return dateTimeValue;
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(literal));
+ }
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value, final EdmLiteralKind literalKind, final EdmFacets facets) throws EdmSimpleTypeException {
+ Calendar dateTimeValue;
+ if (value instanceof Date) {
+ dateTimeValue = Calendar.getInstance();
+ dateTimeValue.clear();
+ 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.clear();
+ dateTimeValue.setTimeInMillis((Long) value);
+ } else {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass()));
+ }
+
+ StringBuilder result = new StringBuilder(15); // 15 characters are enough for millisecond precision.
+ result.append('P');
+ result.append('T');
+ result.append(dateTimeValue.get(Calendar.HOUR_OF_DAY));
+ result.append('H');
+ result.append(dateTimeValue.get(Calendar.MINUTE));
+ result.append('M');
+ result.append(dateTimeValue.get(Calendar.SECOND));
+
+ try {
+ EdmDateTime.appendMilliseconds(result, dateTimeValue.get(Calendar.MILLISECOND), facets);
+ } catch (final IllegalArgumentException e) {
+ throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_FACETS_NOT_MATCHED.addContent(value, facets), e);
+ }
+
+ result.append('S');
+
+ return result.toString();
+ }
+
+ @Override
+ public String toUriLiteral(final String literal) {
+ return "time'" + literal + "'";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/Uint7.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/Uint7.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/Uint7.java
new file mode 100644
index 0000000..3ffc348
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/Uint7.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * 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.odata2.core.edm;
+
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+
+/**
+ * Implementation of the internal simple type "unsigned 7-bit integer".
+ * @author SAP AG
+ */
+public class Uint7 extends AbstractSimpleType {
+
+ private static final Uint7 instance = new Uint7();
+
+ public static Uint7 getInstance() {
+ return instance;
+ }
+
+ @Override
+ public String getNamespace() throws EdmException {
+ return SYSTEM_NAMESPACE;
+ }
+
+ @Override
+ public boolean isCompatible(final EdmSimpleType simpleType) {
+ return simpleType instanceof Bit || simpleType instanceof Uint7;
+ }
+
+ @Override
+ public Class<?> getDefaultType() {
+ return Byte.class;
+ }
+
+ @Override
+ protected <T> T internalValueOfString(final String value, final EdmLiteralKind literalKind, final EdmFacets facets, final Class<T> returnType) throws EdmSimpleTypeException {
+ return EdmSByte.getInstance().internalValueOfString(value, literalKind, facets, returnType);
+ }
+
+ @Override
+ protected <T> String internalValueToString(final T value, final EdmLiteralKind literalKind, final EdmFacets facets) throws EdmSimpleTypeException {
+ return EdmSByte.getInstance().internalValueToString(value, literalKind, facets);
+ }
+}