/*******************************************************************************
* Copyright (C) 2014 The Calrissian Authors
*
* 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 org.calrissian.restdoclet.writer.swagger;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.FieldDoc;
import com.sun.javadoc.ParameterizedType;
import com.sun.javadoc.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Set;
import static java.util.Collections.emptyList;
import static org.calrissian.restdoclet.util.CommonUtils.isEmpty;
class TypeUtils {
/**
* Will return a full data type for Swagger.
* @param type
* @return
*/
public static String dataType(Type type) {
if (type == null)
return null;
if (isContainer(type)) {
//treat sets as sets
if (isType(type.asClassDoc(), Set.class))
return "Set[" + internalContainerType(type) + "]";
return "List[" + internalContainerType(type) + "]";
}
//Treat as a basic type.
return basicType(type);
}
/**
* Checks if the type is an iterable or an array
* @param type
* @return
*/
public static boolean isContainer(Type type) {
//first check for arrays
if (type.dimension() != null && !type.dimension().isEmpty())
return true;
//treat iterables as lists
if (isType(type.asClassDoc(), Iterable.class))
return true;
return false;
}
/**
* This will grab the internal type from an array or a parameterized container.
* @param type
* @return
*/
public static String internalContainerType(Type type) {
//treat arrays first
if (type.dimension() != null && !type.dimension().isEmpty())
return basicType(type);
ParameterizedType pType = type.asParameterizedType();
if (pType != null) {
Type[] paramTypes = ((ParameterizedType)type).typeArguments();
if (!isEmpty(paramTypes))
return basicType(paramTypes[0]);
}
//TODO look into supporting models.
return "Object";
}
/**
* Returns the basic type. If not one of the supported swagger basic types then it is treated as an Object.
* @param type
* @return
*/
public static String basicType(Type type) {
if (type == null)
return "void";
//next primitives
if (type.isPrimitive())
return type.qualifiedTypeName();
String name = type.qualifiedTypeName();
//Check the java.lang classes
if (name.equals(String.class.getName()))
return "string";
if (name.equals(Boolean.class.getName()))
return "boolean";
if (name.equals(Integer.class.getName()))
return "int";
if (name.equals(Long.class.getName()))
return "long";
if (name.equals(Float.class.getName()))
return "float";
if (name.equals(Double.class.getName()))
return "double";
if (name.equals(Byte.class.getName()))
return "byte";
if (name.equals(Date.class.getName()))
return "Date";
//Process enums as strings.
if (!isEmpty(type.asClassDoc().enumConstants()))
return "string";
//TODO look into supporting models.
return "object";
}
/**
* This will retrieve all known allowable values from an enum.
* @param type
* @return
*/
public static Collection<String> allowableValues(Type type) {
if (type == null || type.asClassDoc() == null)
return emptyList();
FieldDoc[] fields = type.asClassDoc().enumConstants();
if (isEmpty(fields))
return emptyList();
Collection<String> values = new ArrayList<String>(fields.length);
for (FieldDoc field : fields)
values.add(field.name());
return values;
}
/**
* Checks the class doc to see if it is a type or subtype of the provided class or object.
* @param classDoc
* @param targetClazz
* @param <T>
* @return
*/
private static <T> boolean isType(ClassDoc classDoc, Class<T> targetClazz) {
if (classDoc == null)
return false;
if (classDoc.qualifiedTypeName().equals(targetClazz.getName()))
return true;
if (isType(classDoc.superclass(), targetClazz))
return true;
for (ClassDoc iface : classDoc.interfaces())
if (isType(iface, targetClazz))
return true;
return false;
}
}