diff --git a/odata4-lib/odata4-commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java b/odata4-lib/odata4-commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java index 01a3e3136..b7d3bcd78 100644 --- a/odata4-lib/odata4-commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java +++ b/odata4-lib/odata4-commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java @@ -83,11 +83,11 @@ public interface Edm { * @param functionName * @param bindingParameterTypeName may be null if it is an unbound function * @param isBindingParameterCollection may be null if it is an unbound function - * @param bindingParameterNames may be null if it is an unbound function + * @param parameterNames may be null if it is an unbound function * @return {@link EdmFunction} */ EdmFunction getFunction(FullQualifiedName functionName, FullQualifiedName bindingParameterTypeName, - Boolean isBindingParameterCollection, List bindingParameterNames); + Boolean isBindingParameterCollection, List parameterNames); /** * Get service metadata

See {@link EdmServiceMetadata} for more information. diff --git a/odata4-lib/odata4-commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmMapping.java b/odata4-lib/odata4-commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmMapping.java index efbb6317a..f27713d88 100644 --- a/odata4-lib/odata4-commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmMapping.java +++ b/odata4-lib/odata4-commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmMapping.java @@ -30,13 +30,6 @@ public interface EdmMapping { */ String getInternalName(); - /** - * Get the mapping name for mime type lookup - * - * @return mapping name as String - */ - String getMimeType(); - /** * Get the set object for this mapping * diff --git a/odata4-lib/odata4-commons-core/pom.xml b/odata4-lib/odata4-commons-core/pom.xml index f9ce5e941..6458dea4d 100644 --- a/odata4-lib/odata4-commons-core/pom.xml +++ b/odata4-lib/odata4-commons-core/pom.xml @@ -38,5 +38,10 @@ olingo-odata4-commons-api-incubating ${project.version} + + commons-codec + commons-codec + ${commonscodec.version} + diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/ActionMapKey.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/ActionMapKey.java new file mode 100644 index 000000000..f4ac15bee --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/ActionMapKey.java @@ -0,0 +1,58 @@ +package org.apache.olingo.commons.core.edm; + +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; + +public class ActionMapKey { + private final FullQualifiedName actionName; + private final FullQualifiedName bindingParameterTypeName; + private final Boolean isBindingParameterCollection; + + public ActionMapKey(final FullQualifiedName actionName, final FullQualifiedName bindingParameterTypeName, + final Boolean isBindingParameterCollection) { + this.actionName = actionName; + this.bindingParameterTypeName = bindingParameterTypeName; + this.isBindingParameterCollection = isBindingParameterCollection; + } + + @Override + public int hashCode() { + String forHash = actionName.toString(); + + if (bindingParameterTypeName != null) { + forHash = forHash + bindingParameterTypeName.toString(); + } else { + forHash = forHash + "TypeNull"; + } + + if (isBindingParameterCollection != null) { + forHash = forHash + isBindingParameterCollection.toString(); + } else { + forHash = forHash + "CollectionNull"; + } + + return forHash.hashCode(); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if ((obj == null) || !(obj instanceof ActionMapKey)) { + return false; + } + final ActionMapKey other = (ActionMapKey) obj; + + if (actionName.equals(other.actionName)) { + if ((bindingParameterTypeName == null && other.bindingParameterTypeName == null) + || (bindingParameterTypeName != null && bindingParameterTypeName.equals(other.bindingParameterTypeName))) { + if ((isBindingParameterCollection == null && other.isBindingParameterCollection == null) + || (isBindingParameterCollection != null && isBindingParameterCollection + .equals(other.isBindingParameterCollection))) { + return true; + } + } + } + return false; + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmImpl.java new file mode 100644 index 000000000..c127c859a --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmImpl.java @@ -0,0 +1,170 @@ +/******************************************************************************* + * 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.commons.core.edm; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.EdmAction; +import org.apache.olingo.commons.api.edm.EdmComplexType; +import org.apache.olingo.commons.api.edm.EdmEntityContainer; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmEnumType; +import org.apache.olingo.commons.api.edm.EdmFunction; +import org.apache.olingo.commons.api.edm.EdmServiceMetadata; +import org.apache.olingo.commons.api.edm.EdmTypeDefinition; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; + +public abstract class EdmImpl implements Edm { + + private final Map entityContainers = + new HashMap(); + private final Map enumTypes = new HashMap(); + private final Map typeDefinitions = + new HashMap(); + private final Map entityTypes = new HashMap(); + private final Map complexTypes = new HashMap(); + private final Map actions = new HashMap(); + private final Map functions = new HashMap(); + private EdmServiceMetadata serviceMetadata; + + @Override + public EdmEntityContainer getEntityContainer(final FullQualifiedName fqn) { + EdmEntityContainer container = entityContainers.get(fqn); + if (container == null) { + container = createEntityContainer(fqn); + if (container != null) { + entityContainers.put(fqn, container); + if (fqn == null) { + entityContainers.put(new FullQualifiedName(container.getNamespace(), container.getName()), container); + } + } + } + return container; + } + + @Override + public EdmEnumType getEnumType(final FullQualifiedName fqn) { + EdmEnumType enumType = enumTypes.get(fqn); + if (enumType == null) { + enumType = createEnumType(fqn); + if (enumType != null) { + enumTypes.put(fqn, enumType); + } + } + return enumType; + } + + @Override + public EdmTypeDefinition getTypeDefinition(final FullQualifiedName fqn) { + EdmTypeDefinition typeDefinition = typeDefinitions.get(fqn); + if (typeDefinition == null) { + typeDefinition = createTypeDefinition(fqn); + if (typeDefinition != null) { + typeDefinitions.put(fqn, typeDefinition); + } + } + return typeDefinition; + } + + @Override + public EdmEntityType getEntityType(final FullQualifiedName fqn) { + EdmEntityType entityType = entityTypes.get(fqn); + if (entityType == null) { + entityType = createEntityType(fqn); + if (entityType != null) { + entityTypes.put(fqn, entityType); + } + } + return entityType; + } + + @Override + public EdmComplexType getComplexType(final FullQualifiedName fqn) { + EdmComplexType complexType = complexTypes.get(fqn); + if (complexType == null) { + complexType = createComplexType(fqn); + if (complexType != null) { + complexTypes.put(fqn, complexType); + } + } + return complexType; + } + + @Override + public EdmAction getAction(final FullQualifiedName actionName, final FullQualifiedName bindingParameterTypeName, + final Boolean isBindingParameterCollection) { + ActionMapKey key = new ActionMapKey(actionName, bindingParameterTypeName, isBindingParameterCollection); + EdmAction action = actions.get(key); + if (action == null) { + action = createAction(actionName, bindingParameterTypeName, isBindingParameterCollection); + if (action != null) { + actions.put(key, action); + } + } + return action; + } + + @Override + public EdmFunction getFunction(final FullQualifiedName functionName, + final FullQualifiedName bindingParameterTypeName, + final Boolean isBindingParameterCollection, final List parameterNames) { + FunctionMapKey key = + new FunctionMapKey(functionName, bindingParameterTypeName, isBindingParameterCollection, parameterNames); + EdmFunction function = functions.get(key); + if (function == null) { + function = createFunction(functionName, bindingParameterTypeName, isBindingParameterCollection, + parameterNames); + if (function != null) { + functions.put(key, function); + } + } + return function; + } + + @Override + public EdmServiceMetadata getServiceMetadata() { + if (serviceMetadata == null) { + serviceMetadata = createServiceMetadata(); + } + return serviceMetadata; + } + + public abstract EdmEntityContainer createEntityContainer(FullQualifiedName containerName); + + public abstract EdmEnumType createEnumType(FullQualifiedName enumName); + + public abstract EdmTypeDefinition createTypeDefinition(FullQualifiedName typeDefinitionName); + + public abstract EdmEntityType createEntityType(FullQualifiedName entityTypeName); + + public abstract EdmComplexType createComplexType(FullQualifiedName complexTypeName); + + public abstract EdmAction createAction(FullQualifiedName actionName, FullQualifiedName bindingPatameterTypeName, + Boolean isBindingParameterCollection); + + public abstract EdmFunction createFunction(FullQualifiedName functionName, + FullQualifiedName bindingPatameterTypeName, Boolean isBindingParameterCollection, + List parameterNames); + + public abstract EdmServiceMetadata createServiceMetadata(); + +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/FunctionMapKey.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/FunctionMapKey.java new file mode 100644 index 000000000..ea7527639 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/FunctionMapKey.java @@ -0,0 +1,82 @@ +package org.apache.olingo.commons.core.edm; + +import java.util.List; + +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; + +public class FunctionMapKey { + + private final FullQualifiedName functionName; + private final FullQualifiedName bindingParameterTypeName; + private final Boolean isBindingParameterCollection; + private final List parameterNames; + + public FunctionMapKey(final FullQualifiedName functionName, final FullQualifiedName bindingParameterTypeName, + final Boolean isBindingParameterCollection, final List bindingParameterNames) { + this.functionName = functionName; + this.bindingParameterTypeName = bindingParameterTypeName; + this.isBindingParameterCollection = isBindingParameterCollection; + parameterNames = bindingParameterNames; + } + + @Override + public int hashCode() { + String hash = functionName.toString(); + + if (bindingParameterTypeName != null) { + hash = hash + bindingParameterTypeName.toString(); + } else { + hash = hash + "typeNull"; + } + + if (isBindingParameterCollection != null) { + hash = hash + isBindingParameterCollection.toString(); + } else { + hash = hash + "collectionNull"; + } + + // TODO: Sort!! + if (parameterNames != null) { + for (String name : parameterNames) { + hash = hash + name; + } + } else { + hash = hash + "parameterNamesNull"; + } + + return hash.hashCode(); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if ((obj == null) || !(obj instanceof FunctionMapKey)) { + return false; + } + final FunctionMapKey other = (FunctionMapKey) obj; + + if (functionName.equals(other.functionName)) { + if ((bindingParameterTypeName == null && other.bindingParameterTypeName == null) + || (bindingParameterTypeName != null && bindingParameterTypeName.equals(other.bindingParameterTypeName))) { + if ((isBindingParameterCollection == null && other.isBindingParameterCollection == null) + || (isBindingParameterCollection != null && isBindingParameterCollection + .equals(other.isBindingParameterCollection))) { + if (parameterNames == null && other.parameterNames == null) { + return true; + } else if (parameterNames != null && other.parameterNames != null + && parameterNames.size() == other.parameterNames.size()) { + for (String name : parameterNames) { + if (!other.parameterNames.contains(name)) { + return false; + } + } + return true; + } + } + } + } + return false; + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/AbstractPrimitiveType.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/AbstractPrimitiveType.java new file mode 100644 index 000000000..780df7d96 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/AbstractPrimitiveType.java @@ -0,0 +1,91 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; +import org.apache.olingo.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 valueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class 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 internalValueOfString(String value, + Boolean isNullable, Integer maxLength, Integer precision, Integer scale, Boolean isUnicode, + Class 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 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(); + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBinary.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBinary.java new file mode 100644 index 000000000..dc830d2b3 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBinary.java @@ -0,0 +1,95 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import org.apache.commons.codec.binary.Base64; +import org.apache.olingo.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 internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class 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 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); + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBoolean.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBoolean.java new file mode 100644 index 000000000..da868d87b --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBoolean.java @@ -0,0 +1,60 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import org.apache.olingo.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 internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class 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 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())"); + } + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmByte.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmByte.java new file mode 100644 index 000000000..841122923 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmByte.java @@ -0,0 +1,81 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import java.math.BigInteger; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.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 internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class 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 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())"); + } + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java new file mode 100644 index 000000000..6a1912f38 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java @@ -0,0 +1,75 @@ +package org.apache.olingo.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.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 internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class 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 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(); + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java new file mode 100644 index 000000000..c1f3fa886 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java @@ -0,0 +1,213 @@ +package org.apache.olingo.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.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 internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class 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 convertDateTime(final Calendar dateTimeValue, final Class 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 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 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 0 <= number <= 99 + */ + 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 0 <= milliseconds <= 999 + * @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(); + } + } + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDecimal.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDecimal.java new file mode 100644 index 000000000..2db4b8344 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDecimal.java @@ -0,0 +1,176 @@ +package org.apache.olingo.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.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.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 internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class 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 convertDecimal(final BigDecimal value, final Class 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 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; + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDouble.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDouble.java new file mode 100644 index 000000000..47c60ef64 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDouble.java @@ -0,0 +1,123 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import java.math.BigDecimal; +import java.util.regex.Pattern; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.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 internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class 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 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())"); + } + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDuration.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDuration.java new file mode 100644 index 000000000..c65feb398 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDuration.java @@ -0,0 +1,119 @@ +package org.apache.olingo.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.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 internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class 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 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(); + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmEnum.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmEnum.java new file mode 100644 index 000000000..f7b24630d --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmEnum.java @@ -0,0 +1,147 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.olingo.commons.api.edm.EdmEnumType; +import org.apache.olingo.commons.api.edm.EdmMember; +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; +import org.apache.olingo.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 members; + private final Boolean isFlags; + + public EdmEnum(final String namespace, final String name, + final EdmPrimitiveType underlyingType, final List 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 getMemberNames() { + List names = new ArrayList(); + for (final EdmMember member : members) { + names.add(member.getName()); + } + return names; + } + + @Override + public EdmPrimitiveType getUnderlyingType() { + return underlyingType; + } + + @Override + protected T internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class 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(); + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmGuid.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmGuid.java new file mode 100644 index 000000000..649f8fb8a --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmGuid.java @@ -0,0 +1,67 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import java.util.UUID; + +import org.apache.olingo.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 internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, + final Class 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 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())"); + } + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt16.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt16.java new file mode 100644 index 000000000..a8693866d --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt16.java @@ -0,0 +1,81 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import java.math.BigInteger; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.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 internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class 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 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())"); + } + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt32.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt32.java new file mode 100644 index 000000000..0bc31337f --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt32.java @@ -0,0 +1,80 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import java.math.BigInteger; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.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 internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class 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 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())"); + } + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt64.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt64.java new file mode 100644 index 000000000..541032ca2 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt64.java @@ -0,0 +1,113 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import java.math.BigInteger; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.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 internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class 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 convertNumber(final Number value, final Class 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 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())"); + } + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmNull.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmNull.java new file mode 100644 index 000000000..cfb02af4f --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmNull.java @@ -0,0 +1,55 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import org.apache.olingo.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 internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class returnType) throws EdmPrimitiveTypeException { + return null; + } + + @Override + protected 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; + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmPrimitiveTypeKind.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmPrimitiveTypeKind.java new file mode 100644 index 000000000..703db1eba --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmPrimitiveTypeKind.java @@ -0,0 +1,61 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; + +//TODO: Should we delete this typekind and use a facade? +public enum EdmPrimitiveTypeKind { + Binary, Boolean, Byte, Date, DateTimeOffset, Decimal, Double, Duration, Guid, + Int16, Int32, Int64, SByte, Single, String, TimeOfDay; + + /** + * Returns the {@link FullQualifiedName} for this type kind. + * @return {@link FullQualifiedName} + */ + public FullQualifiedName getFullQualifiedName() { + return new FullQualifiedName(EdmPrimitiveType.EDM_NAMESPACE, toString()); + } + + /** + * Returns an instance for this {@link EdmPrimitiveTypeKind} in the form of {@link EdmPrimitiveType}. + * @return {@link EdmPrimitiveType} instance + */ + public EdmPrimitiveType getEdmPrimitiveTypeInstance() { + switch (this) { + case Binary: + return EdmBinary.getInstance(); + case Boolean: + return EdmBoolean.getInstance(); + case Byte: + return EdmByte.getInstance(); + case Date: + return EdmDate.getInstance(); + case DateTimeOffset: + return EdmDateTimeOffset.getInstance(); + case Decimal: + return EdmDecimal.getInstance(); + case Double: + return EdmDouble.getInstance(); + case Duration: + return EdmDuration.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 TimeOfDay: + return EdmTimeOfDay.getInstance(); + default: + throw new RuntimeException("Wrong type:" + this); + } + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmSByte.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmSByte.java new file mode 100644 index 000000000..c5c676dfa --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmSByte.java @@ -0,0 +1,75 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import java.math.BigInteger; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; + +/** + * Implementation of the EDM primitive type SByte. + */ +final class EdmSByte extends SingletonPrimitiveType { + + private static final EdmSByte instance = new EdmSByte(); + + public static EdmSByte getInstance() { + return instance; + } + + @Override + public boolean isCompatible(final EdmPrimitiveType primitiveType) { + return primitiveType instanceof Uint7 + || primitiveType instanceof EdmSByte; + } + + @Override + public Class getDefaultType() { + return Byte.class; + } + + @Override + protected T internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class returnType) throws EdmPrimitiveTypeException { + Byte valueByte; + try { + valueByte = Byte.parseByte(value); + } catch (final NumberFormatException e) { + throw new EdmPrimitiveTypeException( + "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)", e); + } + + try { + return EdmInt64.convertNumber(valueByte, returnType); + } catch (final ClassCastException e) { + throw new EdmPrimitiveTypeException( + "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType), e"); + } + } + + @Override + protected 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) { + 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 EdmPrimitiveTypeException( + "EdmPrimitiveTypeException.VALUE_ILLEGAL_CONTENT.addContent(value)"); + } + } else if (value instanceof BigInteger) { + if (((BigInteger) value).bitLength() < Byte.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())"); + } + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmSingle.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmSingle.java new file mode 100644 index 000000000..1ddde105c --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmSingle.java @@ -0,0 +1,127 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import java.math.BigDecimal; +import java.util.regex.Pattern; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; + +/** + * Implementation of the EDM primitive type Single. + */ +final class EdmSingle extends SingletonPrimitiveType { + + private static final Pattern PATTERN = Pattern.compile( + "(?:\\+|-)?\\p{Digit}{1,9}(?:\\.\\p{Digit}{1,9})?(?:(?:E|e)(?:\\+|-)?\\p{Digit}{1,2})?"); + private static final EdmSingle instance = new EdmSingle(); + + public static EdmSingle 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; + } + + @Override + public Class getDefaultType() { + return Float.class; + } + + @Override + protected T internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class returnType) throws EdmPrimitiveTypeException { + Float result = null; + BigDecimal bigDecimalValue = null; + // Handle special values first. + if (value.equals(EdmDouble.NEGATIVE_INFINITY)) { + result = Float.NEGATIVE_INFINITY; + } else if (value.equals(EdmDouble.POSITIVE_INFINITY)) { + result = Float.POSITIVE_INFINITY; + } else if (value.equals(EdmDouble.NaN)) { + result = Float.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.floatValue(); + // "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() || bigDecimalValue.compareTo(new BigDecimal(result.toString())) != 0) { + throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)"); + } + } + + if (returnType.isAssignableFrom(Float.class)) { + return returnType.cast(result); + } else if (result.isInfinite() || result.isNaN()) { + if (returnType.isAssignableFrom(Double.class)) { + return returnType.cast(result.doubleValue()); + } 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 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 || value instanceof Integer) { + if (Math.abs(((Number) value).longValue()) < 1L << 22) { + return value.toString(); + } else { + throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.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 (Double) value == Double.NEGATIVE_INFINITY ? EdmDouble.NEGATIVE_INFINITY : EdmDouble.POSITIVE_INFINITY; + } else { + final String floatString = Float.toString(((Double) value).floatValue()); + if (floatString.equals(((Double) value).toString())) { + return floatString; + } else { + throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.VALUE_ILLEGAL_CONTENT.addContent(value)"); + } + } + } else if (value instanceof Float) { + return (Float) value == Float.NEGATIVE_INFINITY ? EdmDouble.NEGATIVE_INFINITY : + (Float) value == Float.POSITIVE_INFINITY ? EdmDouble.POSITIVE_INFINITY : value.toString(); + } else if (value instanceof BigDecimal) { + final float floatValue = ((BigDecimal) value).floatValue(); + if (!Float.isInfinite(floatValue) && BigDecimal.valueOf(floatValue).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())"); + } + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmString.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmString.java new file mode 100644 index 000000000..5040395ad --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmString.java @@ -0,0 +1,86 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import java.util.regex.Pattern; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; + +/** + * Implementation of the EDM primitive type String. + */ +final class EdmString extends SingletonPrimitiveType { + + private static final Pattern PATTERN_ASCII = Pattern.compile("\\p{ASCII}*"); + private static final EdmString instance = new EdmString(); + { + uriPrefix = "'"; + uriSuffix = "'"; + } + + public static EdmString getInstance() { + return instance; + } + + @Override + public Class getDefaultType() { + return String.class; + } + + @Override + protected T internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class returnType) throws EdmPrimitiveTypeException { + if (isUnicode != null && !isUnicode && !PATTERN_ASCII.matcher(value).matches() + || maxLength != null && maxLength < value.length()) { + throw new EdmPrimitiveTypeException( + "EdmPrimitiveTypeException.LITERAL_FACETS_NOT_MATCHED.addContent(value, facets)"); + } + + if (returnType.isAssignableFrom(String.class)) { + return returnType.cast(value); + } else { + throw new EdmPrimitiveTypeException( + "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType)"); + } + } + + @Override + protected String internalValueToString(final T value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException { + final String result = value instanceof String ? (String) value : String.valueOf(value); + + if (isUnicode != null && !isUnicode && !PATTERN_ASCII.matcher(result).matches() + || maxLength != null && maxLength < result.length()) { + throw new EdmPrimitiveTypeException( + "EdmPrimitiveTypeException.VALUE_FACETS_NOT_MATCHED.addContent(value, facets)"); + } + + return result; + } + + @Override + public String toUriLiteral(final String literal) { + if (literal == null) { + return null; + } + + final int length = literal.length(); + + StringBuilder uriLiteral = new StringBuilder(length + 2); + uriLiteral.append(uriPrefix); + for (int i = 0; i < length; i++) { + final char c = literal.charAt(i); + if (c == '\'') { + uriLiteral.append(c); + } + uriLiteral.append(c); + } + uriLiteral.append(uriSuffix); + return uriLiteral.toString(); + } + + @Override + public String fromUriLiteral(final String literal) throws EdmPrimitiveTypeException { + return literal == null ? null : super.fromUriLiteral(literal).replace("''", "'"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java new file mode 100644 index 000000000..77411f1c3 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java @@ -0,0 +1,86 @@ +package org.apache.olingo.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.commons.api.edm.EdmPrimitiveTypeException; + +final class EdmTimeOfDay extends SingletonPrimitiveType { + + private static final Pattern PATTERN = Pattern.compile( + "(\\p{Digit}{2}):(\\p{Digit}{2})(?::(\\p{Digit}{2})(\\.(\\p{Digit}{0,3}?)0*)?)?"); + private static final EdmTimeOfDay instance = new EdmTimeOfDay(); + + public static EdmTimeOfDay getInstance() { + return instance; + } + + @Override + public Class getDefaultType() { + return Calendar.class; + } + + @Override + protected T internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class returnType) throws EdmPrimitiveTypeException { + final Matcher matcher = PATTERN.matcher(value); + if (!matcher.matches()) { + throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)"); + } + + Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + dateTimeValue.clear(); + dateTimeValue.set(Calendar.HOUR_OF_DAY, Byte.parseByte(matcher.group(1))); + dateTimeValue.set(Calendar.MINUTE, Byte.parseByte(matcher.group(2))); + dateTimeValue.set(Calendar.SECOND, matcher.group(3) == null ? 0 : Byte.parseByte(matcher.group(3))); + + if (matcher.group(4) != null) { + if (matcher.group(4).length() == 1 || matcher.group(4).length() > 13) { + throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)"); + } + final String decimals = matcher.group(5); + 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 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 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(8); // Eight characters are enough for "normal" times. + EdmDateTimeOffset.appendTwoDigits(result, dateTimeValue.get(Calendar.HOUR_OF_DAY)); + result.append(':'); + EdmDateTimeOffset.appendTwoDigits(result, dateTimeValue.get(Calendar.MINUTE)); + result.append(':'); + EdmDateTimeOffset.appendTwoDigits(result, dateTimeValue.get(Calendar.SECOND)); + + try { + EdmDateTimeOffset.appendMilliseconds(result, dateTimeValue.get(Calendar.MILLISECOND), precision); + } catch (final IllegalArgumentException e) { + throw new EdmPrimitiveTypeException( + "EdmPrimitiveTypeException.VALUE_FACETS_NOT_MATCHED.addContent(value, facets), e"); + } + + return result.toString(); + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/SingletonPrimitiveType.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/SingletonPrimitiveType.java new file mode 100644 index 000000000..b216b1ee6 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/SingletonPrimitiveType.java @@ -0,0 +1,34 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; + +/** + * Abstract singleton implementation of the EDM primitive-type interface. + */ +abstract class SingletonPrimitiveType extends AbstractPrimitiveType { + + @Override + public boolean equals(final Object obj) { + return this == obj || obj != null && getClass() == obj.getClass(); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } + + @Override + public String getNamespace() { + return EDM_NAMESPACE; + } + + @Override + public String getName() { + return getClass().getSimpleName().substring(3); + } + + @Override + public EdmTypeKind getKind() { + return EdmTypeKind.PRIMITIVE; + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/Uint7.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/Uint7.java new file mode 100644 index 000000000..17e0a3045 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/Uint7.java @@ -0,0 +1,45 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; + +/** + * Implementation of the internal primitive type "unsigned 7-bit integer". + */ +final class Uint7 extends SingletonPrimitiveType { + + private static final Uint7 instance = new Uint7(); + + public static Uint7 getInstance() { + return instance; + } + + @Override + public String getNamespace() { + return SYSTEM_NAMESPACE; + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public Class getDefaultType() { + return Byte.class; + } + + @Override + protected T internalValueOfString(final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class returnType) throws EdmPrimitiveTypeException { + return EdmSByte.getInstance().internalValueOfString(value, isNullable, maxLength, precision, scale, isUnicode, + returnType); + } + + @Override + protected String internalValueToString(final T value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException { + return EdmSByte.getInstance().internalValueToString(value, isNullable, maxLength, precision, scale, isUnicode); + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmActionImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmActionImpl.java new file mode 100644 index 000000000..c9e1786e7 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmActionImpl.java @@ -0,0 +1,14 @@ +package org.apache.olingo.commons.core.edm.provider; + +import org.apache.olingo.commons.api.edm.EdmAction; +import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.Action; + +//TODO: Test +public class EdmActionImpl extends EdmOperationImpl implements EdmAction { + + public EdmActionImpl(final FullQualifiedName name, final Action action) { + super(name, action, EdmTypeKind.ACTION); + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmComplexTypeImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmComplexTypeImpl.java new file mode 100644 index 000000000..269c561f1 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmComplexTypeImpl.java @@ -0,0 +1,19 @@ +package org.apache.olingo.commons.core.edm.provider; + +import org.apache.olingo.commons.api.edm.EdmComplexType; +import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.ComplexType; + +//TODO: Test +public class EdmComplexTypeImpl extends EdmStructuralTypeImpl implements EdmComplexType { + + public EdmComplexTypeImpl(final EdmProviderImpl edm, final FullQualifiedName name, final ComplexType complexType) { + super(edm, name, complexType, EdmTypeKind.COMPLEX); + } + + @Override + public EdmComplexType getBaseType() { + return (EdmComplexType) baseType; + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmElementImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmElementImpl.java new file mode 100644 index 000000000..48c0d782b --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmElementImpl.java @@ -0,0 +1,10 @@ +package org.apache.olingo.commons.core.edm.provider; + +import org.apache.olingo.commons.api.edm.EdmElement; + +public abstract class EdmElementImpl extends EdmNamedImpl implements EdmElement { + + public EdmElementImpl(final String name) { + super(name); + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmEntityContainerImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmEntityContainerImpl.java new file mode 100644 index 000000000..1fe38a142 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmEntityContainerImpl.java @@ -0,0 +1,45 @@ +package org.apache.olingo.commons.core.edm.provider; + +import org.apache.olingo.commons.api.edm.EdmActionImport; +import org.apache.olingo.commons.api.edm.EdmEntityContainer; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmFunctionImport; +import org.apache.olingo.commons.api.edm.EdmSingleton; +import org.apache.olingo.commons.api.edm.helper.EntityContainerInfo; + +//TODO: Test +public class EdmEntityContainerImpl extends EdmNamedImpl implements EdmEntityContainer { + + private EntityContainerInfo entityContainerInfo; + + public EdmEntityContainerImpl(final EntityContainerInfo entityContainerInfo) { + super(entityContainerInfo.getContainerName().getName()); + this.entityContainerInfo = entityContainerInfo; + } + + @Override + public String getNamespace() { + return entityContainerInfo.getContainerName().getNamespace(); + } + + @Override + public EdmSingleton getSingleton(final String name) { + return null; + } + + @Override + public EdmEntitySet getEntitySet(final String name) { + return null; + } + + @Override + public EdmActionImport getActionImport(final String name) { + return null; + } + + @Override + public EdmFunctionImport getFunctionImport(final String name) { + return null; + } + +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmEntityTypeImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmEntityTypeImpl.java new file mode 100644 index 000000000..9d14cad69 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmEntityTypeImpl.java @@ -0,0 +1,43 @@ +package org.apache.olingo.commons.core.edm.provider; + +import java.util.List; + +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef; +import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.EntityType; + +//TODO: Test +public class EdmEntityTypeImpl extends EdmStructuralTypeImpl implements EdmEntityType { + + public EdmEntityTypeImpl(final EdmProviderImpl edm, final FullQualifiedName name, final EntityType entityType) { + super(edm, name, entityType, EdmTypeKind.ENTITY); + } + + @Override + public boolean hasStream() { + return false; + } + + @Override + public EdmEntityType getBaseType() { + return null; + } + + @Override + public List getKeyPredicateNames() { + return null; + } + + @Override + public List getKeyPropertYRefs() { + return null; + } + + @Override + public EdmKeyPropertyRef getKeyPropertyRef(final String keyPredicateName) { + return null; + } + +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmEnumImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmEnumImpl.java new file mode 100644 index 000000000..bd2b613f2 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmEnumImpl.java @@ -0,0 +1,89 @@ +package org.apache.olingo.commons.core.edm.provider; + +import java.util.List; + +import org.apache.olingo.commons.api.edm.EdmEnumType; +import org.apache.olingo.commons.api.edm.EdmMember; +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; +import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.EnumType; + +//TODO: Test +public class EdmEnumImpl extends EdmNamedImpl implements EdmEnumType { + + private final FullQualifiedName enumName; + + public EdmEnumImpl(final FullQualifiedName enumName, final EnumType enumType) { + super(enumName.getName()); + this.enumName = enumName; + } + + @Override + public boolean isCompatible(final EdmPrimitiveType primitiveType) { + return false; + } + + @Override + public Class getDefaultType() { + return null; + } + + @Override + public boolean validate(final String value, final Boolean isNullable, final Integer maxLength, + final Integer precision, final Integer scale, + final Boolean isUnicode) { + return false; + } + + @Override + public T valueOfString(final String value, final Boolean isNullable, final Integer maxLength, + final Integer precision, final Integer scale, + final Boolean isUnicode, final Class returnType) throws EdmPrimitiveTypeException { + return null; + } + + @Override + public String valueToString(final Object 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; + } + + @Override + public String getNamespace() { + return enumName.getNamespace(); + } + + @Override + public EdmTypeKind getKind() { + return null; + } + + @Override + public EdmMember getMember(final String name) { + return null; + } + + @Override + public List getMemberNames() { + return null; + } + + @Override + public EdmPrimitiveType getUnderlyingType() { + return null; + } + +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmFunctionImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmFunctionImpl.java new file mode 100644 index 000000000..6d033fbb9 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmFunctionImpl.java @@ -0,0 +1,23 @@ +package org.apache.olingo.commons.core.edm.provider; + +import org.apache.olingo.commons.api.edm.EdmFunction; +import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.Function; + +//TODO: Test +public class EdmFunctionImpl extends EdmOperationImpl implements EdmFunction { + + private Function function; + + public EdmFunctionImpl(final FullQualifiedName name, final Function function) { + super(name, function, EdmTypeKind.FUNCTION); + this.function = function; + } + + @Override + public boolean isComposable() { + return function.isComposable(); + } + +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmNamedImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmNamedImpl.java new file mode 100644 index 000000000..a1b0ebd16 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmNamedImpl.java @@ -0,0 +1,19 @@ +package org.apache.olingo.commons.core.edm.provider; + +import org.apache.olingo.commons.api.edm.EdmNamed; + +public abstract class EdmNamedImpl implements EdmNamed { + + private String name; + + // TODO: ValidateName? + public EdmNamedImpl(final String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmNavigationPropertyImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmNavigationPropertyImpl.java new file mode 100644 index 000000000..91217c4c9 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmNavigationPropertyImpl.java @@ -0,0 +1,29 @@ +package org.apache.olingo.commons.core.edm.provider; + +import org.apache.olingo.commons.api.edm.EdmNavigationProperty; +import org.apache.olingo.commons.api.edm.EdmType; +import org.apache.olingo.commons.api.edm.provider.NavigationProperty; + +//TODO: Test +public class EdmNavigationPropertyImpl extends EdmElementImpl implements EdmNavigationProperty { + + public EdmNavigationPropertyImpl(final NavigationProperty navigationProperty) { + super(navigationProperty.getName()); + } + + @Override + public EdmType getType() { + return null; + } + + @Override + public boolean isCollection() { + return false; + } + + @Override + public Boolean isNullable() { + return null; + } + +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmOperationImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmOperationImpl.java new file mode 100644 index 000000000..46d507cd5 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmOperationImpl.java @@ -0,0 +1,45 @@ +package org.apache.olingo.commons.core.edm.provider; + +import java.util.List; + +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmOperation; +import org.apache.olingo.commons.api.edm.EdmParameter; +import org.apache.olingo.commons.api.edm.EdmReturnType; +import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.Operation; + +//TODO: Test +public class EdmOperationImpl extends EdmTypeImpl implements EdmOperation { + + public EdmOperationImpl(final FullQualifiedName name, final Operation operation, final EdmTypeKind kind) { + super(name, kind); + } + + @Override + public EdmParameter getParameter(final String name) { + return null; + } + + @Override + public List getParameterNames() { + return null; + } + + @Override + public EdmEntitySet getReturnedEntitySet(final EdmEntitySet bindingParameterEntitySet, final String path) { + return null; + } + + @Override + public EdmReturnType getReturnType() { + return null; + } + + @Override + public boolean isBound() { + return false; + } + +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmPropertyImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmPropertyImpl.java new file mode 100644 index 000000000..c605e0107 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmPropertyImpl.java @@ -0,0 +1,69 @@ +package org.apache.olingo.commons.core.edm.provider; + +import org.apache.olingo.commons.api.edm.EdmMapping; +import org.apache.olingo.commons.api.edm.EdmProperty; +import org.apache.olingo.commons.api.edm.EdmType; +import org.apache.olingo.commons.api.edm.provider.Property; + +public class EdmPropertyImpl extends EdmElementImpl implements EdmProperty { + + public EdmPropertyImpl(final Property property) { + super(property.getName()); + } + + @Override + public EdmType getType() { + return null; + } + + @Override + public boolean isCollection() { + return false; + } + + @Override + public EdmMapping getMapping() { + return null; + } + + @Override + public String getMimeType() { + return null; + } + + @Override + public boolean isPrimitive() { + return false; + } + + @Override + public Boolean isNullable() { + return null; + } + + @Override + public Integer getMaxLength() { + return null; + } + + @Override + public Integer getPrecision() { + return null; + } + + @Override + public Integer getScale() { + return null; + } + + @Override + public Boolean isUnicode() { + return null; + } + + @Override + public String getDefaultValue() { + return null; + } + +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmProviderImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmProviderImpl.java new file mode 100644 index 000000000..104e698a3 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmProviderImpl.java @@ -0,0 +1,135 @@ +package org.apache.olingo.commons.core.edm.provider; + +import java.util.List; + +import org.apache.olingo.commons.api.edm.EdmAction; +import org.apache.olingo.commons.api.edm.EdmComplexType; +import org.apache.olingo.commons.api.edm.EdmEntityContainer; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmEnumType; +import org.apache.olingo.commons.api.edm.EdmException; +import org.apache.olingo.commons.api.edm.EdmFunction; +import org.apache.olingo.commons.api.edm.EdmServiceMetadata; +import org.apache.olingo.commons.api.edm.EdmTypeDefinition; +import org.apache.olingo.commons.api.edm.helper.EntityContainerInfo; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.Action; +import org.apache.olingo.commons.api.edm.provider.ComplexType; +import org.apache.olingo.commons.api.edm.provider.EdmProvider; +import org.apache.olingo.commons.api.edm.provider.EntityType; +import org.apache.olingo.commons.api.edm.provider.EnumType; +import org.apache.olingo.commons.api.edm.provider.Function; +import org.apache.olingo.commons.api.edm.provider.TypeDefinition; +import org.apache.olingo.commons.api.exception.ODataException; +import org.apache.olingo.commons.core.edm.EdmImpl; + +public class EdmProviderImpl extends EdmImpl { + + private final EdmProvider provider; + + public EdmProviderImpl(final EdmProvider provider) { + this.provider = provider; + + } + + @Override + public EdmEntityContainer createEntityContainer(final FullQualifiedName containerName) { + try { + EntityContainerInfo entityContainerInfo = provider.getEntityContainerInfo(containerName); + if (entityContainerInfo != null) { + return new EdmEntityContainerImpl(entityContainerInfo); + } + return null; + } catch (ODataException e) { + throw new EdmException(e); + } + } + + @Override + public EdmEnumType createEnumType(final FullQualifiedName enumName) { + try { + EnumType enumType = provider.getEnumType(enumName); + if (enumType != null) { + return new EdmEnumImpl(enumName, enumType); + } + return null; + } catch (ODataException e) { + throw new EdmException(e); + } + } + + @Override + public EdmTypeDefinition createTypeDefinition(final FullQualifiedName typeDefinitionName) { + try { + TypeDefinition typeDefinition = provider.getTypeDefinition(typeDefinitionName); + if (typeDefinition != null) { + return new EdmTypeDefinitionImpl(typeDefinitionName, typeDefinition); + } + return null; + } catch (ODataException e) { + throw new EdmException(e); + } + } + + @Override + public EdmEntityType createEntityType(final FullQualifiedName entityTypeName) { + try { + EntityType entityType = provider.getEntityType(entityTypeName); + if (entityType != null) { + return new EdmEntityTypeImpl(this, entityTypeName, entityType); + } + return null; + } catch (ODataException e) { + throw new EdmException(e); + } + } + + @Override + public EdmComplexType createComplexType(final FullQualifiedName complexTypeName) { + try { + ComplexType complexType = provider.getComplexType(complexTypeName); + if (complexType != null) { + return new EdmComplexTypeImpl(this, complexTypeName, complexType); + } + return null; + } catch (ODataException e) { + throw new EdmException(e); + } + } + + @Override + public EdmAction createAction(final FullQualifiedName actionName, final FullQualifiedName bindingPatameterTypeName, + final Boolean isBindingParameterCollection) { + try { + Action action = provider.getAction(actionName, bindingPatameterTypeName, isBindingParameterCollection); + if (action != null) { + return new EdmActionImpl(actionName, action); + } + return null; + } catch (ODataException e) { + throw new EdmException(e); + } + } + + @Override + public EdmFunction createFunction(final FullQualifiedName functionName, + final FullQualifiedName bindingPatameterTypeName, + final Boolean isBindingParameterCollection, final List parameterNames) { + try { + Function function = provider.getFunction(functionName, bindingPatameterTypeName, isBindingParameterCollection, + parameterNames); + if (function != null) { + return new EdmFunctionImpl(functionName, function); + } + return null; + } catch (ODataException e) { + throw new EdmException(e); + } + } + + @Override + public EdmServiceMetadata createServiceMetadata() { + return new EdmServiceMetadataImpl(); + } + +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmServiceMetadataImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmServiceMetadataImpl.java new file mode 100644 index 000000000..ae008690a --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmServiceMetadataImpl.java @@ -0,0 +1,39 @@ +package org.apache.olingo.commons.core.edm.provider; + +import java.io.InputStream; +import java.util.List; + +import org.apache.olingo.commons.api.edm.EdmServiceMetadata; +import org.apache.olingo.commons.api.edm.helper.EdmEntitySetInfo; +import org.apache.olingo.commons.api.edm.helper.EdmFunctionImportInfo; +import org.apache.olingo.commons.api.edm.helper.EdmSingletonInfo; + +//TODO: Test +public class EdmServiceMetadataImpl implements EdmServiceMetadata { + + @Override + public InputStream getMetadata() { + return null; + } + + @Override + public String getDataServiceVersion() { + return null; + } + + @Override + public List getEntitySetInfos() { + return null; + } + + @Override + public List getSingletonInfos() { + return null; + } + + @Override + public List getFunctionImportInfos() { + return null; + } + +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmStructuralTypeImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmStructuralTypeImpl.java new file mode 100644 index 000000000..d2ea895e1 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmStructuralTypeImpl.java @@ -0,0 +1,111 @@ +package org.apache.olingo.commons.core.edm.provider; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.EdmComplexType; +import org.apache.olingo.commons.api.edm.EdmElement; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmException; +import org.apache.olingo.commons.api.edm.EdmStructuralType; +import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.NavigationProperty; +import org.apache.olingo.commons.api.edm.provider.Property; +import org.apache.olingo.commons.api.edm.provider.StructuralType; + +public abstract class EdmStructuralTypeImpl extends EdmTypeImpl implements EdmStructuralType { + + private final Map properties = new HashMap(); + private final ArrayList navigationPropertyNames = new ArrayList(); + private final ArrayList propertyNames = new ArrayList(); + protected final EdmStructuralType baseType; + + public EdmStructuralTypeImpl(final EdmProviderImpl edm, final FullQualifiedName name, + final StructuralType structuralType, + final EdmTypeKind kind) { + super(name, kind); + baseType = buildBaseType(edm, structuralType.getBaseType(), kind); + buildProperties(structuralType.getProperties()); + buildNavigationProperties(structuralType.getNavigationProperties()); + } + + private EdmStructuralType buildBaseType(final Edm edm, final FullQualifiedName baseType, final EdmTypeKind kind) { + if (baseType != null) { + if (EdmTypeKind.COMPLEX.equals(kind)) { + EdmComplexType complexType = edm.getComplexType(baseType); + if (complexType != null) { + propertyNames.addAll(complexType.getPropertyNames()); + navigationPropertyNames.addAll(complexType.getNavigationPropertyNames()); + } else { + throw new EdmException("Missing ComplexType for FQN: " + baseType); + } + return complexType; + } else if (EdmTypeKind.ENTITY.equals(kind)) { + EdmEntityType entityType = edm.getEntityType(baseType); + if (entityType != null) { + propertyNames.addAll(entityType.getPropertyNames()); + navigationPropertyNames.addAll(entityType.getNavigationPropertyNames()); + } else { + throw new EdmException("Missing EntityType for FQN: " + baseType); + } + return entityType; + } else { + throw new EdmException("Unkonwn Type Kind"); + } + } else { + return null; + } + + } + + private void buildNavigationProperties(final List providerNavigationProperties) { + if (providerNavigationProperties != null) { + for (NavigationProperty navigationProperty : providerNavigationProperties) { + navigationPropertyNames.add(navigationProperty.getName()); + properties.put(navigationProperty.getName(), new EdmNavigationPropertyImpl(navigationProperty)); + } + } + + } + + private void buildProperties(final List providerProperties) { + if (providerProperties != null) { + for (Property property : providerProperties) { + propertyNames.add(property.getName()); + properties.put(property.getName(), new EdmPropertyImpl(property)); + } + } + + } + + @Override + public EdmElement getProperty(final String name) { + EdmElement property = null; + if (baseType != null) { + property = baseType.getProperty(name); + } + if (property == null) { + property = properties.get(name); + } + return property; + } + + @Override + public List getPropertyNames() { + return propertyNames; + } + + @Override + public List getNavigationPropertyNames() { + return navigationPropertyNames; + } + + @Override + public EdmStructuralType getBaseType() { + return baseType; + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmTypeDefinitionImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmTypeDefinitionImpl.java new file mode 100644 index 000000000..a3c1758c9 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmTypeDefinitionImpl.java @@ -0,0 +1,95 @@ +package org.apache.olingo.commons.core.edm.provider; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; +import org.apache.olingo.commons.api.edm.EdmTypeDefinition; +import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.TypeDefinition; + +//TODO: Test +public class EdmTypeDefinitionImpl extends EdmNamedImpl implements EdmTypeDefinition { + + private final FullQualifiedName typeDefinitionName; + + public EdmTypeDefinitionImpl(final FullQualifiedName typeDefinitionName, final TypeDefinition typeDefinition) { + super(typeDefinitionName.getName()); + this.typeDefinitionName = typeDefinitionName; + } + + @Override + public boolean isCompatible(final EdmPrimitiveType primitiveType) { + return false; + } + + @Override + public Class getDefaultType() { + return null; + } + + @Override + public boolean validate(final String value, final Boolean isNullable, final Integer maxLength, + final Integer precision, final Integer scale, + final Boolean isUnicode) { + return false; + } + + @Override + public T valueOfString(final String value, final Boolean isNullable, final Integer maxLength, + final Integer precision, final Integer scale, + final Boolean isUnicode, final Class returnType) throws EdmPrimitiveTypeException { + return null; + } + + @Override + public String valueToString(final Object 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; + } + + @Override + public String getNamespace() { + return typeDefinitionName.getNamespace(); + } + + @Override + public EdmTypeKind getKind() { + return null; + } + + @Override + public EdmPrimitiveType getUnderlyingType() { + return null; + } + + @Override + public Integer getMaxLength() { + return null; + } + + @Override + public Integer getPrecision() { + return null; + } + + @Override + public Integer getScale() { + return null; + } + + @Override + public Boolean isUnicode() { + return null; + } +} diff --git a/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmTypeImpl.java b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmTypeImpl.java new file mode 100644 index 000000000..a313746e1 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/main/java/org/apache/olingo/commons/core/edm/provider/EdmTypeImpl.java @@ -0,0 +1,28 @@ +package org.apache.olingo.commons.core.edm.provider; + +import org.apache.olingo.commons.api.edm.EdmType; +import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; + +public abstract class EdmTypeImpl extends EdmNamedImpl implements EdmType { + + private final EdmTypeKind kind; + private final String namespace; + + public EdmTypeImpl(final FullQualifiedName name, final EdmTypeKind kind) { + super(name.getName()); + namespace = name.getNamespace(); + this.kind = kind; + } + + @Override + public String getNamespace() { + return namespace; + } + + @Override + public EdmTypeKind getKind() { + return kind; + } + +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/ActionMapKeyTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/ActionMapKeyTest.java new file mode 100644 index 000000000..53f47db84 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/ActionMapKeyTest.java @@ -0,0 +1,66 @@ +package org.apache.olingo.commons.core.edm; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; + +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.junit.Test; + +public class ActionMapKeyTest { + + private final FullQualifiedName fqn = new FullQualifiedName("namespace", "name"); + private final FullQualifiedName fqnType = new FullQualifiedName("namespace2", "name2"); + + @Test + public void testEqualsMethod() { + ActionMapKey key1 = new ActionMapKey(fqn, null, null); + ActionMapKey someKey = new ActionMapKey(fqn, null, null); + assertEquals(key1, someKey); + + key1 = new ActionMapKey(fqn, null, new Boolean(true)); + someKey = new ActionMapKey(fqn, null, true); + assertEquals(key1, someKey); + + key1 = new ActionMapKey(fqn, fqnType, false); + someKey = new ActionMapKey(fqn, fqnType, false); + assertEquals(key1, someKey); + + key1 = new ActionMapKey(fqn, fqnType, null); + someKey = new ActionMapKey(fqn, fqnType, null); + assertEquals(key1, someKey); + + key1 = new ActionMapKey(fqn, fqnType, true); + someKey = new ActionMapKey(fqn, fqnType, null); + assertNotSame(key1, someKey); + + key1 = new ActionMapKey(fqn, fqnType, true); + someKey = new ActionMapKey(fqn, fqnType, false); + assertNotSame(key1, someKey); + + key1 = new ActionMapKey(fqn, null, true); + someKey = new ActionMapKey(fqn, fqnType, false); + assertNotSame(key1, someKey); + + key1 = new ActionMapKey(fqn, null, true); + someKey = new ActionMapKey(fqn, null, false); + assertNotSame(key1, someKey); + } + + @Test + public void testHashMethod() { + ActionMapKey key1 = new ActionMapKey(fqn, null, null); + ActionMapKey someKey = new ActionMapKey(fqn, null, null); + assertEquals(key1.hashCode(), someKey.hashCode()); + + key1 = new ActionMapKey(fqn, null, new Boolean(true)); + someKey = new ActionMapKey(fqn, null, true); + assertEquals(key1.hashCode(), someKey.hashCode()); + + someKey = new ActionMapKey(fqn, fqnType, true); + assertNotSame(key1.hashCode(), someKey.hashCode()); + + someKey = new ActionMapKey(fqn, fqnType, false); + assertNotSame(key1.hashCode(), someKey.hashCode()); + } + +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/EdmImplCachingTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/EdmImplCachingTest.java new file mode 100644 index 000000000..66e35dc8e --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/EdmImplCachingTest.java @@ -0,0 +1,334 @@ +package org.apache.olingo.commons.core.edm; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.EdmAction; +import org.apache.olingo.commons.api.edm.EdmComplexType; +import org.apache.olingo.commons.api.edm.EdmEntityContainer; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmEnumType; +import org.apache.olingo.commons.api.edm.EdmFunction; +import org.apache.olingo.commons.api.edm.EdmServiceMetadata; +import org.apache.olingo.commons.api.edm.EdmTypeDefinition; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.junit.Before; +import org.junit.Test; + +public class EdmImplCachingTest { + + private final FullQualifiedName NAME1 = new FullQualifiedName("testNamespace1", "testName1"); + private final FullQualifiedName NAME2 = new FullQualifiedName("testNamespace2", "testName2"); + private Edm edm; + + @Test + public void cacheEntityContainer() { + EdmEntityContainer entityContainer = edm.getEntityContainer(null); + assertNotNull(entityContainer); + + EdmEntityContainer cachedContainer = edm.getEntityContainer(NAME1); + assertNotNull(entityContainer); + + assertTrue(entityContainer == cachedContainer); + assertEquals(entityContainer, cachedContainer); + + cachedContainer = edm.getEntityContainer(NAME1); + assertNotNull(cachedContainer); + + assertTrue(entityContainer == cachedContainer); + assertEquals(entityContainer, cachedContainer); + + EdmEntityContainer entityContainer2 = edm.getEntityContainer(NAME2); + assertNotNull(entityContainer2); + + assertNotSame(entityContainer, entityContainer2); + } + + @Test + public void cacheEnumType() { + EdmEnumType enumType = edm.getEnumType(NAME1); + assertNotNull(enumType); + + EdmEnumType cachedType = edm.getEnumType(NAME1); + assertNotNull(cachedType); + + assertTrue(enumType == cachedType); + assertEquals(enumType, cachedType); + + EdmEnumType enumType2 = edm.getEnumType(NAME2); + assertNotNull(enumType2); + + assertNotSame(enumType, enumType2); + } + + @Test + public void cacheTypeDefinition() { + EdmTypeDefinition typeDefinition = edm.getTypeDefinition(NAME1); + assertNotNull(typeDefinition); + + EdmTypeDefinition cachedDefinition = edm.getTypeDefinition(NAME1); + assertNotNull(cachedDefinition); + + assertTrue(typeDefinition == cachedDefinition); + assertEquals(typeDefinition, cachedDefinition); + + EdmTypeDefinition typeDefinition2 = edm.getTypeDefinition(NAME2); + assertNotNull(typeDefinition2); + + assertNotSame(typeDefinition, typeDefinition2); + } + + @Test + public void cacheEntityType() { + EdmEntityType entityType = edm.getEntityType(NAME1); + assertNotNull(entityType); + + EdmEntityType cachedType = edm.getEntityType(NAME1); + assertNotNull(cachedType); + + assertTrue(entityType == cachedType); + assertEquals(entityType, cachedType); + + EdmEntityType entityType2 = edm.getEntityType(NAME2); + assertNotNull(entityType2); + + assertNotSame(entityType, entityType2); + } + + @Test + public void cacheComplexType() { + EdmComplexType complexType = edm.getComplexType(NAME1); + assertNotNull(complexType); + + EdmComplexType cachedType = edm.getComplexType(NAME1); + assertNotNull(cachedType); + + assertTrue(complexType == cachedType); + assertEquals(complexType, cachedType); + + EdmComplexType complexType2 = edm.getComplexType(NAME2); + assertNotNull(complexType2); + + assertNotSame(complexType, complexType2); + } + + @Test + public void cacheActionSimple() { + EdmAction action = edm.getAction(NAME1, null, null); + assertNotNull(action); + + EdmAction cachedAction = edm.getAction(NAME1, null, null); + assertNotNull(cachedAction); + + assertTrue(action == cachedAction); + assertEquals(action, cachedAction); + + EdmAction action2 = edm.getAction(NAME2, null, false); + assertNotNull(action2); + assertNotSame(action, action2); + } + + @Test + public void cacheActionComlex() { + EdmAction action = edm.getAction(NAME1, null, null); + assertNotNull(action); + + EdmAction cachedAction = edm.getAction(NAME1, null, true); + assertNull(cachedAction); + + cachedAction = edm.getAction(NAME1, null, false); + assertNull(cachedAction); + + cachedAction = edm.getAction(NAME1, NAME2, null); + assertNull(cachedAction); + + cachedAction = edm.getAction(NAME1, NAME2, true); + assertNull(cachedAction); + + cachedAction = edm.getAction(NAME1, NAME2, false); + assertNull(cachedAction); + + cachedAction = edm.getAction(NAME1, NAME1, null); + assertNull(cachedAction); + + cachedAction = edm.getAction(NAME1, NAME1, true); + assertNull(cachedAction); + + cachedAction = edm.getAction(NAME1, NAME1, false); + assertNull(cachedAction); + } + + @Test + public void cacheFunctionSimple() { + EdmFunction function = edm.getFunction(NAME1, null, null, null); + assertNotNull(function); + + EdmFunction cachedfunction = edm.getFunction(NAME1, null, null, null); + assertNotNull(cachedfunction); + + assertTrue(function == cachedfunction); + assertEquals(function, cachedfunction); + + EdmFunction function2 = edm.getFunction(NAME2, null, false, null); + assertNotNull(function2); + + assertNotSame(function, function2); + } + + @Test + public void cacheFunctionComplex() { + EdmFunction function = edm.getFunction(NAME1, null, null, null); + assertNotNull(function); + + EdmFunction cachedfunction = edm.getFunction(NAME1, null, false, null); + assertNull(cachedfunction); + + cachedfunction = edm.getFunction(NAME1, null, true, null); + assertNull(cachedfunction); + + cachedfunction = edm.getFunction(NAME1, null, new Boolean(true), null); + assertNull(cachedfunction); + + cachedfunction = edm.getFunction(NAME1, NAME2, null, null); + assertNull(cachedfunction); + + cachedfunction = edm.getFunction(NAME1, NAME2, true, null); + assertNull(cachedfunction); + + cachedfunction = edm.getFunction(NAME1, NAME2, false, null); + assertNull(cachedfunction); + + cachedfunction = edm.getFunction(NAME1, null, null, new ArrayList()); + assertNull(cachedfunction); + } + + @Test + public void cacheFunctionComplexWithListContent() { + + } + + @Test + public void cacheServiceMetadata() { + EdmServiceMetadata serviceMetadata = edm.getServiceMetadata(); + EdmServiceMetadata cachedMetadata = edm.getServiceMetadata(); + + assertTrue(serviceMetadata == cachedMetadata); + assertEquals(serviceMetadata, cachedMetadata); + } + + @Before + public void setup() { + edm = new LocalEdm(); + } + + private class LocalEdm extends EdmImpl { + @Override + public EdmEntityContainer createEntityContainer(final FullQualifiedName fqn) { + if (NAME1.equals(fqn) || fqn == null) { + EdmEntityContainer container = mock(EdmEntityContainer.class); + when(container.getNamespace()).thenReturn(NAME1.getNamespace()); + when(container.getName()).thenReturn(NAME1.getName()); + return container; + } else if (NAME2.equals(fqn)) { + EdmEntityContainer container = mock(EdmEntityContainer.class); + when(container.getNamespace()).thenReturn(fqn.getNamespace()); + when(container.getName()).thenReturn(fqn.getName()); + return container; + } + return null; + } + + @Override + public EdmEnumType createEnumType(final FullQualifiedName fqn) { + if (NAME1.equals(fqn) || NAME2.equals(fqn)) { + EdmEnumType enumType = mock(EdmEnumType.class); + when(enumType.getNamespace()).thenReturn(fqn.getNamespace()); + when(enumType.getName()).thenReturn(fqn.getName()); + return enumType; + } + return null; + } + + @Override + public EdmTypeDefinition createTypeDefinition(final FullQualifiedName fqn) { + if (NAME1.equals(fqn) || NAME2.equals(fqn)) { + EdmTypeDefinition typeDefinition = mock(EdmTypeDefinition.class); + when(typeDefinition.getNamespace()).thenReturn(fqn.getNamespace()); + when(typeDefinition.getName()).thenReturn(fqn.getName()); + return typeDefinition; + } + return null; + } + + @Override + public EdmEntityType createEntityType(final FullQualifiedName fqn) { + if (NAME1.equals(fqn) || NAME2.equals(fqn)) { + EdmEntityType entityType = mock(EdmEntityType.class); + when(entityType.getNamespace()).thenReturn(fqn.getNamespace()); + when(entityType.getName()).thenReturn(fqn.getName()); + return entityType; + } + return null; + } + + @Override + public EdmComplexType createComplexType(final FullQualifiedName fqn) { + if (NAME1.equals(fqn) || NAME2.equals(fqn)) { + EdmComplexType complexType = mock(EdmComplexType.class); + when(complexType.getNamespace()).thenReturn(fqn.getNamespace()); + when(complexType.getName()).thenReturn(fqn.getName()); + return complexType; + } + return null; + } + + @Override + public EdmAction createAction(final FullQualifiedName fqn, final FullQualifiedName bindingParameterTypeName, + final Boolean isBindingParameterCollection) { + if (NAME1.equals(fqn) && bindingParameterTypeName == null && isBindingParameterCollection == null) { + EdmAction action = mock(EdmAction.class); + when(action.getNamespace()).thenReturn(fqn.getNamespace()); + when(action.getName()).thenReturn(fqn.getName()); + return action; + } else if (NAME2.equals(fqn)) { + EdmAction action = mock(EdmAction.class); + when(action.getNamespace()).thenReturn(fqn.getNamespace()); + when(action.getName()).thenReturn(fqn.getName()); + return action; + } + return null; + } + + @Override + public EdmFunction createFunction(final FullQualifiedName fqn, final FullQualifiedName bindingParameterTypeName, + final Boolean isBindingParameterCollection, final List bindingParameterNames) { + if (NAME1.equals(fqn) && bindingParameterTypeName == null && isBindingParameterCollection == null + && bindingParameterNames == null) { + EdmFunction function = mock(EdmFunction.class); + when(function.getNamespace()).thenReturn(fqn.getNamespace()); + when(function.getName()).thenReturn(fqn.getName()); + return function; + } else if (NAME2.equals(fqn)) { + EdmFunction function = mock(EdmFunction.class); + when(function.getNamespace()).thenReturn(fqn.getNamespace()); + when(function.getName()).thenReturn(fqn.getName()); + return function; + } + return null; + } + + @Override + public EdmServiceMetadata createServiceMetadata() { + return mock(EdmServiceMetadata.class); + } + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/EdmImplCallCreateTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/EdmImplCallCreateTest.java new file mode 100644 index 000000000..9aec33210 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/EdmImplCallCreateTest.java @@ -0,0 +1,218 @@ +/******************************************************************************* + * 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.commons.core.edm; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.List; + +import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.EdmAction; +import org.apache.olingo.commons.api.edm.EdmComplexType; +import org.apache.olingo.commons.api.edm.EdmEntityContainer; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmEnumType; +import org.apache.olingo.commons.api.edm.EdmFunction; +import org.apache.olingo.commons.api.edm.EdmServiceMetadata; +import org.apache.olingo.commons.api.edm.EdmTypeDefinition; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.junit.Before; +import org.junit.Test; + +public class EdmImplCallCreateTest { + + private final FullQualifiedName FQN = new FullQualifiedName("testNamespace", "testName"); + private final FullQualifiedName WRONG_FQN = new FullQualifiedName("wrong", "wrong"); + private Edm edm; + + @Test + public void callCreateEntityContainer() { + EdmEntityContainer entityContainer = edm.getEntityContainer(FQN); + assertNotNull(entityContainer); + assertEquals(FQN.getNamespace(), entityContainer.getNamespace()); + assertEquals(FQN.getName(), entityContainer.getName()); + + entityContainer = edm.getEntityContainer(null); + assertNotNull(entityContainer); + assertEquals(FQN.getNamespace(), entityContainer.getNamespace()); + assertEquals(FQN.getName(), entityContainer.getName()); + + assertNull(edm.getEntityContainer(WRONG_FQN)); + } + + @Test + public void callCreateEnumType() { + EdmEnumType enumType = edm.getEnumType(FQN); + assertNotNull(enumType); + assertEquals(FQN.getNamespace(), enumType.getNamespace()); + assertEquals(FQN.getName(), enumType.getName()); + + assertNull(edm.getEnumType(WRONG_FQN)); + } + + @Test + public void callCreateTypeDefinition() { + EdmTypeDefinition typeDefinition = edm.getTypeDefinition(FQN); + assertNotNull(typeDefinition); + assertEquals(FQN.getNamespace(), typeDefinition.getNamespace()); + assertEquals(FQN.getName(), typeDefinition.getName()); + + assertNull(edm.getTypeDefinition(WRONG_FQN)); + } + + @Test + public void callCreateEntityType() { + EdmEntityType entityType = edm.getEntityType(FQN); + assertNotNull(entityType); + assertEquals(FQN.getNamespace(), entityType.getNamespace()); + assertEquals(FQN.getName(), entityType.getName()); + + assertNull(edm.getEntityType(WRONG_FQN)); + } + + @Test + public void callCreateComplexType() { + EdmComplexType complexType = edm.getComplexType(FQN); + assertNotNull(complexType); + assertEquals(FQN.getNamespace(), complexType.getNamespace()); + assertEquals(FQN.getName(), complexType.getName()); + + assertNull(edm.getComplexType(WRONG_FQN)); + } + + @Test + public void callCreateAction() { + EdmAction action = edm.getAction(FQN, null, null); + assertNotNull(action); + assertEquals(FQN.getNamespace(), action.getNamespace()); + assertEquals(FQN.getName(), action.getName()); + + assertNull(edm.getAction(WRONG_FQN, null, null)); + } + + @Test + public void callCreateFunction() { + EdmFunction function = edm.getFunction(FQN, null, null, null); + assertNotNull(function); + assertEquals(FQN.getNamespace(), function.getNamespace()); + assertEquals(FQN.getName(), function.getName()); + + assertNull(edm.getFunction(WRONG_FQN, null, null, null)); + } + + @Test + public void callCreateServiceMetadata() { + assertNotNull(edm.getServiceMetadata()); + } + + @Before + public void setup() { + edm = new LocalEdm(); + } + + private class LocalEdm extends EdmImpl { + @Override + public EdmEntityContainer createEntityContainer(final FullQualifiedName fqn) { + if (fqn == null || FQN.getNamespace().equals(fqn.getNamespace()) && FQN.getName().equals(fqn.getName())) { + EdmEntityContainer container = mock(EdmEntityContainer.class); + when(container.getNamespace()).thenReturn(FQN.getNamespace()); + when(container.getName()).thenReturn(FQN.getName()); + return container; + } + return null; + } + + @Override + public EdmEnumType createEnumType(final FullQualifiedName fqn) { + if (FQN.getNamespace().equals(fqn.getNamespace()) && FQN.getName().equals(fqn.getName())) { + EdmEnumType enumType = mock(EdmEnumType.class); + when(enumType.getNamespace()).thenReturn(fqn.getNamespace()); + when(enumType.getName()).thenReturn(fqn.getName()); + return enumType; + } + return null; + } + + @Override + public EdmTypeDefinition createTypeDefinition(final FullQualifiedName fqn) { + if (FQN.getNamespace().equals(fqn.getNamespace()) && FQN.getName().equals(fqn.getName())) { + EdmTypeDefinition typeDefinition = mock(EdmTypeDefinition.class); + when(typeDefinition.getNamespace()).thenReturn(fqn.getNamespace()); + when(typeDefinition.getName()).thenReturn(fqn.getName()); + return typeDefinition; + } + return null; + } + + @Override + public EdmEntityType createEntityType(final FullQualifiedName fqn) { + if (FQN.getNamespace().equals(fqn.getNamespace()) && FQN.getName().equals(fqn.getName())) { + EdmEntityType entityType = mock(EdmEntityType.class); + when(entityType.getNamespace()).thenReturn(fqn.getNamespace()); + when(entityType.getName()).thenReturn(fqn.getName()); + return entityType; + } + return null; + } + + @Override + public EdmComplexType createComplexType(final FullQualifiedName fqn) { + if (FQN.getNamespace().equals(fqn.getNamespace()) && FQN.getName().equals(fqn.getName())) { + EdmComplexType complexType = mock(EdmComplexType.class); + when(complexType.getNamespace()).thenReturn(fqn.getNamespace()); + when(complexType.getName()).thenReturn(fqn.getName()); + return complexType; + } + return null; + } + + @Override + public EdmAction createAction(final FullQualifiedName fqn, final FullQualifiedName bindingParameterTypeName, + final Boolean isBindingParameterCollection) { + if (FQN.getNamespace().equals(fqn.getNamespace()) && FQN.getName().equals(fqn.getName())) { + EdmAction action = mock(EdmAction.class); + when(action.getNamespace()).thenReturn(fqn.getNamespace()); + when(action.getName()).thenReturn(fqn.getName()); + return action; + } + return null; + } + + @Override + public EdmFunction createFunction(final FullQualifiedName fqn, final FullQualifiedName bindingParameterTypeName, + final Boolean isBindingParameterCollection, final List bindingParameterNames) { + if (FQN.getNamespace().equals(fqn.getNamespace()) && FQN.getName().equals(fqn.getName())) { + EdmFunction function = mock(EdmFunction.class); + when(function.getNamespace()).thenReturn(fqn.getNamespace()); + when(function.getName()).thenReturn(fqn.getName()); + return function; + } + return null; + } + + @Override + public EdmServiceMetadata createServiceMetadata() { + return mock(EdmServiceMetadata.class); + } + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/FunctionMapKeyTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/FunctionMapKeyTest.java new file mode 100644 index 000000000..80102653e --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/FunctionMapKeyTest.java @@ -0,0 +1,212 @@ +package org.apache.olingo.commons.core.edm; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.junit.Test; + +public class FunctionMapKeyTest { + + private final FullQualifiedName fqn = new FullQualifiedName("namespace", "name"); + private final FullQualifiedName fqnType = new FullQualifiedName("namespace2", "name2"); + + @Test + public void testEqualsPositive() { + FunctionMapKey key = new FunctionMapKey(fqn, null, null, null); + FunctionMapKey someKey = new FunctionMapKey(fqn, null, null, null); + assertEquals(key, someKey); + + key = new FunctionMapKey(fqn, null, true, null); + someKey = new FunctionMapKey(fqn, null, true, null); + assertEquals(key, someKey); + + key = new FunctionMapKey(fqn, fqnType, true, null); + someKey = new FunctionMapKey(fqn, fqnType, true, null); + assertEquals(key, someKey); + + key = new FunctionMapKey(fqn, fqnType, false, null); + someKey = new FunctionMapKey(fqn, fqnType, false, null); + assertEquals(key, someKey); + + key = new FunctionMapKey(fqn, fqnType, false, new ArrayList()); + someKey = new FunctionMapKey(fqn, fqnType, false, new ArrayList()); + assertEquals(key, someKey); + + List keyList = new ArrayList(); + keyList.add("Employee"); + List someKeyList = new ArrayList(); + someKeyList.add("Employee"); + key = new FunctionMapKey(fqn, fqnType, false, keyList); + someKey = new FunctionMapKey(fqn, fqnType, false, someKeyList); + assertEquals(key, someKey); + + key = new FunctionMapKey(fqn, null, null, new ArrayList()); + someKey = new FunctionMapKey(fqn, null, null, new ArrayList()); + assertEquals(key, someKey); + + keyList = new ArrayList(); + keyList.add("Employee"); + someKeyList = new ArrayList(); + someKeyList.add("Employee"); + key = new FunctionMapKey(fqn, null, null, keyList); + someKey = new FunctionMapKey(fqn, null, null, someKeyList); + assertEquals(key, someKey); + } + + @Test + public void testEqualsNegative() { + FunctionMapKey key = new FunctionMapKey(fqn, null, null, null); + FunctionMapKey someKey = new FunctionMapKey(fqn, null, true, null); + assertNotSame(key, someKey); + + key = new FunctionMapKey(fqn, null, true, null); + someKey = new FunctionMapKey(fqn, null, false, null); + assertNotSame(key, someKey); + + key = new FunctionMapKey(fqn, fqnType, true, null); + someKey = new FunctionMapKey(fqn, null, true, null); + assertNotSame(key, someKey); + + key = new FunctionMapKey(fqn, null, false, null); + someKey = new FunctionMapKey(fqn, fqnType, true, null); + assertNotSame(key, someKey); + + key = new FunctionMapKey(fqn, fqnType, false, null); + someKey = new FunctionMapKey(fqn, fqnType, false, new ArrayList()); + assertNotSame(key, someKey); + + List keyList = new ArrayList(); + keyList.add("Employee"); + List someKeyList = new ArrayList(); + someKeyList.add("Employee2"); + key = new FunctionMapKey(fqn, fqnType, false, keyList); + someKey = new FunctionMapKey(fqn, fqnType, false, someKeyList); + assertNotSame(key, someKey); + + key = new FunctionMapKey(fqn, null, null, new ArrayList()); + someKey = new FunctionMapKey(fqn, null, null, new ArrayList()); + assertNotSame(key, someKey); + + keyList = new ArrayList(); + keyList.add("Employee"); + someKeyList = new ArrayList(); + someKeyList.add("Employee2"); + key = new FunctionMapKey(fqn, null, null, keyList); + someKey = new FunctionMapKey(fqn, null, null, someKeyList); + assertNotSame(key, someKey); + + key = new FunctionMapKey(fqn, null, null, new ArrayList()); + someKey = new FunctionMapKey(fqn, null, null, null); + assertNotSame(key, someKey); + + keyList = new ArrayList(); + keyList.add("Employee"); + someKeyList = new ArrayList(); + key = new FunctionMapKey(fqn, null, null, keyList); + someKey = new FunctionMapKey(fqn, null, null, someKeyList); + assertNotSame(key, someKey); + + keyList = new ArrayList(); + keyList.add("Employee"); + someKeyList = new ArrayList(); + someKeyList.add("EmpLoYeE"); + key = new FunctionMapKey(fqn, null, null, keyList); + someKey = new FunctionMapKey(fqn, null, null, someKeyList); + assertNotSame(key, someKey); + } + + @Test + public void testHashCodePositive() { + FunctionMapKey key = new FunctionMapKey(fqn, null, null, null); + FunctionMapKey someKey = new FunctionMapKey(fqn, null, null, null); + assertEquals(key.hashCode(), someKey.hashCode()); + + key = new FunctionMapKey(fqn, null, true, null); + someKey = new FunctionMapKey(fqn, null, true, null); + assertEquals(key.hashCode(), someKey.hashCode()); + + key = new FunctionMapKey(fqn, fqnType, true, null); + someKey = new FunctionMapKey(fqn, fqnType, true, null); + assertEquals(key.hashCode(), someKey.hashCode()); + + key = new FunctionMapKey(fqn, fqnType, false, null); + someKey = new FunctionMapKey(fqn, fqnType, false, null); + assertEquals(key.hashCode(), someKey.hashCode()); + + key = new FunctionMapKey(fqn, fqnType, false, new ArrayList()); + someKey = new FunctionMapKey(fqn, fqnType, false, new ArrayList()); + assertEquals(key.hashCode(), someKey.hashCode()); + + List keyList = new ArrayList(); + keyList.add("Employee"); + List someKeyList = new ArrayList(); + someKeyList.add("Employee"); + key = new FunctionMapKey(fqn, fqnType, false, keyList); + someKey = new FunctionMapKey(fqn, fqnType, false, someKeyList); + assertEquals(key.hashCode(), someKey.hashCode()); + + key = new FunctionMapKey(fqn, null, null, new ArrayList()); + someKey = new FunctionMapKey(fqn, null, null, new ArrayList()); + assertEquals(key.hashCode(), someKey.hashCode()); + + keyList = new ArrayList(); + keyList.add("Employee"); + someKeyList = new ArrayList(); + someKeyList.add("Employee"); + key = new FunctionMapKey(fqn, null, null, keyList); + someKey = new FunctionMapKey(fqn, null, null, someKeyList); + assertEquals(key.hashCode(), someKey.hashCode()); + } + + @Test + public void testHashCodeNegative() { + FunctionMapKey key = new FunctionMapKey(fqn, null, null, null); + FunctionMapKey someKey = new FunctionMapKey(fqn, null, true, null); + assertNotSame(key.hashCode(), someKey.hashCode()); + + key = new FunctionMapKey(fqn, null, true, null); + someKey = new FunctionMapKey(fqn, null, false, null); + assertNotSame(key.hashCode(), someKey.hashCode()); + + key = new FunctionMapKey(fqn, fqnType, true, null); + someKey = new FunctionMapKey(fqn, null, true, null); + assertNotSame(key.hashCode(), someKey.hashCode()); + + key = new FunctionMapKey(fqn, null, false, null); + someKey = new FunctionMapKey(fqn, fqnType, true, null); + assertNotSame(key.hashCode(), someKey.hashCode()); + + key = new FunctionMapKey(fqn, fqnType, false, null); + someKey = new FunctionMapKey(fqn, fqnType, false, new ArrayList()); + assertNotSame(key.hashCode(), someKey.hashCode()); + + List keyList = new ArrayList(); + keyList.add("Employee"); + List someKeyList = new ArrayList(); + someKeyList.add("Employee2"); + key = new FunctionMapKey(fqn, fqnType, false, keyList); + someKey = new FunctionMapKey(fqn, fqnType, false, someKeyList); + assertNotSame(key.hashCode(), someKey.hashCode()); + + key = new FunctionMapKey(fqn, null, null, new ArrayList()); + someKey = new FunctionMapKey(fqn, null, null, new ArrayList()); + assertNotSame(key.hashCode(), someKey.hashCode()); + + keyList = new ArrayList(); + keyList.add("Employee"); + someKeyList = new ArrayList(); + someKeyList.add("Employee2"); + key = new FunctionMapKey(fqn, null, null, keyList); + someKey = new FunctionMapKey(fqn, null, null, someKeyList); + assertNotSame(key.hashCode(), someKey.hashCode()); + + key = new FunctionMapKey(fqn, null, null, new ArrayList()); + someKey = new FunctionMapKey(fqn, null, null, null); + assertNotSame(key.hashCode(), someKey.hashCode()); + } + +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/CommonPrimitiveTypeTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/CommonPrimitiveTypeTest.java new file mode 100644 index 000000000..7be578932 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/CommonPrimitiveTypeTest.java @@ -0,0 +1,154 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.math.BigDecimal; +import java.util.Calendar; +import java.util.UUID; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; +import org.junit.Test; + +public class CommonPrimitiveTypeTest extends PrimitiveTypeBaseTest { + + @Test + public void nameSpace() throws Exception { + assertEquals(EdmPrimitiveType.SYSTEM_NAMESPACE, Uint7.getInstance().getNamespace()); + + assertEquals(EdmPrimitiveType.EDM_NAMESPACE, EdmNull.getInstance().getNamespace()); + for (EdmPrimitiveTypeKind kind : EdmPrimitiveTypeKind.values()) { + final EdmPrimitiveType instance = kind.getEdmPrimitiveTypeInstance(); + assertEquals(EdmPrimitiveType.EDM_NAMESPACE, instance.getNamespace()); + } + } + + @Test + public void names() throws Exception { + assertEquals("Uint7", Uint7.getInstance().getName()); + + assertEquals("Null", EdmNull.getInstance().getName()); + assertEquals("Binary", EdmPrimitiveTypeKind.Binary.getEdmPrimitiveTypeInstance().getName()); + assertEquals("Boolean", EdmPrimitiveTypeKind.Boolean.getEdmPrimitiveTypeInstance().getName()); + assertEquals("Byte", EdmPrimitiveTypeKind.Byte.getEdmPrimitiveTypeInstance().getName()); + assertEquals("Date", EdmPrimitiveTypeKind.Date.getEdmPrimitiveTypeInstance().getName()); + assertEquals("DateTimeOffset", EdmPrimitiveTypeKind.DateTimeOffset.getEdmPrimitiveTypeInstance().getName()); + assertEquals("Decimal", EdmPrimitiveTypeKind.Decimal.getEdmPrimitiveTypeInstance().getName()); + assertEquals("Double", EdmPrimitiveTypeKind.Double.getEdmPrimitiveTypeInstance().getName()); + assertEquals("Duration", EdmPrimitiveTypeKind.Duration.getEdmPrimitiveTypeInstance().getName()); + assertEquals("Guid", EdmPrimitiveTypeKind.Guid.getEdmPrimitiveTypeInstance().getName()); + assertEquals("Int16", EdmPrimitiveTypeKind.Int16.getEdmPrimitiveTypeInstance().getName()); + assertEquals("Int32", EdmPrimitiveTypeKind.Int32.getEdmPrimitiveTypeInstance().getName()); + assertEquals("Int64", EdmPrimitiveTypeKind.Int64.getEdmPrimitiveTypeInstance().getName()); + assertEquals("SByte", EdmPrimitiveTypeKind.SByte.getEdmPrimitiveTypeInstance().getName()); + assertEquals("Single", EdmPrimitiveTypeKind.Single.getEdmPrimitiveTypeInstance().getName()); + assertEquals("String", EdmPrimitiveTypeKind.String.getEdmPrimitiveTypeInstance().getName()); + assertEquals("TimeOfDay", EdmPrimitiveTypeKind.TimeOfDay.getEdmPrimitiveTypeInstance().getName()); + } + + @Test + public void kind() throws Exception { + for (EdmPrimitiveTypeKind kind : EdmPrimitiveTypeKind.values()) { + assertEquals(EdmTypeKind.PRIMITIVE, kind.getEdmPrimitiveTypeInstance().getKind()); + } + } + + @Test + public void toStringAll() throws Exception { + assertEquals("System.Uint7", Uint7.getInstance().toString()); + + assertEquals("Edm.Null", EdmNull.getInstance().toString()); + assertEquals("Edm.Binary", EdmPrimitiveTypeKind.Binary.getEdmPrimitiveTypeInstance().toString()); + assertEquals("Edm.Boolean", EdmPrimitiveTypeKind.Boolean.getEdmPrimitiveTypeInstance().toString()); + assertEquals("Edm.Byte", EdmPrimitiveTypeKind.Byte.getEdmPrimitiveTypeInstance().toString()); + assertEquals("Edm.Date", EdmPrimitiveTypeKind.Date.getEdmPrimitiveTypeInstance().toString()); + assertEquals("Edm.DateTimeOffset", EdmPrimitiveTypeKind.DateTimeOffset.getEdmPrimitiveTypeInstance().toString()); + assertEquals("Edm.Decimal", EdmPrimitiveTypeKind.Decimal.getEdmPrimitiveTypeInstance().toString()); + assertEquals("Edm.Double", EdmPrimitiveTypeKind.Double.getEdmPrimitiveTypeInstance().toString()); + assertEquals("Edm.Duration", EdmPrimitiveTypeKind.Duration.getEdmPrimitiveTypeInstance().toString()); + assertEquals("Edm.Guid", EdmPrimitiveTypeKind.Guid.getEdmPrimitiveTypeInstance().toString()); + assertEquals("Edm.Int16", EdmPrimitiveTypeKind.Int16.getEdmPrimitiveTypeInstance().toString()); + assertEquals("Edm.Int32", EdmPrimitiveTypeKind.Int32.getEdmPrimitiveTypeInstance().toString()); + assertEquals("Edm.Int64", EdmPrimitiveTypeKind.Int64.getEdmPrimitiveTypeInstance().toString()); + assertEquals("Edm.SByte", EdmPrimitiveTypeKind.SByte.getEdmPrimitiveTypeInstance().toString()); + assertEquals("Edm.Single", EdmPrimitiveTypeKind.Single.getEdmPrimitiveTypeInstance().toString()); + assertEquals("Edm.String", EdmPrimitiveTypeKind.String.getEdmPrimitiveTypeInstance().toString()); + assertEquals("Edm.TimeOfDay", EdmPrimitiveTypeKind.TimeOfDay.getEdmPrimitiveTypeInstance().toString()); + + for (EdmPrimitiveTypeKind kind : EdmPrimitiveTypeKind.values()) { + final EdmPrimitiveType instance = kind.getEdmPrimitiveTypeInstance(); + assertEquals(instance.toString(), kind.getFullQualifiedName().toString()); + } + } + + @Test + public void compatibility() { + for (EdmPrimitiveTypeKind kind : EdmPrimitiveTypeKind.values()) { + final EdmPrimitiveType instance = kind.getEdmPrimitiveTypeInstance(); + assertTrue(instance.isCompatible(instance)); + assertFalse(instance.isCompatible( + (kind == EdmPrimitiveTypeKind.String ? EdmPrimitiveTypeKind.Binary : EdmPrimitiveTypeKind.String) + .getEdmPrimitiveTypeInstance())); + } + } + + @Test + public void defaultType() throws Exception { + assertEquals(Byte.class, Uint7.getInstance().getDefaultType()); + assertNull(EdmNull.getInstance().getDefaultType()); + + assertEquals(byte[].class, EdmPrimitiveTypeKind.Binary.getEdmPrimitiveTypeInstance().getDefaultType()); + assertEquals(Boolean.class, EdmPrimitiveTypeKind.Boolean.getEdmPrimitiveTypeInstance().getDefaultType()); + assertEquals(Short.class, EdmPrimitiveTypeKind.Byte.getEdmPrimitiveTypeInstance().getDefaultType()); + assertEquals(Calendar.class, EdmPrimitiveTypeKind.Date.getEdmPrimitiveTypeInstance().getDefaultType()); + assertEquals(Calendar.class, EdmPrimitiveTypeKind.DateTimeOffset.getEdmPrimitiveTypeInstance().getDefaultType()); + assertEquals(BigDecimal.class, EdmPrimitiveTypeKind.Decimal.getEdmPrimitiveTypeInstance().getDefaultType()); + assertEquals(Double.class, EdmPrimitiveTypeKind.Double.getEdmPrimitiveTypeInstance().getDefaultType()); + assertEquals(BigDecimal.class, EdmPrimitiveTypeKind.Duration.getEdmPrimitiveTypeInstance().getDefaultType()); + assertEquals(UUID.class, EdmPrimitiveTypeKind.Guid.getEdmPrimitiveTypeInstance().getDefaultType()); + assertEquals(Short.class, EdmPrimitiveTypeKind.Int16.getEdmPrimitiveTypeInstance().getDefaultType()); + assertEquals(Integer.class, EdmPrimitiveTypeKind.Int32.getEdmPrimitiveTypeInstance().getDefaultType()); + assertEquals(Long.class, EdmPrimitiveTypeKind.Int64.getEdmPrimitiveTypeInstance().getDefaultType()); + assertEquals(Byte.class, EdmPrimitiveTypeKind.SByte.getEdmPrimitiveTypeInstance().getDefaultType()); + assertEquals(Float.class, EdmPrimitiveTypeKind.Single.getEdmPrimitiveTypeInstance().getDefaultType()); + assertEquals(String.class, EdmPrimitiveTypeKind.String.getEdmPrimitiveTypeInstance().getDefaultType()); + assertEquals(Calendar.class, EdmPrimitiveTypeKind.TimeOfDay.getEdmPrimitiveTypeInstance().getDefaultType()); + } + + @Test + public void validate() throws Exception { + for (EdmPrimitiveTypeKind kind : EdmPrimitiveTypeKind.values()) { + final EdmPrimitiveType instance = kind.getEdmPrimitiveTypeInstance(); + assertTrue(instance.validate(null, null, null, null, null, null)); + assertTrue(instance.validate(null, true, null, null, null, null)); + assertFalse(instance.validate(null, false, null, null, null, null)); + assertFalse(instance.validate("ä", null, null, null, null, false)); + if (kind != EdmPrimitiveTypeKind.String && kind != EdmPrimitiveTypeKind.Binary) { + assertFalse(instance.validate("", null, null, null, null, null)); + } + if (kind != EdmPrimitiveTypeKind.String) { + assertFalse(instance.validate("ä", null, null, null, null, null)); + } + } + + assertTrue(EdmPrimitiveTypeKind.Binary.getEdmPrimitiveTypeInstance().validate("abcd", null, 3, null, null, null)); + assertFalse(EdmPrimitiveTypeKind.Binary.getEdmPrimitiveTypeInstance().validate("abcd", null, 2, null, null, null)); + + assertTrue(EdmPrimitiveTypeKind.Decimal.getEdmPrimitiveTypeInstance().validate("1", null, null, null, null, + null)); + assertFalse(EdmPrimitiveTypeKind.Decimal.getEdmPrimitiveTypeInstance().validate("1.2", null, null, null, 0, null)); + } + + @Test + public void uriLiteral() throws Exception { + for (EdmPrimitiveTypeKind kind : EdmPrimitiveTypeKind.values()) { + final EdmPrimitiveType instance = kind.getEdmPrimitiveTypeInstance(); + assertEquals("test", instance.fromUriLiteral(instance.toUriLiteral("test"))); + assertNull(instance.toUriLiteral(null)); + assertNull(instance.fromUriLiteral(null)); + } + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBinaryTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBinaryTest.java new file mode 100644 index 000000000..e9ae9bca3 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBinaryTest.java @@ -0,0 +1,87 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmBinaryTest extends PrimitiveTypeBaseTest { + + private final EdmPrimitiveType instance = EdmPrimitiveTypeKind.Binary.getEdmPrimitiveTypeInstance(); + + @Test + public void validate() throws Exception { + assertTrue(instance.validate(null, null, null, null, null, null)); + assertTrue(instance.validate(null, true, null, null, null, null)); + assertFalse(instance.validate(null, false, null, null, null, null)); + assertTrue(instance.validate("", null, null, null, null, null)); + assertFalse(instance.validate("????", null, null, null, null, null)); + + assertTrue(instance.validate("qrvM3e7_", null, null, null, null, null)); + assertTrue(instance.validate("qrvM3e7_", null, 6, null, null, null)); + assertFalse(instance.validate("qrvM3e7_", null, 5, null, null, null)); + } + + @Test + public void toUriLiteral() throws Exception { + assertEquals("binary'+hKqoQ=='", instance.toUriLiteral("+hKqoQ==")); + assertEquals("binary''", instance.toUriLiteral("")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertEquals("+hKqoQ==", instance.fromUriLiteral("binary'+hKqoQ=='")); + assertEquals("", instance.fromUriLiteral("binary''")); + + expectErrorInFromUriLiteral(instance, ""); + expectErrorInFromUriLiteral(instance, "binary'\""); + expectErrorInFromUriLiteral(instance, "X''"); + expectErrorInFromUriLiteral(instance, "Xinary''"); + } + + @Test + public void valueToString() throws Exception { + final byte[] binary = new byte[] { (byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD, (byte) 0xEE, (byte) 0xFF }; + + assertEquals("qrvM3e7_", instance.valueToString(binary, null, null, null, null, null)); + + assertEquals("qrvM3e7_", instance.valueToString(binary, null, 6, null, null, null)); + assertEquals("qrvM3e7_", instance.valueToString(binary, null, Integer.MAX_VALUE, null, null, null)); + + assertEquals("qg", instance.valueToString(new Byte[] { new Byte((byte) 170) }, null, null, null, null, null)); + + expectFacetsErrorInValueToString(instance, binary, null, 3, null, null, null); + + expectTypeErrorInValueToString(instance, 0); + } + + @Test + public void valueOfString() throws Exception { + final byte[] binary = new byte[] { (byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD, (byte) 0xEE, (byte) 0xFF }; + + assertTrue(Arrays.equals(binary, instance.valueOfString("qrvM3e7_", null, null, null, null, null, byte[].class))); + assertTrue(Arrays.equals(new Byte[] { binary[0], binary[1], binary[2] }, instance.valueOfString("qrvM", null, null, + null, null, null, Byte[].class))); + + assertTrue(Arrays.equals(binary, instance.valueOfString("qrvM3e7_", null, 6, null, null, null, byte[].class))); + assertTrue(Arrays.equals(new byte[] { 42 }, instance.valueOfString("Kg==", null, 1, null, null, null, + byte[].class))); + assertTrue(Arrays.equals(new byte[] { 42 }, instance.valueOfString("Kg", null, 1, null, null, null, + byte[].class))); + assertTrue(Arrays.equals(new byte[] { 1, 2 }, instance.valueOfString("AQI=", null, 2, null, null, null, + byte[].class))); + assertTrue(Arrays.equals(binary, instance.valueOfString("qrvM3e7_", null, 6, null, null, null, + byte[].class))); + assertTrue(Arrays.equals(binary, instance.valueOfString("qrvM3e7_", null, Integer.MAX_VALUE, null, null, null, + byte[].class))); + + expectFacetsErrorInValueOfString(instance, "qrvM3e7_", null, 3, null, null, null); + expectContentErrorInValueOfString(instance, "@"); + + expectTypeErrorInValueOfString(instance, "qrvM3e7_"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBooleanTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBooleanTest.java new file mode 100644 index 000000000..bf137c4e5 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBooleanTest.java @@ -0,0 +1,45 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmBooleanTest extends PrimitiveTypeBaseTest { + + private final EdmPrimitiveType instance = EdmPrimitiveTypeKind.Boolean.getEdmPrimitiveTypeInstance(); + + @Test + public void toUriLiteral() throws Exception { + assertEquals("true", instance.toUriLiteral("true")); + assertEquals("false", instance.toUriLiteral("false")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertEquals("true", instance.fromUriLiteral("true")); + assertEquals("false", instance.fromUriLiteral("false")); + } + + @Test + public void valueToString() throws Exception { + assertEquals("true", instance.valueToString(true, null, null, null, null, null)); + assertEquals("false", instance.valueToString(Boolean.FALSE, null, null, null, null, null)); + + expectTypeErrorInValueToString(instance, 0); + } + + @Test + public void valueOfString() throws Exception { + assertEquals(true, instance.valueOfString("true", null, null, null, null, null, Boolean.class)); + assertEquals(false, instance.valueOfString("false", null, null, null, null, null, Boolean.class)); + + expectContentErrorInValueOfString(instance, "True"); + expectContentErrorInValueOfString(instance, "1"); + expectContentErrorInValueOfString(instance, "0"); + expectContentErrorInValueOfString(instance, "-1"); + expectContentErrorInValueOfString(instance, "FALSE"); + + expectTypeErrorInValueOfString(instance, "true"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmByteTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmByteTest.java new file mode 100644 index 000000000..69fc3502f --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmByteTest.java @@ -0,0 +1,66 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.math.BigInteger; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmByteTest extends PrimitiveTypeBaseTest { + + private final EdmPrimitiveType instance = EdmPrimitiveTypeKind.Byte.getEdmPrimitiveTypeInstance(); + + @Test + public void compatibility() { + assertTrue(instance.isCompatible(Uint7.getInstance())); + } + + @Test + public void toUriLiteral() throws Exception { + assertEquals("127", instance.toUriLiteral("127")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertEquals("127", instance.fromUriLiteral("127")); + } + + @Test + public void valueToString() throws Exception { + assertEquals("0", instance.valueToString(0, null, null, null, null, null)); + assertEquals("8", instance.valueToString((byte) 8, null, null, null, null, null)); + assertEquals("16", instance.valueToString((short) 16, null, null, null, null, null)); + assertEquals("32", instance.valueToString(Integer.valueOf(32), null, null, null, null, null)); + assertEquals("255", instance.valueToString(255L, null, null, null, null, null)); + assertEquals("255", instance.valueToString(BigInteger.valueOf(255), null, null, null, null, null)); + + expectContentErrorInValueToString(instance, -1); + expectContentErrorInValueToString(instance, 256); + expectContentErrorInValueToString(instance, BigInteger.valueOf(-1)); + expectContentErrorInValueToString(instance, BigInteger.valueOf(256)); + + expectTypeErrorInValueToString(instance, 'A'); + } + + @Test + public void valueOfString() throws Exception { + assertEquals(Short.valueOf((short) 1), instance.valueOfString("1", null, null, null, null, null, Short.class)); + assertEquals(Integer.valueOf(2), instance.valueOfString("2", null, null, null, null, null, Integer.class)); + assertEquals(Byte.valueOf((byte) 127), instance.valueOfString("127", null, null, null, null, null, Byte.class)); + assertEquals(Short.valueOf((short) 255), instance.valueOfString("255", null, null, null, null, null, Short.class)); + assertEquals(Long.valueOf(0), instance.valueOfString("0", null, null, null, null, null, Long.class)); + assertEquals(BigInteger.TEN, instance.valueOfString("10", null, null, null, null, null, BigInteger.class)); + + expectContentErrorInValueOfString(instance, "0x42"); + expectContentErrorInValueOfString(instance, "abc"); + expectContentErrorInValueOfString(instance, "256"); + expectContentErrorInValueOfString(instance, "-1"); + expectContentErrorInValueOfString(instance, "1.0"); + + expectUnconvertibleErrorInValueOfString(instance, "128", Byte.class); + + expectTypeErrorInValueOfString(instance, "1"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java new file mode 100644 index 000000000..4056c7a93 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java @@ -0,0 +1,74 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; + +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmDateTest extends PrimitiveTypeBaseTest { + + private final EdmPrimitiveType instance = EdmPrimitiveTypeKind.Date.getEdmPrimitiveTypeInstance(); + + @Test + public void toUriLiteral() throws Exception { + assertEquals("2009-12-26", instance.toUriLiteral("2009-12-26")); + assertEquals("-2009-12-26", instance.toUriLiteral("-2009-12-26")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertEquals("2009-12-26", instance.fromUriLiteral("2009-12-26")); + assertEquals("-2009-12-26", instance.fromUriLiteral("-2009-12-26")); + } + + @Test + public void valueToString() throws Exception { + Calendar dateTime = Calendar.getInstance(); + dateTime.clear(); + dateTime.setTimeZone(TimeZone.getTimeZone("GMT-11:30")); + dateTime.set(2012, 1, 29, 13, 0, 0); + assertEquals("2012-02-29", instance.valueToString(dateTime, null, null, null, null, null)); + + final Long millis = 1330558323007L; + assertEquals("2012-02-29", instance.valueToString(millis, null, null, null, null, null)); + + assertEquals("1969-12-31", instance.valueToString(new Date(-43200000), null, null, null, null, null)); + + dateTime.set(Calendar.YEAR, 12344); + assertEquals("12344-02-29", instance.valueToString(dateTime, null, null, null, null, null)); + + expectTypeErrorInValueToString(instance, 0); + } + + @Test + public void valueOfString() throws Exception { + Calendar dateTime = Calendar.getInstance(); + dateTime.clear(); + dateTime.setTimeZone(TimeZone.getTimeZone("GMT")); + dateTime.set(2012, 1, 29); + assertEquals(dateTime, instance.valueOfString("2012-02-29", null, null, null, null, null, Calendar.class)); + assertEquals(Long.valueOf(dateTime.getTimeInMillis()), instance.valueOfString("2012-02-29", null, null, null, null, + null, Long.class)); + assertEquals(dateTime.getTime(), instance.valueOfString("2012-02-29", null, null, null, null, null, Date.class)); + + dateTime.set(Calendar.YEAR, 12344); + assertEquals(dateTime, instance.valueOfString("12344-02-29", null, null, null, null, null, Calendar.class)); + + // TODO: Clarify whether negative years are really needed. + // dateTime.set(-1, 1, 28); + // assertEquals(dateTime, instance.valueOfString("-0001-02-28", null, Calendar.class)); + + expectContentErrorInValueOfString(instance, "2012-02-29T23:32:02"); + expectContentErrorInValueOfString(instance, "2012-02-30"); + expectContentErrorInValueOfString(instance, "20120229"); + expectContentErrorInValueOfString(instance, "2012-02-1"); + expectContentErrorInValueOfString(instance, "2012-2-12"); + expectContentErrorInValueOfString(instance, "123-02-03"); + + expectTypeErrorInValueOfString(instance, "2012-02-29"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java new file mode 100644 index 000000000..6f5fcb3db --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java @@ -0,0 +1,106 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmDateTimeOffsetTest extends PrimitiveTypeBaseTest { + + final EdmPrimitiveType instance = EdmPrimitiveTypeKind.DateTimeOffset.getEdmPrimitiveTypeInstance(); + + @Test + public void toUriLiteral() throws Exception { + assertEquals("2009-12-26T21:23:38Z", instance.toUriLiteral("2009-12-26T21:23:38Z")); + assertEquals("2002-10-10T12:00:00-05:00", instance.toUriLiteral("2002-10-10T12:00:00-05:00")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertEquals("2009-12-26T21:23:38Z", instance.fromUriLiteral("2009-12-26T21:23:38Z")); + assertEquals("2002-10-10T12:00:00-05:00", instance.fromUriLiteral("2002-10-10T12:00:00-05:00")); + } + + @Test + public void valueToString() throws Exception { + Calendar dateTime = Calendar.getInstance(); + dateTime.clear(); + dateTime.setTimeZone(TimeZone.getTimeZone("GMT")); + dateTime.set(2012, 1, 29, 1, 2, 3); + assertEquals("2012-02-29T01:02:03Z", instance.valueToString(dateTime, null, null, null, null, null)); + assertEquals("2012-02-29T01:02:03Z", instance.valueToString(dateTime, null, null, 0, null, null)); + assertEquals("2012-02-29T01:02:03Z", instance.valueToString(dateTime, null, null, 5, null, null)); + + dateTime.setTimeZone(TimeZone.getTimeZone("GMT-1:30")); + assertEquals("2012-02-29T01:02:03-01:30", instance.valueToString(dateTime, null, null, null, null, null)); + + dateTime.setTimeZone(TimeZone.getTimeZone("GMT+11:00")); + assertEquals("2012-02-29T01:02:03+11:00", instance.valueToString(dateTime, null, null, null, null, null)); + + final Long millis = 1330558323007L; + assertEquals("2012-02-29T23:32:03.007Z", instance.valueToString(millis, null, null, 3, null, null)); + assertEquals("1969-12-31T23:59:59.9Z", instance.valueToString(-100L, null, null, 1, null, null)); + assertEquals("1969-12-31T23:59:59.98Z", instance.valueToString(-20L, null, null, 2, null, null)); + + final Date date = new Date(millis); + final String time = date.toString().substring(11, 19); + assertTrue(instance.valueToString(date, null, null, 3, null, null).contains(time)); + + expectFacetsErrorInValueToString(instance, millis, null, null, null, null, null); + expectFacetsErrorInValueToString(instance, 3L, null, null, 2, null, null); + + expectTypeErrorInValueToString(instance, 0); + } + + @Test + public void valueOfString() throws Exception { + Calendar dateTime = Calendar.getInstance(); + dateTime.clear(); + dateTime.setTimeZone(TimeZone.getTimeZone("GMT")); + dateTime.set(2012, 1, 29, 1, 2, 3); + assertEquals(dateTime, instance.valueOfString("2012-02-29T01:02:03Z", null, null, null, null, null, + Calendar.class)); + assertEquals(Long.valueOf(dateTime.getTimeInMillis()), instance.valueOfString("2012-02-29T01:02:03+00:00", null, + null, null, null, null, Long.class)); + assertEquals(dateTime, instance.valueOfString("2012-02-29T01:02:03", null, null, null, null, null, + Calendar.class)); + + dateTime.clear(); + dateTime.setTimeZone(TimeZone.getTimeZone("GMT-01:30")); + dateTime.set(2012, 1, 29, 1, 2, 3); + assertEquals(dateTime.getTime(), instance.valueOfString("2012-02-29T01:02:03-01:30", null, null, null, null, null, + Date.class)); + + dateTime.clear(); + dateTime.setTimeZone(TimeZone.getTimeZone("GMT+11:00")); + dateTime.set(2012, 1, 29, 1, 2, 3); + assertEquals(dateTime, instance.valueOfString("2012-02-29T01:02:03+11:00", null, null, null, null, null, + Calendar.class)); + + dateTime.add(Calendar.MILLISECOND, 7); + assertEquals(dateTime, instance.valueOfString("2012-02-29T01:02:03.007+11:00", null, null, 3, null, null, + Calendar.class)); + + assertEquals(Long.valueOf(120000L), instance.valueOfString("1970-01-01T00:02", null, null, null, null, null, + Long.class)); + assertEquals(Long.valueOf(12L), instance.valueOfString("1970-01-01T00:00:00.012", null, null, 3, null, null, + Long.class)); + assertEquals(Long.valueOf(120L), instance.valueOfString("1970-01-01T00:00:00.12", null, null, 2, null, null, + Long.class)); + + expectFacetsErrorInValueOfString(instance, "2012-02-29T23:32:02.9Z", null, null, null, null, null); + expectFacetsErrorInValueOfString(instance, "2012-02-29T23:32:02.9Z", null, null, 0, null, null); + expectContentErrorInValueOfString(instance, "2012-02-29T23:32:02X"); + expectContentErrorInValueOfString(instance, "2012-02-29T23:32:02+24:00"); + expectContentErrorInValueOfString(instance, "2012-02-30T01:02:03"); + expectContentErrorInValueOfString(instance, "2012-02-29T23:32:02."); + expectContentErrorInValueOfString(instance, "2012-02-29T23:32:02.0000000000000"); + + expectTypeErrorInValueOfString(instance, "2012-02-29T01:02:03Z"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDecimalTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDecimalTest.java new file mode 100644 index 000000000..c080bf4dd --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDecimalTest.java @@ -0,0 +1,112 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmDecimalTest extends PrimitiveTypeBaseTest { + + private final EdmPrimitiveType instance = EdmPrimitiveTypeKind.Decimal.getEdmPrimitiveTypeInstance(); + + @Test + public void compatibility() { + assertTrue(instance.isCompatible(Uint7.getInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Byte.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.SByte.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Int16.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Int32.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Int64.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Single.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Double.getEdmPrimitiveTypeInstance())); + } + + @Test + public void uriLiteral() throws Exception { + assertEquals("12.34", instance.toUriLiteral("12.34")); + assertEquals("12.34", instance.fromUriLiteral("12.34")); + } + + @Test + public void valueToString() throws Exception { + assertEquals("0", instance.valueToString(0, null, null, null, null, null)); + assertEquals("8", instance.valueToString((byte) 8, null, null, null, null, null)); + assertEquals("16", instance.valueToString((short) 16, null, null, null, null, null)); + assertEquals("32", instance.valueToString(Integer.valueOf(32), null, null, null, null, null)); + assertEquals("-32768", instance.valueToString(-32768, null, null, null, null, null)); + assertEquals("255", instance.valueToString(255L, null, null, null, null, null)); + assertEquals("1234567890123456789012345678901", instance.valueToString(new BigInteger( + "1234567890123456789012345678901"), null, null, null, null, null)); + assertEquals("0.00390625", instance.valueToString(1.0 / 256, null, null, null, 8, null)); + assertEquals("-0.125", instance.valueToString(-0.125f, null, null, null, 3, null)); + assertEquals("-1234567890.1234567890", instance.valueToString(new BigDecimal( + "-1234567890.1234567890"), null, null, null, 10, null)); + + assertEquals("-32768", instance.valueToString(-32768, null, null, 42, null, null)); + assertEquals("-32768", instance.valueToString(-32768, null, null, 5, null, null)); + assertEquals("32768", instance.valueToString(32768, null, null, 5, null, null)); + assertEquals("0.5", instance.valueToString(0.5, null, null, 1, 1, null)); + assertEquals("0.5", instance.valueToString(0.5, null, null, null, 1, null)); + assertEquals("100", instance.valueToString(new BigDecimal(BigInteger.ONE, -2), null, null, 3, null, null)); + + expectFacetsErrorInValueToString(instance, 0.5, null, null, null, null, null); + expectFacetsErrorInValueToString(instance, -1234, null, null, 2, null, null); + expectFacetsErrorInValueToString(instance, 1234, null, null, 3, null, null); + expectFacetsErrorInValueToString(instance, 0.00390625, null, null, 5, null, null); + expectFacetsErrorInValueToString(instance, 0.00390625, null, null, null, 7, null); + + expectContentErrorInValueToString(instance, Double.NaN); + + expectTypeErrorInValueToString(instance, 'A'); + } + + @Test + public void valueOfString() throws Exception { + assertEquals(BigDecimal.ONE, instance.valueOfString("1", null, null, null, null, null, BigDecimal.class)); + assertEquals(Byte.valueOf((byte) -2), instance.valueOfString("-2", null, null, null, null, null, Byte.class)); + assertEquals(new BigDecimal("-123456789012345678901234567890"), instance.valueOfString( + "-123456789012345678901234567890", null, null, null, null, null, BigDecimal.class)); + assertEquals(Short.valueOf((short) 0), instance.valueOfString("0", null, null, null, null, null, Short.class)); + + assertEquals(Integer.valueOf(-32768), instance.valueOfString("-32768", null, null, 42, null, null, Integer.class)); + assertEquals(Long.valueOf(-32768), instance.valueOfString("-32768", null, null, 5, null, null, Long.class)); + assertEquals(BigInteger.valueOf(32768), instance.valueOfString("32768", null, null, 5, null, null, + BigInteger.class)); + assertEquals(Double.valueOf(0.5), instance.valueOfString("0.5", null, null, 1, 1, null, Double.class)); + assertEquals(Float.valueOf(0.5F), instance.valueOfString("0.5", null, null, null, 1, null, Float.class)); + assertEquals(new BigDecimal("12.3"), instance.valueOfString("12.3", null, null, 3, 1, null, BigDecimal.class)); + + expectFacetsErrorInValueOfString(instance, "0.5", null, null, null, null, null); + expectFacetsErrorInValueOfString(instance, "-1234", null, null, 2, null, null); + expectFacetsErrorInValueOfString(instance, "1234", null, null, 3, null, null); + expectFacetsErrorInValueOfString(instance, "12.34", null, null, 3, null, null); + expectFacetsErrorInValueOfString(instance, "12.34", null, null, 3, 2, null); + expectFacetsErrorInValueOfString(instance, "12.34", null, null, 4, 1, null); + expectFacetsErrorInValueOfString(instance, "0.00390625", null, null, 5, null, null); + expectFacetsErrorInValueOfString(instance, "0.00390625", null, null, null, 7, null); + + expectContentErrorInValueOfString(instance, "-1E2"); + expectContentErrorInValueOfString(instance, "1."); + expectContentErrorInValueOfString(instance, ".1"); + expectContentErrorInValueOfString(instance, "1.0.1"); + expectContentErrorInValueOfString(instance, "1M"); + expectContentErrorInValueOfString(instance, "0x42"); + + expectUnconvertibleErrorInValueOfString(instance, "-129", Byte.class); + expectUnconvertibleErrorInValueOfString(instance, "128", Byte.class); + expectUnconvertibleErrorInValueOfString(instance, "-32769", Short.class); + expectUnconvertibleErrorInValueOfString(instance, "32768", Short.class); + expectUnconvertibleErrorInValueOfString(instance, "-2147483649", Integer.class); + expectUnconvertibleErrorInValueOfString(instance, "2147483648", Integer.class); + expectUnconvertibleErrorInValueOfString(instance, "-9223372036854775809", Long.class); + expectUnconvertibleErrorInValueOfString(instance, "9223372036854775808", Long.class); + expectUnconvertibleErrorInValueOfString(instance, "12345678901234567", Double.class); + expectUnconvertibleErrorInValueOfString(instance, "1234567890", Float.class); + + expectTypeErrorInValueOfString(instance, "1"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDoubleTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDoubleTest.java new file mode 100644 index 000000000..80f519eed --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDoubleTest.java @@ -0,0 +1,112 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmDoubleTest extends PrimitiveTypeBaseTest { + + private final EdmPrimitiveType instance = EdmPrimitiveTypeKind.Double.getEdmPrimitiveTypeInstance(); + + @Test + public void compatibility() { + assertTrue(instance.isCompatible(Uint7.getInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Byte.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.SByte.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Int16.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Int32.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Int64.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Single.getEdmPrimitiveTypeInstance())); + } + + @Test + public void toUriLiteral() { + assertEquals("127E42", instance.toUriLiteral("127E42")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertEquals("127E42", instance.fromUriLiteral("127E42")); + } + + @Test + public void valueToString() throws Exception { + assertEquals("0", instance.valueToString(0, null, null, null, null, null)); + assertEquals("8", instance.valueToString((byte) 8, null, null, null, null, null)); + assertEquals("16", instance.valueToString((short) 16, null, null, null, null, null)); + assertEquals("32", instance.valueToString(Integer.valueOf(32), null, null, null, null, null)); + assertEquals("255", instance.valueToString(255L, null, null, null, null, null)); + assertEquals("0.00390625", instance.valueToString(1.0 / 256, null, null, null, null, null)); + assertEquals("4.2E-41", instance.valueToString(42e-42, null, null, null, null, null)); + assertEquals("INF", instance.valueToString(Double.POSITIVE_INFINITY, null, null, null, null, null)); + assertEquals("-INF", instance.valueToString(Double.NEGATIVE_INFINITY, null, null, null, null, null)); + assertEquals("NaN", instance.valueToString(Double.NaN, null, null, null, null, null)); + assertEquals("-0.125", instance.valueToString(-0.125f, null, null, null, null, null)); + assertEquals("INF", instance.valueToString(Float.POSITIVE_INFINITY, null, null, null, null, null)); + assertEquals("-INF", instance.valueToString(Float.NEGATIVE_INFINITY, null, null, null, null, null)); + assertEquals("NaN", instance.valueToString(Float.NaN, null, null, null, null, null)); + assertEquals("-1234567890.12345", instance.valueToString(new BigDecimal("-1234567890.12345"), null, null, null, + null, null)); + + expectContentErrorInValueToString(instance, 3234567890123456L); + expectContentErrorInValueToString(instance, new BigDecimal("98765432109876543")); + expectContentErrorInValueToString(instance, new BigDecimal(BigInteger.ONE, 324)); + expectContentErrorInValueToString(instance, new BigDecimal(BigInteger.ONE.negate(), -309)); + + expectTypeErrorInValueToString(instance, 'A'); + } + + @Test + public void valueOfString() throws Exception { + assertEquals(Double.valueOf(1.42), instance.valueOfString("1.42", null, null, null, null, null, Double.class)); + assertEquals(Float.valueOf(-42.25F), instance.valueOfString("-42.25", null, null, null, null, null, Float.class)); + assertEquals(Double.valueOf(42.0), instance.valueOfString("42", null, null, null, null, null, Double.class)); + assertEquals(Double.valueOf(42E42), instance.valueOfString("42E42", null, null, null, null, null, Double.class)); + assertEquals(BigDecimal.TEN, instance.valueOfString("10", null, null, null, null, null, BigDecimal.class)); + assertEquals(Byte.valueOf((byte) 0), instance.valueOfString("0", null, null, null, null, null, Byte.class)); + assertEquals(Short.valueOf((short) 1), instance.valueOfString("1.00", null, null, null, null, null, Short.class)); + assertEquals(Integer.valueOf(42), instance.valueOfString("4.2E1", null, null, null, null, null, Integer.class)); + assertEquals(Long.valueOf(1234567890), instance.valueOfString("1234567890E-00", null, null, null, null, null, + Long.class)); + + assertEquals(Double.valueOf(Double.NaN), instance.valueOfString("NaN", null, null, null, null, null, + Double.class)); + assertEquals(Double.valueOf(Double.NEGATIVE_INFINITY), instance.valueOfString("-INF", null, null, null, null, + null, Double.class)); + assertEquals(Float.valueOf(Float.POSITIVE_INFINITY), instance.valueOfString("INF", null, null, null, null, null, + Float.class)); + + expectContentErrorInValueOfString(instance, "0."); + expectContentErrorInValueOfString(instance, ".0"); + expectContentErrorInValueOfString(instance, "1234567890.12345678"); + expectContentErrorInValueOfString(instance, "42E400"); + expectContentErrorInValueOfString(instance, "42.42.42"); + expectContentErrorInValueOfString(instance, "42F"); + expectContentErrorInValueOfString(instance, "0x42P42"); + + expectUnconvertibleErrorInValueOfString(instance, "INF", BigDecimal.class); + expectUnconvertibleErrorInValueOfString(instance, "NaN", BigDecimal.class); + expectUnconvertibleErrorInValueOfString(instance, "1234567.0625", Float.class); + expectUnconvertibleErrorInValueOfString(instance, "-INF", Integer.class); + expectUnconvertibleErrorInValueOfString(instance, "NaN", Integer.class); + expectUnconvertibleErrorInValueOfString(instance, "5E-1", Byte.class); + expectUnconvertibleErrorInValueOfString(instance, "5E-1", Short.class); + expectUnconvertibleErrorInValueOfString(instance, "5E-1", Integer.class); + expectUnconvertibleErrorInValueOfString(instance, "5E-1", Long.class); + expectUnconvertibleErrorInValueOfString(instance, "-129", Byte.class); + expectUnconvertibleErrorInValueOfString(instance, "128", Byte.class); + expectUnconvertibleErrorInValueOfString(instance, "-32769", Short.class); + expectUnconvertibleErrorInValueOfString(instance, "32768", Short.class); + expectUnconvertibleErrorInValueOfString(instance, "-2147483649", Integer.class); + expectUnconvertibleErrorInValueOfString(instance, "2147483648", Integer.class); + expectUnconvertibleErrorInValueOfString(instance, "-922337203685477.5E10", Long.class); + expectUnconvertibleErrorInValueOfString(instance, "922337203685477.5E10", Long.class); + + expectTypeErrorInValueOfString(instance, "1.42"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDurationTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDurationTest.java new file mode 100644 index 000000000..3094ab9b4 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDurationTest.java @@ -0,0 +1,86 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmDurationTest extends PrimitiveTypeBaseTest { + + private final EdmPrimitiveType instance = EdmPrimitiveTypeKind.Duration.getEdmPrimitiveTypeInstance(); + + @Test + public void toUriLiteral() throws Exception { + assertEquals("duration'P120D'", instance.toUriLiteral("P120D")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertEquals("P120D", instance.fromUriLiteral("duration'P120D'")); + + expectErrorInFromUriLiteral(instance, ""); + expectErrorInFromUriLiteral(instance, "Duration'PT1S'"); + expectErrorInFromUriLiteral(instance, "duration'PT1S\""); + } + + @Test + public void valueToString() throws Exception { + assertEquals("PT10S", instance.valueToString(BigDecimal.TEN, null, null, null, null, null)); + assertEquals("-PT10S", instance.valueToString(BigDecimal.TEN.negate(), null, null, null, null, null)); + assertEquals("PT10S", instance.valueToString(BigDecimal.TEN, null, null, null, null, null)); + assertEquals("PT10S", instance.valueToString(BigDecimal.TEN, null, null, 0, null, null)); + assertEquals("-PT0.01S", instance.valueToString(BigDecimal.ONE.movePointLeft(2).negate(), null, null, 2, null, + null)); + assertEquals("PT2M3S", instance.valueToString(123, null, null, null, null, null)); + assertEquals("PT2M3S", instance.valueToString((byte) 123, null, null, null, null, null)); + assertEquals("PT3H25M45S", instance.valueToString((short) 12345, null, null, null, null, null)); + assertEquals("P14288DT23H31M30S", instance.valueToString(1234567890L, null, null, null, null, null)); + assertEquals("P50903316DT2H25M4S", instance.valueToString(BigInteger.ONE.shiftLeft(42), null, null, null, null, + null)); + + expectFacetsErrorInValueToString(instance, BigDecimal.ONE.movePointLeft(1), null, null, null, null, null); + expectFacetsErrorInValueToString(instance, BigDecimal.ONE.movePointLeft(1), null, null, 0, null, null); + + expectTypeErrorInValueToString(instance, ""); + } + + @Test + public void valueOfString() throws Exception { + assertEquals(BigDecimal.TEN, instance.valueOfString("PT10S", null, null, null, null, null, BigDecimal.class)); + assertEquals(BigDecimal.TEN.negate(), instance.valueOfString("-PT10S", null, null, null, null, null, + BigDecimal.class)); + assertEquals(BigDecimal.TEN, instance.valueOfString("PT10S", null, null, null, null, null, BigDecimal.class)); + assertEquals(BigDecimal.ONE.movePointLeft(1), instance.valueOfString("PT0.1S", null, null, 1, null, null, + BigDecimal.class)); + assertEquals(Byte.valueOf((byte) 123), instance.valueOfString("PT2M3S", null, null, null, null, null, Byte.class)); + assertEquals(Short.valueOf((short) 123), instance.valueOfString("PT2M3S", null, null, null, null, null, + Short.class)); + assertEquals(Integer.valueOf(12345), instance.valueOfString("PT3H25M45S", null, null, null, null, null, + Integer.class)); + assertEquals(Long.valueOf(1234567890L), instance.valueOfString("P14288DT23H31M30S", null, null, null, null, null, + Long.class)); + assertEquals(BigInteger.ONE.shiftLeft(42), instance.valueOfString("P50903316DT2H25M4S", null, null, null, null, + null, BigInteger.class)); + + expectFacetsErrorInValueOfString(instance, "PT1.1S", null, null, null, null, null); + expectFacetsErrorInValueOfString(instance, "PT1H2M3.123S", null, null, 2, null, null); + expectFacetsErrorInValueOfString(instance, "PT13H2M3.9S", null, null, 0, null, null); + + expectContentErrorInValueOfString(instance, "PT1H2M3S.1234"); + expectContentErrorInValueOfString(instance, "P2012Y2M29DT23H32M2S"); + expectContentErrorInValueOfString(instance, "PT-1H"); + expectContentErrorInValueOfString(instance, "PT"); + + expectUnconvertibleErrorInValueOfString(instance, "-PT2M9S", Byte.class); + expectUnconvertibleErrorInValueOfString(instance, "PT2M8S", Byte.class); + expectUnconvertibleErrorInValueOfString(instance, "PT10H", Short.class); + expectUnconvertibleErrorInValueOfString(instance, "P25000D", Integer.class); + expectUnconvertibleErrorInValueOfString(instance, "P123456789012345D", Long.class); + // expectUnconvertibleErrorInValueOfString(instance, "PT1.1S", BigInteger.class); + + expectTypeErrorInValueOfString(instance, "PT0S"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmEnumTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmEnumTest.java new file mode 100644 index 000000000..c796934ee --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmEnumTest.java @@ -0,0 +1,144 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Arrays; + +import org.apache.olingo.commons.api.edm.EdmEnumType; +import org.apache.olingo.commons.api.edm.EdmMember; +import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; +import org.junit.Test; + +public class EdmEnumTest extends PrimitiveTypeBaseTest { + + private final EdmEnumType instance; + + public EdmEnumTest() { + EdmMember member1 = mock(EdmMember.class); + when(member1.getName()).thenReturn("first"); + when(member1.getValue()).thenReturn("1"); + EdmMember member2 = mock(EdmMember.class); + when(member2.getName()).thenReturn("second"); + when(member2.getValue()).thenReturn("64"); + instance = new EdmEnum("namespace", "name", + EdmPrimitiveTypeKind.SByte.getEdmPrimitiveTypeInstance(), + Arrays.asList(member1, member2), + true); + } + + @Test + public void nameSpace() throws Exception { + assertEquals("namespace", instance.getNamespace()); + } + + @Test + public void name() throws Exception { + assertEquals("name", instance.getName()); + } + + @Test + public void kind() throws Exception { + assertEquals(EdmTypeKind.ENUM, instance.getKind()); + } + + @Test + public void compatibility() { + assertTrue(instance.isCompatible(instance)); + assertFalse(instance.isCompatible(instance.getUnderlyingType())); + } + + @Test + public void defaultType() throws Exception { + assertEquals(Byte.class, instance.getDefaultType()); + } + + @Test + public void members() throws Exception { + assertArrayEquals(new String[] { "first", "second" }, instance.getMemberNames().toArray()); + assertEquals("64", instance.getMember("second").getValue()); + assertNull(instance.getMember("notExisting")); + } + + @Test + public void underlyingType() throws Exception { + assertEquals(EdmPrimitiveTypeKind.SByte.getEdmPrimitiveTypeInstance(), instance.getUnderlyingType()); + } + + @Test + public void validate() throws Exception { + assertTrue(instance.validate(null, null, null, null, null, null)); + assertTrue(instance.validate(null, true, null, null, null, null)); + assertFalse(instance.validate(null, false, null, null, null, null)); + assertFalse(instance.validate("", null, null, null, null, null)); + assertFalse(instance.validate("something", null, null, null, null, null)); + + assertTrue(instance.validate("second", null, null, null, null, null)); + assertTrue(instance.validate("first,second", null, null, null, null, null)); + assertTrue(instance.validate("64", null, null, null, null, null)); + assertTrue(instance.validate("1,64", null, null, null, null, null)); + } + + @Test + public void toUriLiteral() throws Exception { + assertNull(instance.toUriLiteral(null)); + assertEquals("namespace.name'first'", instance.toUriLiteral("first")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertNull(instance.fromUriLiteral(null)); + assertEquals("first", instance.fromUriLiteral("namespace.name'first'")); + + expectErrorInFromUriLiteral(instance, ""); + expectErrorInFromUriLiteral(instance, "name'first'"); + expectErrorInFromUriLiteral(instance, "namespace.name'first"); + expectErrorInFromUriLiteral(instance, "namespace.namespace'first"); + } + + @Test + public void valueToString() throws Exception { + assertNull(instance.valueToString(null, null, null, null, null, null)); + assertNull(instance.valueToString(null, true, null, null, null, null)); + assertEquals("first", instance.valueToString(1, null, null, null, null, null)); + assertEquals("first", instance.valueToString((byte) 1, null, null, null, null, null)); + assertEquals("first", instance.valueToString((short) 1, null, null, null, null, null)); + assertEquals("second", instance.valueToString(Integer.valueOf(64), null, null, null, null, null)); + assertEquals("second", instance.valueToString(64L, null, null, null, null, null)); + assertEquals("first,second", instance.valueToString(65, null, null, null, null, null)); + + expectNullErrorInValueToString(instance); + expectContentErrorInValueToString(instance, 3); + expectTypeErrorInValueToString(instance, 1.0); + } + + @Test + public void valueOfString() throws Exception { + assertNull(instance.valueOfString(null, null, null, null, null, null, Byte.class)); + assertNull(instance.valueOfString(null, true, null, null, null, null, Byte.class)); + assertEquals(Short.valueOf((short) 1), instance.valueOfString("1", null, null, null, null, null, Short.class)); + assertEquals(Integer.valueOf(1), instance.valueOfString("1", null, null, null, null, null, Integer.class)); + assertEquals(Long.valueOf(64L), instance.valueOfString("64", null, null, null, null, null, Long.class)); + assertEquals(Long.valueOf(1), instance.valueOfString("first", null, null, null, null, null, Long.class)); + assertEquals(Byte.valueOf((byte) 65), instance.valueOfString("first,64", null, null, null, null, null, Byte.class)); + assertEquals(Integer.valueOf(1), instance.valueOfString("1,1,first", null, null, null, null, null, Integer.class)); + + final EdmEnumType nonFlagsInstance = new EdmEnum("namespace", "name", + instance.getUnderlyingType(), + Arrays.asList(instance.getMember("first"), instance.getMember("second")), + false); + assertEquals(Integer.valueOf(1), nonFlagsInstance.valueOfString("1", null, null, null, null, null, Integer.class)); + expectContentErrorInValueOfString(nonFlagsInstance, "1,64"); + + expectNullErrorInValueOfString(instance); + expectContentErrorInValueOfString(instance, "2"); + expectContentErrorInValueOfString(instance, "1,"); + expectContentErrorInValueOfString(instance, ",1"); + expectTypeErrorInValueOfString(instance, "1"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmGuidTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmGuidTest.java new file mode 100644 index 000000000..088f8a8ab --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmGuidTest.java @@ -0,0 +1,49 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; + +import java.util.UUID; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmGuidTest extends PrimitiveTypeBaseTest { + + private final EdmPrimitiveType instance = EdmPrimitiveTypeKind.Guid.getEdmPrimitiveTypeInstance(); + + @Test + public void toUriLiteral() { + assertEquals("aabbccdd-aabb-ccdd-eeff-aabbccddeeff", + instance.toUriLiteral("aabbccdd-aabb-ccdd-eeff-aabbccddeeff")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertEquals("aabbccdd-aabb-ccdd-eeff-aabbccddeeff", + instance.fromUriLiteral("aabbccdd-aabb-ccdd-eeff-aabbccddeeff")); + } + + @Test + public void valueToString() throws Exception { + final UUID uuid = UUID.randomUUID(); + assertEquals(uuid.toString(), instance.valueToString(uuid, null, null, null, null, null)); + + expectTypeErrorInValueToString(instance, 'A'); + } + + @Test + public void valueOfString() throws Exception { + final UUID uuid = UUID.fromString("aabbccdd-aabb-ccdd-eeff-aabbccddeeff"); + + assertEquals(uuid, instance.valueOfString("aabbccdd-aabb-ccdd-eeff-aabbccddeeff", null, null, null, null, null, + UUID.class)); + assertEquals(uuid, instance.valueOfString("AABBCCDD-AABB-CCDD-EEFF-AABBCCDDEEFF", null, null, null, null, null, + UUID.class)); + assertEquals(uuid, instance.valueOfString("AABBCCDD-aabb-ccdd-eeff-AABBCCDDEEFF", null, null, null, null, null, + UUID.class)); + + expectContentErrorInValueOfString(instance, "AABBCCDDAABBCCDDEEFFAABBCCDDEEFF"); + + expectTypeErrorInValueOfString(instance, uuid.toString()); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt16Test.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt16Test.java new file mode 100644 index 000000000..3ac12c68a --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt16Test.java @@ -0,0 +1,68 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.math.BigInteger; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmInt16Test extends PrimitiveTypeBaseTest { + + final EdmPrimitiveType instance = EdmPrimitiveTypeKind.Int16.getEdmPrimitiveTypeInstance(); + + @Test + public void testInt16Compatibility() { + assertTrue(instance.isCompatible(Uint7.getInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Byte.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.SByte.getEdmPrimitiveTypeInstance())); + } + + @Test + public void toUriLiteral() throws Exception { + assertEquals("127", instance.toUriLiteral("127")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertEquals("127", instance.fromUriLiteral("127")); + } + + @Test + public void valueToString() throws Exception { + assertEquals("0", instance.valueToString(0, null, null, null, null, null)); + assertEquals("8", instance.valueToString((byte) 8, null, null, null, null, null)); + assertEquals("16", instance.valueToString((short) 16, null, null, null, null, null)); + assertEquals("32", instance.valueToString(Integer.valueOf(32), null, null, null, null, null)); + assertEquals("255", instance.valueToString(255L, null, null, null, null, null)); + assertEquals("-32768", instance.valueToString(BigInteger.valueOf(Short.MIN_VALUE), null, null, null, null, null)); + + expectContentErrorInValueToString(instance, 123456); + expectContentErrorInValueToString(instance, -32769); + expectContentErrorInValueToString(instance, BigInteger.valueOf(32768)); + + expectTypeErrorInValueToString(instance, 1.0); + } + + @Test + public void valueOfString() throws Exception { + assertEquals(Byte.valueOf((byte) 1), instance.valueOfString("1", null, null, null, null, null, Byte.class)); + assertEquals(Short.valueOf((short) 2), instance.valueOfString("2", null, null, null, null, null, Short.class)); + assertEquals(Short.valueOf((short) -32768), instance.valueOfString("-32768", null, null, null, null, null, + Short.class)); + assertEquals(Short.valueOf((short) 32767), instance.valueOfString("32767", null, null, null, null, null, + Short.class)); + assertEquals(Integer.valueOf(0), instance.valueOfString("0", null, null, null, null, null, Integer.class)); + assertEquals(Long.valueOf(-1), instance.valueOfString("-1", null, null, null, null, null, Long.class)); + assertEquals(BigInteger.TEN, instance.valueOfString("10", null, null, null, null, null, BigInteger.class)); + + expectContentErrorInValueOfString(instance, "32768"); + expectContentErrorInValueOfString(instance, "1.0"); + + expectUnconvertibleErrorInValueOfString(instance, "-129", Byte.class); + expectUnconvertibleErrorInValueOfString(instance, "128", Byte.class); + + expectTypeErrorInValueOfString(instance, "1"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt32Test.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt32Test.java new file mode 100644 index 000000000..c29202f03 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt32Test.java @@ -0,0 +1,69 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.math.BigInteger; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmInt32Test extends PrimitiveTypeBaseTest { + + private final EdmPrimitiveType instance = EdmPrimitiveTypeKind.Int32.getEdmPrimitiveTypeInstance(); + + @Test + public void compatibility() { + assertTrue(instance.isCompatible(Uint7.getInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Byte.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.SByte.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Int16.getEdmPrimitiveTypeInstance())); + } + + @Test + public void toUriLiteral() throws Exception { + assertEquals("127", instance.toUriLiteral("127")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertEquals("127", instance.fromUriLiteral("127")); + } + + @Test + public void valueToString() throws Exception { + assertEquals("0", instance.valueToString(0, null, null, null, null, null)); + assertEquals("8", instance.valueToString((byte) 8, null, null, null, null, null)); + assertEquals("16", instance.valueToString((short) 16, null, null, null, null, null)); + assertEquals("32", instance.valueToString(Integer.valueOf(32), null, null, null, null, null)); + assertEquals("255", instance.valueToString(255L, null, null, null, null, null)); + assertEquals("-2147483648", instance.valueToString(BigInteger.valueOf(Integer.MIN_VALUE), null, null, null, null, + null)); + + expectContentErrorInValueToString(instance, 12345678901L); + expectContentErrorInValueToString(instance, -2147483649L); + expectContentErrorInValueToString(instance, BigInteger.valueOf(2147483648L)); + + expectTypeErrorInValueToString(instance, 1.0); + } + + @Test + public void valueOfString() throws Exception { + assertEquals(Byte.valueOf((byte) 1), instance.valueOfString("1", null, null, null, null, null, Byte.class)); + assertEquals(Short.valueOf((short) 2), instance.valueOfString("2", null, null, null, null, null, Short.class)); + assertEquals(Integer.valueOf(-10000000), instance.valueOfString("-10000000", null, null, null, null, null, + Integer.class)); + assertEquals(Long.valueOf(10000000), instance.valueOfString("10000000", null, null, null, null, null, Long.class)); + assertEquals(BigInteger.TEN, instance.valueOfString("10", null, null, null, null, null, BigInteger.class)); + + expectContentErrorInValueOfString(instance, "-2147483649"); + expectContentErrorInValueOfString(instance, "1.0"); + + expectUnconvertibleErrorInValueOfString(instance, "-129", Byte.class); + expectUnconvertibleErrorInValueOfString(instance, "128", Byte.class); + expectUnconvertibleErrorInValueOfString(instance, "-32769", Short.class); + expectUnconvertibleErrorInValueOfString(instance, "32768", Short.class); + + expectTypeErrorInValueOfString(instance, "1"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt64Test.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt64Test.java new file mode 100644 index 000000000..5ef9de3b2 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmInt64Test.java @@ -0,0 +1,76 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.math.BigInteger; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmInt64Test extends PrimitiveTypeBaseTest { + + private final EdmPrimitiveType instance = EdmPrimitiveTypeKind.Int64.getEdmPrimitiveTypeInstance(); + + @Test + public void compatibility() { + assertTrue(instance.isCompatible(Uint7.getInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Byte.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.SByte.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Int16.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Int32.getEdmPrimitiveTypeInstance())); + } + + @Test + public void toUriLiteral() throws Exception { + assertEquals("127", instance.toUriLiteral("127")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertEquals("127", instance.fromUriLiteral("127")); + } + + @Test + public void valueToString() throws Exception { + assertEquals("0", instance.valueToString(0, null, null, null, null, null)); + assertEquals("8", instance.valueToString((byte) 8, null, null, null, null, null)); + assertEquals("16", instance.valueToString((short) 16, null, null, null, null, null)); + assertEquals("32", instance.valueToString(Integer.valueOf(32), null, null, null, null, null)); + assertEquals("255", instance.valueToString(255L, null, null, null, null, null)); + assertEquals("12345678901", instance.valueToString(12345678901L, null, null, null, null, null)); + assertEquals("1234567890123456789", instance.valueToString(new BigInteger("1234567890123456789"), null, null, null, + null, null)); + assertEquals("-1234567890123456789", instance.valueToString(new BigInteger("-1234567890123456789"), null, null, + null, null, null)); + + expectContentErrorInValueToString(instance, new BigInteger("123456789012345678901")); + + expectTypeErrorInValueToString(instance, 1.0); + } + + @Test + public void valueOfString() throws Exception { + assertEquals(Short.valueOf((short) 1), instance.valueOfString("1", null, null, null, null, null, Short.class)); + assertEquals(Integer.valueOf(2), instance.valueOfString("2", null, null, null, null, null, Integer.class)); + assertEquals(Long.valueOf(-1234567890123456789L), instance.valueOfString("-1234567890123456789", null, null, null, + null, null, Long.class)); + assertEquals(BigInteger.ONE, instance.valueOfString("1", null, null, null, null, null, BigInteger.class)); + assertEquals(Long.valueOf(0), instance.valueOfString("0", null, null, null, null, null, Long.class)); + assertEquals(Byte.valueOf((byte) 0), instance.valueOfString("0", null, null, null, null, null, Byte.class)); + + expectContentErrorInValueOfString(instance, "-12345678901234567890"); + expectContentErrorInValueOfString(instance, "1.0"); + expectContentErrorInValueOfString(instance, "0L"); + expectContentErrorInValueOfString(instance, "0x42"); + + expectUnconvertibleErrorInValueOfString(instance, "-129", Byte.class); + expectUnconvertibleErrorInValueOfString(instance, "128", Byte.class); + expectUnconvertibleErrorInValueOfString(instance, "-32769", Short.class); + expectUnconvertibleErrorInValueOfString(instance, "32768", Short.class); + expectUnconvertibleErrorInValueOfString(instance, "-2147483649", Integer.class); + expectUnconvertibleErrorInValueOfString(instance, "2147483648", Integer.class); + + expectTypeErrorInValueOfString(instance, "1"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmNullTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmNullTest.java new file mode 100644 index 000000000..a1d964b3b --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmNullTest.java @@ -0,0 +1,31 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertNull; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmNullTest extends PrimitiveTypeBaseTest { + + @Test + public void checkNull() throws Exception { + for (EdmPrimitiveTypeKind kind : EdmPrimitiveTypeKind.values()) { + final EdmPrimitiveType instance = kind.getEdmPrimitiveTypeInstance(); + assertNull(instance.valueToString(null, null, null, null, null, null)); + assertNull(instance.valueToString(null, true, null, null, null, null)); + + expectNullErrorInValueToString(instance); + } + } + + @Test + public void checkValueOfNull() throws Exception { + for (EdmPrimitiveTypeKind kind : EdmPrimitiveTypeKind.values()) { + final EdmPrimitiveType instance = kind.getEdmPrimitiveTypeInstance(); + assertNull(instance.valueOfString(null, null, null, null, null, null, instance.getDefaultType())); + assertNull(instance.valueOfString(null, true, null, null, null, null, instance.getDefaultType())); + + expectNullErrorInValueOfString(instance); + } + } +} \ No newline at end of file diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmSByteTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmSByteTest.java new file mode 100644 index 000000000..fa9f0a730 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmSByteTest.java @@ -0,0 +1,62 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.math.BigInteger; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmSByteTest extends PrimitiveTypeBaseTest { + + private final EdmPrimitiveType instance = EdmPrimitiveTypeKind.SByte.getEdmPrimitiveTypeInstance(); + + @Test + public void compatibility() { + assertTrue(instance.isCompatible(Uint7.getInstance())); + } + + @Test + public void toUriLiteral() throws Exception { + assertEquals("127", instance.toUriLiteral("127")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertEquals("127", instance.fromUriLiteral("127")); + } + + @Test + public void valueToString() throws Exception { + assertEquals("0", instance.valueToString(0, null, null, null, null, null)); + assertEquals("8", instance.valueToString((byte) 8, null, null, null, null, null)); + assertEquals("16", instance.valueToString((short) 16, null, null, null, null, null)); + assertEquals("32", instance.valueToString(Integer.valueOf(32), null, null, null, null, null)); + assertEquals("64", instance.valueToString(64L, null, null, null, null, null)); + assertEquals("-128", instance.valueToString(BigInteger.valueOf(Byte.MIN_VALUE), null, null, null, null, null)); + + expectContentErrorInValueToString(instance, -129); + expectContentErrorInValueToString(instance, 128); + expectContentErrorInValueToString(instance, BigInteger.valueOf(128)); + + expectTypeErrorInValueToString(instance, 'A'); + } + + @Test + public void valueOfString() throws Exception { + assertEquals(Byte.valueOf((byte) 1), instance.valueOfString("1", null, null, null, null, null, Byte.class)); + assertEquals(Short.valueOf((short) -2), instance.valueOfString("-2", null, null, null, null, null, Short.class)); + assertEquals(Byte.valueOf((byte) 127), instance.valueOfString("127", null, null, null, null, null, Byte.class)); + assertEquals(Byte.valueOf((byte) -128), instance.valueOfString("-128", null, null, null, null, null, Byte.class)); + assertEquals(Integer.valueOf(0), instance.valueOfString("0", null, null, null, null, null, Integer.class)); + assertEquals(Long.valueOf(0), instance.valueOfString("0", null, null, null, null, null, Long.class)); + assertEquals(BigInteger.TEN, instance.valueOfString("10", null, null, null, null, null, BigInteger.class)); + + expectContentErrorInValueOfString(instance, "128"); + expectContentErrorInValueOfString(instance, "-129"); + expectContentErrorInValueOfString(instance, "1.0"); + + expectTypeErrorInValueOfString(instance, "1"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmSingleTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmSingleTest.java new file mode 100644 index 000000000..03bd5dd78 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmSingleTest.java @@ -0,0 +1,118 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmSingleTest extends PrimitiveTypeBaseTest { + + private final EdmPrimitiveType instance = EdmPrimitiveTypeKind.Single.getEdmPrimitiveTypeInstance(); + + @Test + public void compatibility() { + assertTrue(instance.isCompatible(Uint7.getInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Byte.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.SByte.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Int16.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Int32.getEdmPrimitiveTypeInstance())); + assertTrue(instance.isCompatible(EdmPrimitiveTypeKind.Int64.getEdmPrimitiveTypeInstance())); + } + + @Test + public void toUriLiteral() throws Exception { + assertEquals("127", instance.toUriLiteral("127")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertEquals("127", instance.fromUriLiteral("127")); + } + + @Test + public void valueToString() throws Exception { + assertEquals("0", instance.valueToString(0, null, null, null, null, null)); + assertEquals("8", instance.valueToString((byte) 8, null, null, null, null, null)); + assertEquals("16", instance.valueToString((short) 16, null, null, null, null, null)); + assertEquals("32", instance.valueToString(Integer.valueOf(32), null, null, null, null, null)); + assertEquals("255", instance.valueToString(255L, null, null, null, null, null)); + assertEquals("0.00390625", instance.valueToString(1.0 / 256, null, null, null, null, null)); + assertEquals("4.2E-8", instance.valueToString(42e-9, null, null, null, null, null)); + assertEquals("INF", instance.valueToString(Double.POSITIVE_INFINITY, null, null, null, null, null)); + assertEquals("-INF", instance.valueToString(Double.NEGATIVE_INFINITY, null, null, null, null, null)); + assertEquals("NaN", instance.valueToString(Double.NaN, null, null, null, null, null)); + assertEquals("-0.125", instance.valueToString(-0.125f, null, null, null, null, null)); + assertEquals("INF", instance.valueToString(Float.POSITIVE_INFINITY, null, null, null, null, null)); + assertEquals("-INF", instance.valueToString(Float.NEGATIVE_INFINITY, null, null, null, null, null)); + assertEquals("NaN", instance.valueToString(Float.NaN, null, null, null, null, null)); + assertEquals("-123456.75", instance.valueToString(new BigDecimal("-123456.75"), null, null, null, null, null)); + + expectContentErrorInValueToString(instance, 12345678L); + expectContentErrorInValueToString(instance, new BigDecimal("123456789")); + expectContentErrorInValueToString(instance, new BigDecimal(BigInteger.ONE, -39)); + expectContentErrorInValueToString(instance, 42e38); + expectContentErrorInValueToString(instance, 12345.6789); + expectContentErrorInValueToString(instance, 1E-50); + + expectTypeErrorInValueToString(instance, 'A'); + } + + @Test + public void valueOfString() throws Exception { + assertEquals(Float.valueOf(1.42F), instance.valueOfString("1.42", null, null, null, null, null, Float.class)); + assertEquals(Double.valueOf(-42.42), instance.valueOfString("-42.42", null, null, null, null, null, Double.class)); + assertEquals(Float.valueOf(42.0F), instance.valueOfString("42", null, null, null, null, null, Float.class)); + assertEquals(Float.valueOf(2.2E38F), instance.valueOfString("22E37", null, null, null, null, null, Float.class)); + assertEquals(Float.valueOf(1.23E-38F), instance.valueOfString("12.3E-39", null, null, null, null, null, + Float.class)); + assertEquals(BigDecimal.TEN, instance.valueOfString("10", null, null, null, null, null, BigDecimal.class)); + assertEquals(Byte.valueOf((byte) 0), instance.valueOfString("0", null, null, null, null, null, Byte.class)); + assertEquals(Short.valueOf((short) 1), instance.valueOfString("1.00", null, null, null, null, null, Short.class)); + assertEquals(Integer.valueOf(42), instance.valueOfString("4.2E1", null, null, null, null, null, Integer.class)); + assertEquals(Long.valueOf(12345678), instance.valueOfString("12345.678E+03", null, null, null, null, null, + Long.class)); + + assertEquals(Float.valueOf(Float.NaN), instance.valueOfString("NaN", null, null, null, null, null, Float.class)); + assertEquals(Float.valueOf(Float.NEGATIVE_INFINITY), instance.valueOfString("-INF", null, null, null, null, null, + Float.class)); + assertEquals(Float.valueOf(Float.POSITIVE_INFINITY), instance.valueOfString("INF", null, null, null, null, null, + Float.class)); + assertEquals(Double.valueOf(Double.NaN), instance.valueOfString("NaN", null, null, null, null, null, + Double.class)); + assertEquals(Double.valueOf(Double.NEGATIVE_INFINITY), instance.valueOfString("-INF", null, null, null, null, null, + Double.class)); + + expectContentErrorInValueOfString(instance, "0."); + expectContentErrorInValueOfString(instance, ".0"); + expectContentErrorInValueOfString(instance, "1E-50"); + expectContentErrorInValueOfString(instance, "12345.6789"); + expectContentErrorInValueOfString(instance, "42E42"); + expectContentErrorInValueOfString(instance, "42.42.42"); + expectContentErrorInValueOfString(instance, "42.42.42"); + expectContentErrorInValueOfString(instance, "42D"); + expectContentErrorInValueOfString(instance, "0x42P4"); + + expectUnconvertibleErrorInValueOfString(instance, "INF", BigDecimal.class); + expectUnconvertibleErrorInValueOfString(instance, "NaN", BigDecimal.class); + expectUnconvertibleErrorInValueOfString(instance, "-INF", Integer.class); + expectUnconvertibleErrorInValueOfString(instance, "NaN", Integer.class); + expectUnconvertibleErrorInValueOfString(instance, "5E-1", Byte.class); + expectUnconvertibleErrorInValueOfString(instance, "5E-1", Short.class); + expectUnconvertibleErrorInValueOfString(instance, "5E-1", Integer.class); + expectUnconvertibleErrorInValueOfString(instance, "5E-1", Long.class); + expectUnconvertibleErrorInValueOfString(instance, "-129", Byte.class); + expectUnconvertibleErrorInValueOfString(instance, "128", Byte.class); + expectUnconvertibleErrorInValueOfString(instance, "-32769", Short.class); + expectUnconvertibleErrorInValueOfString(instance, "32768", Short.class); + expectUnconvertibleErrorInValueOfString(instance, "-2147483.65E3", Integer.class); + expectUnconvertibleErrorInValueOfString(instance, "2147483.65E3", Integer.class); + expectUnconvertibleErrorInValueOfString(instance, "-1E19", Long.class); + expectUnconvertibleErrorInValueOfString(instance, "1E19", Long.class); + + expectTypeErrorInValueOfString(instance, "1.42"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmStringTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmStringTest.java new file mode 100644 index 000000000..5c35c3b48 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmStringTest.java @@ -0,0 +1,59 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmStringTest extends PrimitiveTypeBaseTest { + + private final EdmPrimitiveType instance = EdmPrimitiveTypeKind.String.getEdmPrimitiveTypeInstance(); + + @Test + public void toUriLiteral() throws Exception { + assertEquals("'StringValue'", instance.toUriLiteral("StringValue")); + assertEquals("'String''Value'", instance.toUriLiteral("String'Value")); + assertEquals("'String''''''Value'", instance.toUriLiteral("String'''Value")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertEquals("String''Value", instance.fromUriLiteral("'String''''Value'")); + + expectErrorInFromUriLiteral(instance, ""); + expectErrorInFromUriLiteral(instance, "'"); + expectErrorInFromUriLiteral(instance, "'\""); + } + + @Test + public void valueToString() throws Exception { + assertEquals("text", instance.valueToString("text", null, null, null, null, null)); + assertEquals("a\nb", instance.valueToString("a\nb", null, null, null, null, null)); + assertEquals("true", instance.valueToString(true, null, null, null, null, null)); + assertEquals("a'b", instance.valueToString("a'b", null, null, null, null, null)); + + assertEquals("text", instance.valueToString("text", null, null, null, null, true)); + assertEquals("text", instance.valueToString("text", null, 4, null, null, null)); + assertEquals("text", instance.valueToString("text", null, Integer.MAX_VALUE, null, null, null)); + + expectFacetsErrorInValueToString(instance, "schräg", null, null, null, null, false); + expectFacetsErrorInValueToString(instance, "text", null, 3, null, null, null); + } + + @Test + public void valueOfString() throws Exception { + assertEquals("text", instance.valueOfString("text", null, null, null, null, null, String.class)); + assertEquals("a\nb", instance.valueOfString("a\nb", null, null, null, null, null, String.class)); + assertEquals("true", instance.valueOfString("true", null, null, null, null, null, String.class)); + assertEquals("'a''b'", instance.valueOfString("'a''b'", null, null, null, null, null, String.class)); + + assertEquals("text", instance.valueOfString("text", null, null, null, null, true, String.class)); + assertEquals("text", instance.valueOfString("text", null, 4, null, null, null, String.class)); + assertEquals("text", instance.valueOfString("text", null, Integer.MAX_VALUE, null, null, null, String.class)); + + expectFacetsErrorInValueOfString(instance, "schräg", null, null, null, null, false); + expectFacetsErrorInValueOfString(instance, "text", null, 3, null, null, null); + + expectTypeErrorInValueOfString(instance, "text"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDayTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDayTest.java new file mode 100644 index 000000000..ba5706cb1 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDayTest.java @@ -0,0 +1,74 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertEquals; + +import java.util.Calendar; +import java.util.TimeZone; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.junit.Test; + +public class EdmTimeOfDayTest extends PrimitiveTypeBaseTest { + + private final EdmPrimitiveType instance = EdmPrimitiveTypeKind.TimeOfDay.getEdmPrimitiveTypeInstance(); + + @Test + public void toUriLiteral() throws Exception { + assertEquals("11:12", instance.toUriLiteral("11:12")); + assertEquals("11:12:13.012", instance.toUriLiteral("11:12:13.012")); + } + + @Test + public void fromUriLiteral() throws Exception { + assertEquals("11:12", instance.fromUriLiteral("11:12")); + assertEquals("11:12:13.012", instance.fromUriLiteral("11:12:13.012")); + } + + @Test + public void valueToString() throws Exception { + Calendar dateTime = Calendar.getInstance(); + dateTime.clear(); + dateTime.setTimeZone(TimeZone.getTimeZone("GMT+11:30")); + dateTime.set(1, 2, 3, 4, 5, 6); + assertEquals("04:05:06", instance.valueToString(dateTime, null, null, null, null, null)); + + dateTime.add(Calendar.MILLISECOND, 42); + assertEquals("04:05:06.042", instance.valueToString(dateTime, null, null, 3, null, null)); + assertEquals("04:05:06.042", instance.valueToString(dateTime, null, null, 4, null, null)); + + expectFacetsErrorInValueToString(instance, dateTime, null, null, null, null, null); + expectFacetsErrorInValueToString(instance, dateTime, null, null, 2, null, null); + + expectTypeErrorInValueToString(instance, 0); + } + + @Test + public void valueOfString() throws Exception { + Calendar dateTime = Calendar.getInstance(); + dateTime.clear(); + dateTime.setTimeZone(TimeZone.getTimeZone("GMT")); + + assertEquals(dateTime, instance.valueOfString("00:00", null, null, null, null, null, Calendar.class)); + assertEquals(dateTime, instance.valueOfString("00:00:00", null, null, null, null, null, Calendar.class)); + assertEquals(dateTime, instance.valueOfString("00:00:00.000000000000", null, null, null, null, null, + Calendar.class)); + + dateTime.set(Calendar.MILLISECOND, 999); + assertEquals(dateTime, instance.valueOfString("00:00:00.999", null, null, 3, null, null, Calendar.class)); + assertEquals(dateTime, instance.valueOfString("00:00:00.999", null, null, 3, null, null, Calendar.class)); + + expectFacetsErrorInValueOfString(instance, "11:12:13.123", null, null, null, null, null); + expectFacetsErrorInValueOfString(instance, "11:12:13.123", null, null, 2, null, null); + + expectContentErrorInValueOfString(instance, "24:32:02"); + expectContentErrorInValueOfString(instance, "011:12:13"); + expectContentErrorInValueOfString(instance, "11:12:13:14"); + expectContentErrorInValueOfString(instance, "111213"); + expectContentErrorInValueOfString(instance, "1:2:3"); + expectContentErrorInValueOfString(instance, "11:12:13.0.1"); + expectContentErrorInValueOfString(instance, "11:12:13."); + expectContentErrorInValueOfString(instance, "11:12:13.0000000000000"); + + expectTypeErrorInValueOfString(instance, "11:12:13"); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/PrimitiveTypeBaseTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/PrimitiveTypeBaseTest.java new file mode 100644 index 000000000..3976b1ba9 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/PrimitiveTypeBaseTest.java @@ -0,0 +1,109 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; + +public abstract class PrimitiveTypeBaseTest { + + private void expectErrorInValueToString(final EdmPrimitiveType instance, + final Object value, final Boolean isNullable, final Integer maxLength, + final Integer precision, final Integer scale, final Boolean isUnicode, + final String messageReferenceString) { + try { + instance.valueToString(value, isNullable, maxLength, precision, scale, isUnicode); + fail("Expected exception not thrown"); + } catch (final EdmPrimitiveTypeException e) { + // TODO: How to test without message reference + // assertNotNull(e.getMessageReference()); + // assertEquals(messageReference.getKey(), e.getMessageReference().getKey()); + assertNotNull(e.getLocalizedMessage()); + assertTrue(e.getLocalizedMessage().startsWith(messageReferenceString)); + } + } + + private void expectErrorInValueToString(final EdmPrimitiveType instance, final Object value, + final String messageReference) { + expectErrorInValueToString(instance, value, null, null, null, null, null, messageReference); + } + + protected void expectTypeErrorInValueToString(final EdmPrimitiveType instance, final Object value) { + expectErrorInValueToString(instance, value, "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED"); + } + + protected void expectContentErrorInValueToString(final EdmPrimitiveType instance, final Object value) { + expectErrorInValueToString(instance, value, "EdmPrimitiveTypeException.VALUE_ILLEGAL_CONTENT"); + } + + protected void expectFacetsErrorInValueToString(final EdmPrimitiveType instance, final Object value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode) { + expectErrorInValueToString(instance, value, isNullable, maxLength, precision, scale, isUnicode, + "EdmPrimitiveTypeException.VALUE_FACETS_NOT_MATCHED"); + } + + protected void expectNullErrorInValueToString(final EdmPrimitiveType instance) { + expectErrorInValueToString(instance, null, false, null, null, null, null, + "EdmPrimitiveTypeException.VALUE_NULL_NOT_ALLOWED"); + } + + private void expectErrorInValueOfString(final EdmPrimitiveType instance, + final String value, final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode, final Class returnType, final String messageReferenceString) { + try { + instance.valueOfString(value, isNullable, maxLength, precision, scale, isUnicode, returnType); + fail("Expected exception not thrown"); + } catch (final EdmPrimitiveTypeException e) { + // TODO: How to test without message reference + // assertNotNull(e.getMessageReference()); + // assertEquals(messageReference.getKey(), e.getMessageReference().getKey()); + assertNotNull(e.getLocalizedMessage()); + assertTrue(e.getLocalizedMessage().startsWith(messageReferenceString)); + } + } + + protected void expectTypeErrorInValueOfString(final EdmPrimitiveType instance, final String value) { + expectErrorInValueOfString(instance, value, null, null, null, null, null, Class.class, + "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED"); + } + + protected void expectUnconvertibleErrorInValueOfString(final EdmPrimitiveType instance, final String value, + final Class type) { + expectErrorInValueOfString(instance, value, null, null, null, null, null, type, + "EdmPrimitiveTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE"); + } + + protected void expectContentErrorInValueOfString(final EdmPrimitiveType instance, final String value) { + expectErrorInValueOfString(instance, value, null, null, null, null, null, instance.getDefaultType(), + "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT"); + } + + protected void expectFacetsErrorInValueOfString(final EdmPrimitiveType instance, final String value, + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode) { + expectErrorInValueOfString(instance, value, isNullable, maxLength, precision, scale, isUnicode, + instance.getDefaultType(), "EdmPrimitiveTypeException.LITERAL_FACETS_NOT_MATCHED"); + } + + protected void expectNullErrorInValueOfString(final EdmPrimitiveType instance) { + expectErrorInValueOfString(instance, null, false, null, null, null, null, instance.getDefaultType(), + "EdmPrimitiveTypeException.LITERAL_NULL_NOT_ALLOWED"); + } + + protected void expectErrorInFromUriLiteral(final EdmPrimitiveType instance, final String value) { + try { + instance.fromUriLiteral(value); + fail("Expected exception not thrown"); + } catch (final EdmPrimitiveTypeException e) { + // TODO: How to test without message reference + // assertNotNull(e.getMessageReference()); + // assertEquals(EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.getKey(), + // e.getMessageReference().getKey()); + assertNotNull(e.getLocalizedMessage()); + assertTrue(e.getLocalizedMessage().startsWith("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT")); + } + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/UInt7Test.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/UInt7Test.java new file mode 100644 index 000000000..ef7a496ce --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/UInt7Test.java @@ -0,0 +1,15 @@ +package org.apache.olingo.commons.core.edm.primitivetype; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class UInt7Test extends PrimitiveTypeBaseTest { + + @Test + public void compatibility() { + assertTrue(Uint7.getInstance().isCompatible(Uint7.getInstance())); + assertFalse(Uint7.getInstance().isCompatible(EdmPrimitiveTypeKind.String.getEdmPrimitiveTypeInstance())); + } +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/provider/EdmComplexTypeImplTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/provider/EdmComplexTypeImplTest.java new file mode 100644 index 000000000..bcab5ba51 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/provider/EdmComplexTypeImplTest.java @@ -0,0 +1,109 @@ +package org.apache.olingo.commons.core.edm.provider; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.olingo.commons.api.edm.EdmComplexType; +import org.apache.olingo.commons.api.edm.EdmElement; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.ComplexType; +import org.apache.olingo.commons.api.edm.provider.EdmProvider; +import org.apache.olingo.commons.api.edm.provider.NavigationProperty; +import org.apache.olingo.commons.api.edm.provider.Property; +import org.junit.Before; +import org.junit.Test; + +public class EdmComplexTypeImplTest { + + private EdmComplexType baseType; + private EdmComplexType type; + + @Before + public void setupTypes() throws Exception { + EdmProvider provider = mock(EdmProvider.class); + EdmProviderImpl edm = new EdmProviderImpl(provider); + + FullQualifiedName baseName = new FullQualifiedName("namespace", "BaseTypeName"); + ComplexType baseComplexType = new ComplexType(); + List baseProperties = new ArrayList(); + baseProperties.add(new Property().setName("prop1")); + List baseNavigationProperties = new ArrayList(); + baseNavigationProperties.add(new NavigationProperty().setName("nav1")); + baseComplexType.setName("BaseTypeName").setAbstract(false).setOpenType(false).setProperties(baseProperties) + .setNavigationProperties(baseNavigationProperties); + when(provider.getComplexType(baseName)).thenReturn(baseComplexType); + + baseType = new EdmComplexTypeImpl(edm, baseName, baseComplexType); + + FullQualifiedName name = new FullQualifiedName("namespace", "typeName"); + ComplexType complexType = new ComplexType().setBaseType(baseName); + List properties = new ArrayList(); + properties.add(new Property().setName("prop2")); + List navigationProperties = new ArrayList(); + navigationProperties.add(new NavigationProperty().setName("nav2")); + complexType.setName("BaseTypeName").setAbstract(false).setOpenType(false).setProperties(properties) + .setNavigationProperties(navigationProperties); + when(provider.getComplexType(name)).thenReturn(complexType); + + type = new EdmComplexTypeImpl(edm, name, complexType); + } + + @Test + public void getBaseType() { + assertNull(baseType.getBaseType()); + assertNotNull(type.getBaseType()); + } + + @Test + public void propertiesBehaviour() { + List propertyNames = baseType.getPropertyNames(); + assertEquals(1, propertyNames.size()); + assertEquals("prop1", baseType.getProperty("prop1").getName()); + } + + @Test + public void propertiesBehaviourWithBaseType() { + List propertyNames = type.getPropertyNames(); + assertEquals(2, propertyNames.size()); + assertEquals("prop1", type.getProperty("prop1").getName()); + assertEquals("prop2", type.getProperty("prop2").getName()); + } + + @Test + public void navigationPropertiesBehaviour() { + List navigationPropertyNames = baseType.getNavigationPropertyNames(); + assertEquals(1, navigationPropertyNames.size()); + assertEquals("nav1", baseType.getProperty("nav1").getName()); + } + + @Test + public void navigationPropertiesBehaviourWithBaseType() { + List navigationPropertyNames = type.getNavigationPropertyNames(); + assertEquals(2, navigationPropertyNames.size()); + assertEquals("nav1", type.getProperty("nav1").getName()); + assertEquals("nav2", type.getProperty("nav2").getName()); + } + + @Test + public void propertyCaching() { + EdmElement property = type.getProperty("prop1"); + assertTrue(property == type.getProperty("prop1")); + + property = type.getProperty("prop2"); + assertTrue(property == type.getProperty("prop2")); + + property = type.getProperty("nav1"); + assertTrue(property == type.getProperty("nav1")); + + property = type.getProperty("nav2"); + assertTrue(property == type.getProperty("nav2")); + } + +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/provider/EdmNamedImplTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/provider/EdmNamedImplTest.java new file mode 100644 index 000000000..aca69def6 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/provider/EdmNamedImplTest.java @@ -0,0 +1,23 @@ +package org.apache.olingo.commons.core.edm.provider; + +import static org.junit.Assert.assertEquals; + +import org.apache.olingo.commons.api.edm.EdmNamed; +import org.junit.Test; + +public class EdmNamedImplTest { + + @Test + public void getNameTest() { + EdmNamed obj = new EdmNamedImplTester("Name"); + assertEquals("Name", obj.getName()); + } + + private class EdmNamedImplTester extends EdmNamedImpl { + + public EdmNamedImplTester(final String name) { + super(name); + } + } + +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/provider/EdmProviderImplTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/provider/EdmProviderImplTest.java new file mode 100644 index 000000000..e61d0a49d --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/provider/EdmProviderImplTest.java @@ -0,0 +1,143 @@ +package org.apache.olingo.commons.core.edm.provider; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.EdmAction; +import org.apache.olingo.commons.api.edm.EdmComplexType; +import org.apache.olingo.commons.api.edm.EdmEntityContainer; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmEnumType; +import org.apache.olingo.commons.api.edm.EdmFunction; +import org.apache.olingo.commons.api.edm.EdmTypeDefinition; +import org.apache.olingo.commons.api.edm.helper.EntityContainerInfo; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.Action; +import org.apache.olingo.commons.api.edm.provider.ComplexType; +import org.apache.olingo.commons.api.edm.provider.EdmProvider; +import org.apache.olingo.commons.api.edm.provider.EntityType; +import org.apache.olingo.commons.api.edm.provider.EnumType; +import org.apache.olingo.commons.api.edm.provider.Function; +import org.apache.olingo.commons.api.edm.provider.TypeDefinition; +import org.junit.Before; +import org.junit.Test; + +public class EdmProviderImplTest { + + private Edm edm; + private final FullQualifiedName FQN = new FullQualifiedName("testNamespace", "testName"); + private final FullQualifiedName WRONG_FQN = new FullQualifiedName("wrong", "wrong"); + + @Before + public void setup() throws Exception { + EdmProvider provider = mock(EdmProvider.class); + EntityContainerInfo containerInfo = new EntityContainerInfo().setContainerName(FQN); + when(provider.getEntityContainerInfo(FQN)).thenReturn(containerInfo); + when(provider.getEntityContainerInfo(null)).thenReturn(containerInfo); + + EnumType enumType = new EnumType().setName(FQN.getName()); + when(provider.getEnumType(FQN)).thenReturn(enumType); + + TypeDefinition typeDefinition = new TypeDefinition().setName(FQN.getName()); + when(provider.getTypeDefinition(FQN)).thenReturn(typeDefinition); + + EntityType entityType = new EntityType().setName(FQN.getName()); + when(provider.getEntityType(FQN)).thenReturn(entityType); + + ComplexType complexType = new ComplexType().setName(FQN.getName()); + when(provider.getComplexType(FQN)).thenReturn(complexType); + + Action action = new Action().setName(FQN.getName()); + when(provider.getAction(FQN, null, null)).thenReturn(action); + + Function function = new Function().setName(FQN.getName()); + when(provider.getFunction(FQN, null, null, null)).thenReturn(function); + + edm = new EdmProviderImpl(provider); + } + + @Test + public void getEntityContainer() { + EdmEntityContainer entityContainer = edm.getEntityContainer(FQN); + assertNotNull(entityContainer); + assertEquals(FQN.getNamespace(), entityContainer.getNamespace()); + assertEquals(FQN.getName(), entityContainer.getName()); + + entityContainer = edm.getEntityContainer(null); + assertNotNull(entityContainer); + assertEquals(FQN.getNamespace(), entityContainer.getNamespace()); + assertEquals(FQN.getName(), entityContainer.getName()); + + assertNull(edm.getEntityContainer(WRONG_FQN)); + } + + @Test + public void getEnumType() { + EdmEnumType enumType = edm.getEnumType(FQN); + assertNotNull(enumType); + assertEquals(FQN.getNamespace(), enumType.getNamespace()); + assertEquals(FQN.getName(), enumType.getName()); + + assertNull(edm.getEnumType(WRONG_FQN)); + } + + @Test + public void getTypeDefinition() { + EdmTypeDefinition typeDefinition = edm.getTypeDefinition(FQN); + assertNotNull(typeDefinition); + assertEquals(FQN.getNamespace(), typeDefinition.getNamespace()); + assertEquals(FQN.getName(), typeDefinition.getName()); + + assertNull(edm.getTypeDefinition(WRONG_FQN)); + } + + @Test + public void getEntityType() { + EdmEntityType entityType = edm.getEntityType(FQN); + assertNotNull(entityType); + assertEquals(FQN.getNamespace(), entityType.getNamespace()); + assertEquals(FQN.getName(), entityType.getName()); + + assertNull(edm.getEntityType(WRONG_FQN)); + } + + @Test + public void getComplexType() { + EdmComplexType complexType = edm.getComplexType(FQN); + assertNotNull(complexType); + assertEquals(FQN.getNamespace(), complexType.getNamespace()); + assertEquals(FQN.getName(), complexType.getName()); + + assertNull(edm.getComplexType(WRONG_FQN)); + } + + @Test + public void getAction() { + EdmAction action = edm.getAction(FQN, null, null); + assertNotNull(action); + assertEquals(FQN.getNamespace(), action.getNamespace()); + assertEquals(FQN.getName(), action.getName()); + + assertNull(edm.getAction(WRONG_FQN, null, null)); + } + + @Test + public void getFunction() { + EdmFunction function = edm.getFunction(FQN, null, null, null); + assertNotNull(function); + assertEquals(FQN.getNamespace(), function.getNamespace()); + assertEquals(FQN.getName(), function.getName()); + + assertNull(edm.getFunction(WRONG_FQN, null, null, null)); + } + + @Test + public void getServiceMetadata() { + assertNotNull(edm.getServiceMetadata()); + } + +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/provider/EdmStructuralTypeImplTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/provider/EdmStructuralTypeImplTest.java new file mode 100644 index 000000000..52b8f56f0 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/provider/EdmStructuralTypeImplTest.java @@ -0,0 +1,196 @@ +package org.apache.olingo.commons.core.edm.provider; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.olingo.commons.api.edm.EdmComplexType; +import org.apache.olingo.commons.api.edm.EdmElement; +import org.apache.olingo.commons.api.edm.EdmNavigationProperty; +import org.apache.olingo.commons.api.edm.EdmProperty; +import org.apache.olingo.commons.api.edm.EdmStructuralType; +import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.NavigationProperty; +import org.apache.olingo.commons.api.edm.provider.Property; +import org.apache.olingo.commons.api.edm.provider.StructuralType; +import org.junit.Before; +import org.junit.Test; + +public class EdmStructuralTypeImplTest { + + private EdmStructuralType type; + private EdmStructuralType extendedType; + + @Before + public void setupType() { + EdmProviderImpl mockEdm = mock(EdmProviderImpl.class); + + StructuralType structuralTypeMock = mock(StructuralType.class); + when(structuralTypeMock.getName()).thenReturn("MockName"); + + List propertyList = new ArrayList(); + Property property = new Property().setName("TestName1"); + propertyList.add(property); + property = new Property().setName("TestName2"); + propertyList.add(property); + when(structuralTypeMock.getProperties()).thenReturn(propertyList); + + List navigationPropertyList = new ArrayList(); + NavigationProperty navProperty = new NavigationProperty().setName("TestNavName1"); + navigationPropertyList.add(navProperty); + navProperty = new NavigationProperty().setName("TestNavName2"); + navigationPropertyList.add(navProperty); + when(structuralTypeMock.getNavigationProperties()).thenReturn(navigationPropertyList); + + type = new EdmStructuralTypeImplTester(mockEdm, new FullQualifiedName("namespace", "MockName"), structuralTypeMock, + EdmTypeKind.COMPLEX); + + FullQualifiedName baseName = new FullQualifiedName("namespace", "name"); + EdmComplexType baseTypeMock = mock(EdmComplexType.class); + when(baseTypeMock.getName()).thenReturn(baseName.getName()); + when(baseTypeMock.getNamespace()).thenReturn(baseName.getNamespace()); + List basePropNames = new ArrayList(); + basePropNames.add("TestName3"); + when(baseTypeMock.getPropertyNames()).thenReturn(basePropNames); + List baseNavNames = new ArrayList(); + baseNavNames.add("TestNavName3"); + when(baseTypeMock.getNavigationPropertyNames()).thenReturn(baseNavNames); + EdmProperty testName3Mock = mock(EdmProperty.class); + when(testName3Mock.getName()).thenReturn("TestName3"); + when(baseTypeMock.getProperty("TestName3")).thenReturn(testName3Mock); + EdmNavigationProperty testNavName3Mock = mock(EdmNavigationProperty.class); + when(testNavName3Mock.getName()).thenReturn("TestNavName3"); + when(baseTypeMock.getProperty("TestNavName3")).thenReturn(testNavName3Mock); + when(mockEdm.getComplexType(baseName)).thenReturn(baseTypeMock); + + StructuralType typeMockWithBaseType = mock(StructuralType.class); + when(typeMockWithBaseType.getBaseType()).thenReturn(baseName); + when(typeMockWithBaseType.getProperties()).thenReturn(propertyList); + when(typeMockWithBaseType.getNavigationProperties()).thenReturn(navigationPropertyList); + when(typeMockWithBaseType.getName()).thenReturn("MockName2"); + extendedType = new EdmStructuralTypeImplTester(mockEdm, new FullQualifiedName("namespace", "MockName2"), + typeMockWithBaseType, + EdmTypeKind.COMPLEX); + } + + @Test + public void getExistingProperty() { + EdmElement property = type.getProperty("TestName1"); + assertNotNull(property); + assertTrue(property instanceof EdmProperty); + assertEquals("TestName1", property.getName()); + } + + @Test + public void getExistingCachedProperty() { + EdmElement property = type.getProperty("TestName1"); + assertNotNull(property); + + EdmElement cachedProperty = type.getProperty("TestName1"); + assertNotNull(property); + + assertEquals(property, cachedProperty); + } + + @Test + public void getExistingPropertyWithBaseType() { + EdmElement property = extendedType.getProperty("TestName3"); + assertNotNull(property); + assertTrue(property instanceof EdmProperty); + assertEquals("TestName3", property.getName()); + } + + @Test + public void getNonExistingProperty() { + EdmElement property = type.getProperty("TestNameWrong"); + assertNull(property); + } + + @Test + public void getExistingNavigationProperty() { + EdmElement property = type.getProperty("TestNavName1"); + assertNotNull(property); + assertTrue(property instanceof EdmNavigationProperty); + assertEquals("TestNavName1", property.getName()); + } + + @Test + public void getExistingNavigationPropertyWithBaseType() { + EdmElement property = extendedType.getProperty("TestNavName3"); + assertNotNull(property); + assertTrue(property instanceof EdmNavigationProperty); + assertEquals("TestNavName3", property.getName()); + + } + + @Test + public void getAllPropertyNamesAndVerifyExistence() { + List propertyNames = type.getPropertyNames(); + assertNotNull(propertyNames); + assertEquals(2, propertyNames.size()); + assertTrue(propertyNames.contains("TestName1")); + assertTrue(propertyNames.contains("TestName2")); + for (String name : propertyNames) { + assertNotNull(type.getProperty(name)); + } + } + + @Test + public void getAllNavigationPropertyNamesAndVerifyExistence() { + List navigationPropertyNames = type.getNavigationPropertyNames(); + assertNotNull(navigationPropertyNames); + assertEquals(2, navigationPropertyNames.size()); + assertTrue(navigationPropertyNames.contains("TestNavName1")); + assertTrue(navigationPropertyNames.contains("TestNavName2")); + for (String name : navigationPropertyNames) { + assertNotNull(type.getProperty(name)); + } + } + + @Test + public void getAllPropertyNamesAndVerifyExistenceWithBaseType() { + List propertyNames = extendedType.getPropertyNames(); + assertNotNull(propertyNames); + assertEquals(3, propertyNames.size()); + assertTrue(propertyNames.contains("TestName1")); + assertTrue(propertyNames.contains("TestName2")); + assertTrue(propertyNames.contains("TestName3")); + for (String name : propertyNames) { + assertNotNull(extendedType.getProperty(name)); + } + } + + @Test + public void getAllNavigationPropertyNamesAndVerifyExistenceWithBaseType() { + List navigationPropertyNames = extendedType.getNavigationPropertyNames(); + assertNotNull(navigationPropertyNames); + assertEquals(3, navigationPropertyNames.size()); + assertTrue(navigationPropertyNames.contains("TestNavName1")); + assertTrue(navigationPropertyNames.contains("TestNavName2")); + assertTrue(navigationPropertyNames.contains("TestNavName3")); + for (String name : navigationPropertyNames) { + assertNotNull(extendedType.getProperty(name)); + } + } + + @Test + public void verifyBaseType() { + assertNotNull(extendedType.getBaseType()); + } + + private class EdmStructuralTypeImplTester extends EdmStructuralTypeImpl { + public EdmStructuralTypeImplTester(final EdmProviderImpl edm, final FullQualifiedName name, + final StructuralType structuralType, + final EdmTypeKind kind) { + super(edm, name, structuralType, kind); + } + } + +} diff --git a/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/provider/EdmTypeImplTest.java b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/provider/EdmTypeImplTest.java new file mode 100644 index 000000000..8c9d6f8a7 --- /dev/null +++ b/odata4-lib/odata4-commons-core/src/test/java/org/apache/olingo/commons/core/edm/provider/EdmTypeImplTest.java @@ -0,0 +1,26 @@ +package org.apache.olingo.commons.core.edm.provider; + +import static org.junit.Assert.assertEquals; + +import org.apache.olingo.commons.api.edm.EdmType; +import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; +import org.apache.olingo.commons.api.edm.helper.FullQualifiedName; +import org.junit.Test; + +public class EdmTypeImplTest { + + @Test + public void getterTest() { + EdmType type = new EdmTypeImplTester(new FullQualifiedName("namespace", "name"), EdmTypeKind.UNDEFINED); + assertEquals("name", type.getName()); + assertEquals("namespace", type.getNamespace()); + assertEquals(EdmTypeKind.UNDEFINED, type.getKind()); + } + + private class EdmTypeImplTester extends EdmTypeImpl { + public EdmTypeImplTester(final FullQualifiedName name, final EdmTypeKind kind) { + super(name, kind); + } + } + +} diff --git a/pom.xml b/pom.xml index 4b8248778..2f2bfedd9 100644 --- a/pom.xml +++ b/pom.xml @@ -47,7 +47,28 @@ odata4-lib - + + + 1.9.0 + 4.10 + 1.6 + + + + + junit + junit + ${junit.version} + test + + + org.mockito + mockito-all + ${mockito.version} + test + + + ${project.artifactId}-${project.version}