/*******************************************************************************
* Copyright 2013 SAP AG
*
* Licensed 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 com.sap.core.odata.core.edm;
import com.sap.core.odata.api.edm.EdmLiteral;
import com.sap.core.odata.api.edm.EdmLiteralException;
import com.sap.core.odata.api.edm.EdmLiteralKind;
import com.sap.core.odata.api.edm.EdmSimpleType;
import com.sap.core.odata.api.edm.EdmSimpleTypeException;
import com.sap.core.odata.api.edm.EdmSimpleTypeFacade;
import com.sap.core.odata.api.edm.EdmSimpleTypeKind;
import com.sap.core.odata.core.exception.ODataRuntimeException;
/**
* @author SAP AG
*/
public class EdmSimpleTypeFacadeImpl implements EdmSimpleTypeFacade {
@Override
public EdmLiteral parseUriLiteral(final String uriLiteral) throws EdmLiteralException {
if (uriLiteral == null || "null".equals(uriLiteral)) {
return new EdmLiteral(getEdmSimpleType(EdmSimpleTypeKind.Null), uriLiteral);
}
if ("true".equals(uriLiteral) || "false".equals(uriLiteral)) {
return new EdmLiteral(getEdmSimpleType(EdmSimpleTypeKind.Boolean), uriLiteral);
}
if (uriLiteral.length() >= 2
&& uriLiteral.startsWith("'") && uriLiteral.endsWith("'")) {
try {
final EdmSimpleType type = getEdmSimpleType(EdmSimpleTypeKind.String);
return new EdmLiteral(type, type.valueOfString(uriLiteral, EdmLiteralKind.URI, null, String.class));
} catch (EdmSimpleTypeException e) {
throw new EdmLiteralException(EdmLiteralException.LITERALFORMAT.addContent(uriLiteral), e);
}
}
if (uriLiteral.matches("-?\\p{Digit}+")) {
try {
final int i = getEdmSimpleType(EdmSimpleTypeKind.Int32).valueOfString(uriLiteral, EdmLiteralKind.URI, null, Integer.class);
if (i == 0 || i == 1) {
return new EdmLiteral(getInternalEdmSimpleTypeByString("Bit"), uriLiteral);
}
if (i >= 0 && i <= Byte.MAX_VALUE) {
return new EdmLiteral(getInternalEdmSimpleTypeByString("Uint7"), uriLiteral);
}
if (i >= Byte.MIN_VALUE && i < 0) {
return new EdmLiteral(getEdmSimpleType(EdmSimpleTypeKind.SByte), uriLiteral);
} else if (i > Byte.MAX_VALUE && i <= 255) {
return new EdmLiteral(getEdmSimpleType(EdmSimpleTypeKind.Byte), uriLiteral);
} else if (i >= Short.MIN_VALUE && i <= Short.MAX_VALUE) {
return new EdmLiteral(getEdmSimpleType(EdmSimpleTypeKind.Int16), uriLiteral);
} else {
return new EdmLiteral(getEdmSimpleType(EdmSimpleTypeKind.Int32), uriLiteral);
}
} catch (EdmSimpleTypeException e) {
throw new EdmLiteralException(EdmLiteralException.LITERALFORMAT.addContent(uriLiteral), e);
}
}
if (uriLiteral.endsWith("L") || uriLiteral.endsWith("l")) {
return createEdmLiteral(EdmSimpleTypeKind.Int64, uriLiteral, 0, 1);
}
if (uriLiteral.endsWith("M") || uriLiteral.endsWith("m")) {
return createEdmLiteral(EdmSimpleTypeKind.Decimal, uriLiteral, 0, 1);
}
if (uriLiteral.endsWith("D") || uriLiteral.endsWith("d")) {
return createEdmLiteral(EdmSimpleTypeKind.Double, uriLiteral, 0, 1);
}
if (uriLiteral.equals("-INF") || uriLiteral.equals("INF") || uriLiteral.equals("NaN")) {
return new EdmLiteral(getEdmSimpleType(EdmSimpleTypeKind.Single), uriLiteral);
}
if (uriLiteral.endsWith("F") || uriLiteral.endsWith("f")) {
return createEdmLiteral(EdmSimpleTypeKind.Single, uriLiteral, 0, 1);
}
if (uriLiteral.startsWith("datetime'")) {
return createEdmLiteral(EdmSimpleTypeKind.DateTime, uriLiteral, 9, 1);
}
if (uriLiteral.startsWith("datetimeoffset'")) {
return createEdmLiteral(EdmSimpleTypeKind.DateTimeOffset, uriLiteral, 15, 1);
}
if (uriLiteral.startsWith("guid'")) {
return createEdmLiteral(EdmSimpleTypeKind.Guid, uriLiteral, 5, 1);
}
if (uriLiteral.startsWith("time'")) {
return createEdmLiteral(EdmSimpleTypeKind.Time, uriLiteral, 5, 1);
}
if (uriLiteral.startsWith("X'") || uriLiteral.startsWith("binary'")) {
try {
final EdmSimpleType type = getEdmSimpleType(EdmSimpleTypeKind.Binary);
final byte[] value = type.valueOfString(uriLiteral, EdmLiteralKind.URI, null, byte[].class);
return new EdmLiteral(type, type.valueToString(value, EdmLiteralKind.DEFAULT, null));
} catch (EdmSimpleTypeException e) {
throw new EdmLiteralException(EdmLiteralException.LITERALFORMAT.addContent(uriLiteral), e);
}
}
throw new EdmLiteralException(EdmLiteralException.UNKNOWNLITERAL.addContent(uriLiteral));
}
private static EdmLiteral createEdmLiteral(final EdmSimpleTypeKind typeKind, final String literal, final int prefixLength, final int suffixLength) throws EdmLiteralException {
final EdmSimpleType type = getEdmSimpleType(typeKind);
if (type.validate(literal, EdmLiteralKind.URI, null)) {
return new EdmLiteral(type, literal.substring(prefixLength, literal.length() - suffixLength));
} else {
throw new EdmLiteralException(EdmLiteralException.LITERALFORMAT.addContent(literal));
}
}
@Override
public EdmSimpleType getEdmSimpleTypeInstance(final EdmSimpleTypeKind typeKind) {
return getEdmSimpleType(typeKind);
}
public static EdmSimpleType getEdmSimpleType(final EdmSimpleTypeKind typeKind) {
switch (typeKind) {
case Binary:
return EdmBinary.getInstance();
case Boolean:
return EdmBoolean.getInstance();
case Byte:
return EdmByte.getInstance();
case DateTime:
return EdmDateTime.getInstance();
case DateTimeOffset:
return EdmDateTimeOffset.getInstance();
case Decimal:
return EdmDecimal.getInstance();
case Double:
return EdmDouble.getInstance();
case Guid:
return EdmGuid.getInstance();
case Int16:
return EdmInt16.getInstance();
case Int32:
return EdmInt32.getInstance();
case Int64:
return EdmInt64.getInstance();
case SByte:
return EdmSByte.getInstance();
case Single:
return EdmSingle.getInstance();
case String:
return EdmString.getInstance();
case Time:
return EdmTime.getInstance();
case Null:
return EdmNull.getInstance();
default:
throw new ODataRuntimeException("Invalid Type " + typeKind);
}
}
public static EdmSimpleType getInternalEdmSimpleTypeByString(final String edmSimpleType) {
if ("Bit".equals(edmSimpleType)) {
return Bit.getInstance();
} else if ("Uint7".equals(edmSimpleType)) {
return Uint7.getInstance();
} else {
throw new ODataRuntimeException("Invalid internal Type " + edmSimpleType);
}
}
}