/*
* Copyright 2014, The Sporting Exchange Limited
*
* 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.betfair.cougar.marshalling.impl.util;
import com.betfair.cougar.core.api.exception.CougarFrameworkException;
import com.betfair.cougar.core.api.exception.CougarMarshallingException;
import com.betfair.cougar.core.api.exception.CougarValidationException;
import com.betfair.cougar.core.api.exception.ServerFaultCode;
import com.betfair.cougar.core.api.transcription.EnumDerialisationException;
import com.betfair.cougar.core.api.transcription.EnumUtils;
import com.betfair.cougar.util.dates.DateTimeUtility;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
public final class BindingUtils {
private static final Pattern csv = Pattern.compile(",");
public static Object convertToSimpleType(Class<?> clazz, Class<?> genericClass, String name, String value, boolean unescapeStrings, boolean hardFailEnums, String format, boolean client) throws IllegalArgumentException {
Object result = null;
if (value != null) {
try {
if (clazz == String.class) {
try {
if (unescapeStrings) {
result = URLDecoder.decode(value, "UTF-8");
} else {
result = value;
}
} catch (UnsupportedEncodingException e) {
throw new CougarFrameworkException("Unsupported encoding", e);
}
}
else if (clazz == Integer.class) {
result = Integer.valueOf(value);
} else if (clazz == Byte.class) {
result = Byte.valueOf(value);
} else if (clazz == Short.class) {
result = Short.valueOf(value);
} else if (clazz == Long.class) {
result = Long.valueOf(value);
} else if (clazz == Float.class) {
try {
result = Float.valueOf(value);
} catch (NumberFormatException e) {
result = checkXMLInfinity(clazz, value);
if (result == null) {
throw e;
}
}
} else if (clazz == Double.class) {
try {
result = Double.valueOf(value);
} catch (NumberFormatException e) {
result = checkXMLInfinity(clazz, value);
if (result == null) {
throw e;
}
}
} else if (clazz == Boolean.class) {
// Boolean.valueOf only checks for true, so a value of "foo" will return Boolean.FALSE
if (Boolean.valueOf(value)) {
result = Boolean.TRUE;
} else if (value.equalsIgnoreCase("false")) {
result = Boolean.FALSE;
} else {
throw newValidationException(name, value, clazz, null, format, client);
}
} else if (clazz == Character.class) {
result = value.charAt(0);
} else if (clazz.isEnum()) {
result = EnumUtils.readEnum((Class) clazz, value, hardFailEnums);
} else if (clazz == List.class || clazz == Set.class) {
int start=0,end=value.length();
if (value.startsWith("[")) {
start=1;
}
if (value.endsWith("]")) {
end--;
}
Collection<Object> collection = (clazz == List.class) ? new ArrayList<Object>() : new HashSet<Object>();
for (String val: csv.split(value.substring(start,end))) {
val = val.trim();
if (genericClass == String.class || val.length() > 0) {
collection.add(convertToSimpleType(genericClass, null, name + "[member]", val.trim(), unescapeStrings, hardFailEnums, format, client));
}
}
if (collection.size() > 0) {
result = collection ;
}
} else if(clazz == java.util.Date.class) {
result = DateTimeUtility.parse(value);
} else {
throw newValidationException(name, value, clazz, null, format, client);
}
} catch (RuntimeException ex) {
if (ex instanceof CougarMarshallingException || ex instanceof EnumDerialisationException) {
throw ex;
} else {
throw newValidationException(name, value, clazz, ex, format, client);
}
}
}
return result;
}
private final static CougarMarshallingException newValidationException(String name, String value, Class clazz, Exception originalException, String format, boolean client) {
final StringBuilder msg = new StringBuilder("Unable to convert '");
msg.append(value).append("' to ").append(clazz.getName()).append(" for parameter: " + name);
return CougarMarshallingException.unmarshallingException(format, msg.toString(), originalException, client);
}
private static final Object checkXMLInfinity(Class<?> clazz, String value) {
boolean returnFloat = Float.class.equals(clazz);
if (value.equals("INF")) {
if (returnFloat) {
return Float.POSITIVE_INFINITY;
} else {
return Double.POSITIVE_INFINITY;
}
} else if (value.equals("-INF")) {
if (returnFloat) {
return Float.NEGATIVE_INFINITY;
} else {
return Double.NEGATIVE_INFINITY;
}
}
return null;
}
}