/** * Copyright 2005-2014 Restlet * * The contents of this file are subject to the terms of one of the following * open source licenses: Apache 2.0 or or EPL 1.0 (the "Licenses"). You can * select the license that you prefer but you may not use this file except in * compliance with one of these Licenses. * * You can obtain a copy of the Apache 2.0 license at * http://www.opensource.org/licenses/apache-2.0 * * You can obtain a copy of the EPL 1.0 license at * http://www.opensource.org/licenses/eclipse-1.0 * * See the Licenses for the specific language governing permissions and * limitations under the Licenses. * * Alternatively, you can obtain a royalty free commercial license with less * limitations, transferable or non-transferable, directly at * http://restlet.com/products/restlet-framework * * Restlet is a registered trademark of Restlet S.A.S. */ package org.restlet.ext.apispark.internal.introspection.helper; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import org.restlet.data.Status; import org.restlet.engine.util.StringUtils; import org.restlet.ext.apispark.internal.introspection.util.Types; import org.restlet.ext.apispark.internal.model.Operation; import org.restlet.ext.apispark.internal.model.Parameter; import org.restlet.ext.apispark.internal.model.PayLoad; import org.restlet.ext.apispark.internal.model.Property; import org.restlet.ext.apispark.internal.model.QueryParameter; import org.restlet.ext.apispark.internal.model.Representation; import org.restlet.ext.apispark.internal.model.Resource; import org.restlet.ext.apispark.internal.model.Response; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.wordnik.swagger.annotations.Api; import com.wordnik.swagger.annotations.ApiImplicitParam; import com.wordnik.swagger.annotations.ApiImplicitParams; import com.wordnik.swagger.annotations.ApiModel; import com.wordnik.swagger.annotations.ApiModelProperty; import com.wordnik.swagger.annotations.ApiOperation; import com.wordnik.swagger.annotations.ApiParam; import com.wordnik.swagger.annotations.ApiResponse; import com.wordnik.swagger.annotations.ApiResponses; /** * Tools for Swagger annotations. * * @author Manuel Boillod. */ public class SwaggerAnnotationUtils { /** Internal logger. */ protected static Logger LOGGER = Logger .getLogger(SwaggerAnnotationUtils.class.getName()); /** * Adds data from the {@link Api} annotation to the resource. * * @param api * The {@link Api} annotation. * @param resource * The {@link Resource} to update. */ public static void processApi(Api api, Resource resource) { if (!StringUtils.isNullOrEmpty(api.value())) { resource.setName(api.value()); } if (!StringUtils.isNullOrEmpty(api.description())) { resource.setDescription(api.description()); } } /** * Adds data from the {@link ApiImplicitParam} annotation to the operation. * * @param apiImplicitParam * The {@link ApiImplicitParam} annotation. * @param operation * The {@link Operation} to update. */ public static void processApiImplicitParam( ApiImplicitParam apiImplicitParam, Operation operation) { QueryParameter parameter = new QueryParameter(); if (!StringUtils.isNullOrEmpty(apiImplicitParam.name())) { parameter.setName(apiImplicitParam.name()); } if (!StringUtils.isNullOrEmpty(apiImplicitParam.value())) { parameter.setDescription(apiImplicitParam.value()); } if (!StringUtils.isNullOrEmpty(apiImplicitParam.defaultValue())) { parameter.setDefaultValue(apiImplicitParam.defaultValue()); } parameter.setRequired(apiImplicitParam.required()); parameter.setAllowMultiple(apiImplicitParam.allowMultiple()); operation.getQueryParameters().add(parameter); } /** * Adds data from the {@link ApiImplicitParams} annotation to the operation. * * @param apiImplicitParams * The {@link ApiImplicitParams} annotation. * @param operation * The {@link Operation} to update. */ public static void processApiImplicitParams( ApiImplicitParams apiImplicitParams, Operation operation) { for (ApiImplicitParam apiImplicitParam : apiImplicitParams.value()) { processApiImplicitParam(apiImplicitParam, operation); } } /** * Adds data from the {@link ApiModel} annotation to the representation. * * @param apiModel * The {@link ApiModel} annotation. * @param representation * The {@link Representation} to update. */ public static void processApiModel(ApiModel apiModel, Representation representation) { if (!StringUtils.isNullOrEmpty(apiModel.value())) { representation.setName(apiModel.value()); } if (!StringUtils.isNullOrEmpty(apiModel.description())) { representation.setDescription(apiModel.description()); } if (apiModel.parent() != null) { representation.setExtendedType(Types.convertPrimitiveType(apiModel .parent())); } } /** * Adds data from the {@link ApiModelProperty} annotation to the * representation property. * * @param apiModelProperty * The {@link ApiModelProperty} annotation. * @param property * The {@link Property} to update. */ public static void processApiModelProperty( ApiModelProperty apiModelProperty, Property property) { if (!StringUtils.isNullOrEmpty(apiModelProperty.value())) { property.setDescription(apiModelProperty.value()); } if (!StringUtils.isNullOrEmpty(apiModelProperty.dataType())) { property.setType(apiModelProperty.dataType()); } if (!StringUtils.isNullOrEmpty(apiModelProperty.allowableValues())) { property.setMinOccurs(1); property.setMaxOccurs(1); } } /** * Adds data from the {@link ApiModelProperty} annotation to the operation. * * @param apiOperation * The {@link com.wordnik.swagger.annotations.ApiOperation} * annotation. * @param resource * The {@link org.restlet.ext.apispark.internal.model.Resource} * to update. * @param operation * The {@link org.restlet.ext.apispark.internal.model.Operation} * to update. */ public static void processApiOperation(ApiOperation apiOperation, Resource resource, Operation operation) { if (!StringUtils.isNullOrEmpty(apiOperation.nickname())) { operation.setName(apiOperation.nickname()); } if (!StringUtils.isNullOrEmpty(apiOperation.value())) { operation.setDescription(apiOperation.value()); } if (!StringUtils.isNullOrEmpty(apiOperation.httpMethod())) { operation.setMethod(apiOperation.httpMethod()); } if (!StringUtils.isNullOrEmpty(apiOperation.tags())) { List<String> tags = StringUtils.splitAndTrim(apiOperation.tags()); for (String tag : tags) { if (!resource.getSections().contains(tag)) { resource.getSections().add(tag); } } } if (!StringUtils.isNullOrEmpty(apiOperation.consumes())) { operation.setConsumes(StringUtils.splitAndTrim(apiOperation .consumes())); } if (!StringUtils.isNullOrEmpty(apiOperation.produces())) { operation.setProduces(StringUtils.splitAndTrim(apiOperation .produces())); } } /** * Adds data from the {@link ApiParam} annotation to the parameter. * * @param apiParam * The {@link ApiParam} annotation. * @param parameter * The {@link Parameter} to update. */ public static void processApiParameter(ApiParam apiParam, Parameter parameter) { if (!StringUtils.isNullOrEmpty(apiParam.name())) { parameter.setName(apiParam.name()); } if (!StringUtils.isNullOrEmpty(apiParam.value())) { parameter.setDescription(apiParam.value()); } if (!StringUtils.isNullOrEmpty(apiParam.defaultValue())) { parameter.setDefaultValue(apiParam.defaultValue()); } parameter.setRequired(apiParam.required()); parameter.setAllowMultiple(apiParam.allowMultiple()); } /** * Adds data from the {@link ApiResponse} annotation to the operation. * * @param apiResponse * The {@link ApiResponse} annotation. * @param operation * The {@link Operation} to update. * @param representationsUsed * The {@link java.lang.Class} of representation used. */ public static void processApiResponse(ApiResponse apiResponse, Operation operation, List<Class<?>> representationsUsed) { List<Response> responses = operation.getResponses(); if (responses == null) { responses = new ArrayList<>(); operation.setResponses(responses); } final int code = apiResponse.code(); Optional<Response> existingResponse = Iterables.tryFind(responses, new Predicate<Response>() { @Override public boolean apply(Response response) { return response.getCode() == code; } }); boolean responseExists = existingResponse.isPresent(); Response response; if (responseExists) { response = existingResponse.get(); } else { response = new Response(); response.setCode(code); } response.setCode(code); response.setName(Status.valueOf(code).getReasonPhrase()); if (!StringUtils.isNullOrEmpty(apiResponse.message())) { response.setDescription(apiResponse.message()); } Class<?> responseClazz = apiResponse.response(); if (responseClazz != null && responseClazz != Void.TYPE && responseClazz != Void.class) { representationsUsed.add(responseClazz); PayLoad payLoad = new PayLoad(); payLoad.setType(Types.convertPrimitiveType(responseClazz)); response.setOutputPayLoad(payLoad); } if (!responseExists) { responses.add(response); } } /** * Adds data from the {@link ApiResponses} annotation to the operation. * * @param apiResponses * The {@link ApiResponses} annotation. * @param operation * The {@link Operation} to update. * @param representationsUsed * The {@link java.lang.Class} of representation used. */ public static void processApiResponses(ApiResponses apiResponses, Operation operation, List<Class<?>> representationsUsed) { for (ApiResponse apiResponse : apiResponses.value()) { processApiResponse(apiResponse, operation, representationsUsed); } } }