/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.translator.swagger;
import java.lang.reflect.Array;
import java.sql.Date;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.types.Transform;
import org.teiid.core.types.TransformationException;
import org.teiid.translator.TranslatorException;
public class SwaggerTypeManager {
private static Pattern timestampPattern = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})" //date //$NON-NLS-1$
+ "[T|t](\\d{2}):(\\d{2}):(\\d{2})" // time //$NON-NLS-1$
+ "(\\.\\d{1})?" // optional fractions //$NON-NLS-1$
+ "([Z|z]|([+|-](\\d{2}):(\\d{2})))"); //$NON-NLS-1$ // timezone
private static final String INTEGER = "integer";
private static final String INTEGER_ = typeFormat("integer", "int32");
private static final String LONG = "long";
private static final String LONG_ = typeFormat("integer", "int64");
private static final String FLOAT = "float";
private static final String FLOAT_ = typeFormat("number", "float");
private static final String DOUBLE = "double";
private static final String DOUBLE_ = typeFormat("number", "double");
private static final String STRING = "string";
private static final String STRING_ = typeFormat("string", "");
private static final String BYTE = "byte";
private static final String BYTE_ = typeFormat("string", "byte");
private static final String BINARY = "binary";
private static final String BINARY_ = typeFormat("string", "binary");
private static final String BOOLEAN = "boolean";
private static final String BOOLEAN_ = typeFormat("boolean", "");
private static final String DATE = "date";
private static final String DATE_ = typeFormat("string", "date");
private static final String DATETIME = "dateTime";
private static final String DATETIME_ = typeFormat("string", "date-time");
private static final String PASSWORD = "password";
private static final String PASSWORD_ = typeFormat("string", "password");
// this no swagger definition
private static final String OBJECT = typeFormat("array", "");
// private static final String OBJECT_ = typeFormat("object", "");
static String typeFormat(String type, String format){
return type + "/" + format;
}
private static HashMap<String, String> swaggerTypes = new HashMap<String, String>();
static {
swaggerTypes.put(INTEGER, DataTypeManager.DefaultDataTypes.INTEGER);
swaggerTypes.put(INTEGER_, DataTypeManager.DefaultDataTypes.INTEGER);
swaggerTypes.put(LONG, DataTypeManager.DefaultDataTypes.LONG);
swaggerTypes.put(LONG_, DataTypeManager.DefaultDataTypes.LONG);
swaggerTypes.put(FLOAT, DataTypeManager.DefaultDataTypes.FLOAT);
swaggerTypes.put(FLOAT_, DataTypeManager.DefaultDataTypes.FLOAT);
swaggerTypes.put(DOUBLE, DataTypeManager.DefaultDataTypes.DOUBLE);
swaggerTypes.put(DOUBLE_, DataTypeManager.DefaultDataTypes.DOUBLE);
swaggerTypes.put(STRING, DataTypeManager.DefaultDataTypes.STRING);
swaggerTypes.put(STRING_, DataTypeManager.DefaultDataTypes.STRING);
swaggerTypes.put(BYTE, DataTypeManager.DefaultDataTypes.BYTE);
swaggerTypes.put(BYTE_, DataTypeManager.DefaultDataTypes.BYTE);
swaggerTypes.put(BINARY, DataTypeManager.DefaultDataTypes.BLOB);
swaggerTypes.put(BINARY_, DataTypeManager.DefaultDataTypes.BLOB);
swaggerTypes.put(BOOLEAN, DataTypeManager.DefaultDataTypes.BOOLEAN);
swaggerTypes.put(BOOLEAN_, DataTypeManager.DefaultDataTypes.BOOLEAN);
swaggerTypes.put(DATE, DataTypeManager.DefaultDataTypes.DATE);
swaggerTypes.put(DATE_, DataTypeManager.DefaultDataTypes.DATE);
swaggerTypes.put(DATETIME, DataTypeManager.DefaultDataTypes.TIMESTAMP);
swaggerTypes.put(DATETIME_, DataTypeManager.DefaultDataTypes.TIMESTAMP);
swaggerTypes.put(PASSWORD, DataTypeManager.DefaultDataTypes.STRING);
swaggerTypes.put(PASSWORD_, DataTypeManager.DefaultDataTypes.STRING);
swaggerTypes.put(OBJECT, DataTypeManager.DefaultDataTypes.OBJECT);
}
static String teiidType(String name) {
String type = swaggerTypes.get(name);
if (type == null) {
type = DataTypeManager.DefaultDataTypes.STRING; // special case for enum type
}
return type ;
}
static String teiidType(String type, String format, boolean array) {
if(null == format) {
format = "";
}
String returnType = swaggerTypes.get(typeFormat(type, format));
if(null == returnType) {
returnType = DataTypeManager.DefaultDataTypes.STRING;
}
if (array) {
returnType +="[]";
}
return returnType;
}
static Object convertTeiidRuntimeType(Object value, Class<?> expectedType) throws TranslatorException {
if (value == null) {
return null;
}
if (expectedType.isAssignableFrom(value.getClass())) {
return value;
} else {
if(expectedType.isAssignableFrom(Timestamp.class) && value instanceof Long) {
return new Timestamp((Long)value);
} else if (expectedType.isAssignableFrom(java.sql.Timestamp.class) && value instanceof String){
return formTimestamp((String)value);
} else if (expectedType.isAssignableFrom(java.util.Date.class) && value instanceof Long) {
return new java.util.Date((Long)value);
} else if (expectedType.isAssignableFrom(java.util.Date.class) && value instanceof String) {
return formDate((String)value);
} else if (expectedType.isArray() && value instanceof List) {
List<?> values = (List<?>)value;
Class<?> expectedArrayComponentType = expectedType.getComponentType();
Object array = Array.newInstance(expectedArrayComponentType, values.size());
for (int i = 0; i < values.size(); i++) {
Object arrayItem = convertTeiidRuntimeType(values.get(i), expectedArrayComponentType);
Array.set(array, i, arrayItem);
}
return array;
}
Transform transform = DataTypeManager.getTransform(value.getClass(), expectedType);
if (transform != null) {
try {
value = transform.transform(value, expectedType);
} catch (TransformationException e) {
throw new TranslatorException(e);
}
}
}
return value;
}
static Date formDate(String value) throws TranslatorException {
try {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
return new Date(formatter.parse(value).getTime());
} catch (ParseException e) {
throw new TranslatorException(e, SwaggerPlugin.Util.gs(SwaggerPlugin.Event.TEIID28012));
}
}
static Timestamp formTimestamp(String value) throws TranslatorException {
Matcher m = timestampPattern.matcher((String)value);
if (m.matches()) {
Calendar cal = null;
String timeZone = m.group(8);
if (timeZone.equalsIgnoreCase("Z")) {
cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
} else {
cal = Calendar.getInstance(TimeZone.getTimeZone("GMT" + m.group(9)));
}
cal.set(Integer.valueOf(m.group(1)), Integer.valueOf(m.group(2))-1,
Integer.valueOf(m.group(3)), Integer.valueOf(m.group(4)),
Integer.valueOf(m.group(5)), Integer.valueOf(m.group(6)));
Timestamp ts = new Timestamp(cal.getTime().getTime());
if (m.group(7) != null) {
String fraction = m.group(7).substring(1);
ts.setNanos(Integer.parseInt(fraction));
} else {
ts.setNanos(0);
}
return ts;
} else {
throw new TranslatorException(SwaggerPlugin.Util
.gs(SwaggerPlugin.Event.TEIID28011, timestampPattern));
}
}
static String timestampToString(Timestamp ts) {
SimpleDateFormat timestampSDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SZ");
if (ts == null) {
return null;
}
String str = timestampSDF.format(ts);
if(str.endsWith("+0000")) {
str = str.replace("+0000", "Z");
}
return str;
}
static String dateToString(Date date) {
SimpleDateFormat dateSDF = new SimpleDateFormat("yyyy-MM-dd");
if (date == null) {
return null;
}
return dateSDF.format(date);
}
}