Java tutorial
package org.motechproject.mds.docs.swagger; import ch.lambdaj.Lambda; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.apache.commons.lang.StringUtils; import org.motechproject.mds.docs.RestDocumentationGenerator; import org.motechproject.mds.docs.swagger.gson.ParameterTypeAdapter; import org.motechproject.mds.docs.swagger.model.Definition; import org.motechproject.mds.docs.swagger.model.Info; import org.motechproject.mds.docs.swagger.model.License; import org.motechproject.mds.docs.swagger.model.Parameter; import org.motechproject.mds.docs.swagger.model.ParameterType; import org.motechproject.mds.docs.swagger.model.PathEntry; import org.motechproject.mds.docs.swagger.model.Property; import org.motechproject.mds.docs.swagger.model.Response; import org.motechproject.mds.docs.swagger.model.ResponseWithSchema; import org.motechproject.mds.docs.swagger.model.SwaggerModel; import org.motechproject.mds.domain.Entity; import org.motechproject.mds.domain.Field; import org.motechproject.mds.domain.Lookup; import org.motechproject.mds.domain.RestOptions; import org.motechproject.mds.dto.LookupFieldType; import org.motechproject.mds.repository.internal.AllEntities; import org.motechproject.mds.util.ClassName; import org.motechproject.mds.util.Constants; import org.motechproject.mds.util.LookupName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.MessageSource; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.io.Writer; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.API_DESCRIPTION_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.ARRAY_TYPE; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.BASE_PATH_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.BLOB_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.CREATE_BODY_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.CREATE_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.CREATE_ID_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.DELETE_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.DELETE_ID_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.DELETE_ID_PARAM_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.HTTP; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.ID_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.ID_PATHVAR; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.INCLUDE_BLOB_PARAM; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.INT32_FORMAT; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.INT64_FORMAT; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.INTEGER_TYPE; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.LICENSE_NAME_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.LICENSE_URL_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.LOOKUP_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.NO_ENTITY_IS_EXPOSED_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.ORDER_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.ORDER_DIR_PARAM; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.PAGESIZE_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.PAGE_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.PAGE_PARAM; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.PAGE_SIZE_PARAM; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.RANGE_PARAM_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.READ_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.READ_ID_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.REF; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.RESPONSE_BAD_REQUEST_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.RESPONSE_DELETE_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.RESPONSE_FORBIDDEN_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.RESPONSE_LIST_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.RESPONSE_LOOKUP_NOT_FOUND_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.RESPONSE_NEW_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.RESPONSE_NOT_FOUND_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.RESPONSE_SINGLE_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.RESPONSE_UPDATED_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.REST_API_DOCS_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.REST_API_DOCS_URL_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.SET_PARAM_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.SORT_BY_PARAM; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.SORT_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.STRING_TYPE; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.TITLE_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.UPDATE_BODY_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.UPDATE_DESC_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.UPDATE_ID_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.VERSION_KEY; import static org.motechproject.mds.docs.swagger.model.SwaggerConstants.V_2; /** * A REST API documentation generator for Swagger - http://swagger.io/. * Generates a spec file in the Swagger JSON format. Gson is used for generating * the JSON file. */ @Service public class SwaggerGenerator implements RestDocumentationGenerator { private static final Logger LOGGER = LoggerFactory.getLogger(SwaggerGenerator.class); private MessageSource messageSource; private AllEntities allEntities; private Properties swaggerProperties; @Override public void generateDocumentation(Writer writer, String serverPrefix, Locale locale) { LOGGER.info("Generating REST documentation"); SwaggerModel swaggerModel = initialSwaggerModel(serverPrefix, locale); swaggerModel.addDefinition("Metadata", buildMetadataDefinition()); for (Entity entity : allEntities.retrieveAll()) { addCrudEndpoints(swaggerModel, entity, locale); addLookupEndpoints(swaggerModel, entity, locale); addDefinitions(swaggerModel, entity); } if (swaggerModel.getDefinitions().size() == 1) { swaggerModel.getInfo() .setDescription(String.format("%s \n\n**%s [%s](%s)**", msg(locale, API_DESCRIPTION_KEY), msg(locale, NO_ENTITY_IS_EXPOSED_KEY), msg(locale, REST_API_DOCS_KEY), property(REST_API_DOCS_URL_KEY))); } Gson gson = buildGson(); gson.toJson(swaggerModel, writer); } private void addCrudEndpoints(SwaggerModel swaggerModel, Entity entity, Locale locale) { final String entityPath = ClassName.restUrl(entity.getName(), entity.getModule(), entity.getNamespace()); RestOptions restOptions = restOptionsOrDefault(entity); if (restOptions.isAllowRead()) { // retrieveAll and retrieveById swaggerModel.addPathEntry(entityPath, HttpMethod.GET, readPathEntry(entity, locale)); } if (restOptions.isAllowCreate()) { // post new item swaggerModel.addPathEntry(entityPath, HttpMethod.POST, postPathEntry(entity, locale)); } if (restOptions.isAllowUpdate()) { // update an existing item swaggerModel.addPathEntry(entityPath, HttpMethod.PUT, putPathEntry(entity, locale)); } if (restOptions.isAllowDelete()) { // delete an item swaggerModel.addPathEntry(entityPath + ID_PATHVAR, HttpMethod.DELETE, deletePathEntry(entity, locale)); } } private void addLookupEndpoints(SwaggerModel swaggerModel, Entity entity, Locale locale) { for (Lookup lookup : entity.getLookupsExposedByRest()) { String lookupUrl = ClassName.restLookupUrl(entity.getName(), entity.getModule(), entity.getNamespace(), lookup.getMethodName()); swaggerModel.addPathEntry(lookupUrl, HttpMethod.GET, lookupPathEntry(entity, lookup, locale)); } } private void addDefinitions(SwaggerModel swaggerModel, Entity entity) { RestOptions restOptions = restOptionsOrDefault(entity); if (restOptions.supportsAnyOperation() || !entity.getLookupsExposedByRest().isEmpty()) { // all fields, including generated ones swaggerModel.addDefinition(entity.getClassName(), definition(entity, true, true)); swaggerModel.addDefinition(entity.getClassName() + "-WithMetadata", definitionWithMetadata(entity)); } if (restOptions.isAllowCreate()) { // no auto-generated fields swaggerModel.addDefinition(definitionNewName(entity.getClassName()), definition(entity, false, false)); } if (restOptions.isAllowUpdate()) { // no auto-generated fields, except ID swaggerModel.addDefinition(definitionUpdateName(entity.getClassName()), definition(entity, false, true)); } } private SwaggerModel initialSwaggerModel(String serverPrefix, Locale locale) { SwaggerModel swaggerModel = new SwaggerModel(); swaggerModel.setSwagger(V_2); swaggerModel.setBasePath(serverPrefix + property(BASE_PATH_KEY)); swaggerModel.setInfo(mdsApiInfo(locale)); swaggerModel.setSchemes(Arrays.asList(HTTP)); swaggerModel.setProduces(json()); swaggerModel.setConsumes(json()); return swaggerModel; } private Info mdsApiInfo(Locale locale) { Info info = new Info(); info.setVersion(property(VERSION_KEY)); info.setDescription(msg(locale, API_DESCRIPTION_KEY)); info.setTitle(property(TITLE_KEY)); info.setLicense(motechLicense()); return info; } private License motechLicense() { return new License(property(LICENSE_NAME_KEY), property(LICENSE_URL_KEY)); } private PathEntry readPathEntry(Entity entity, Locale locale) { final PathEntry pathEntry = new PathEntry(); final String entityName = entity.getName(); pathEntry.setDescription(msg(locale, READ_DESC_KEY, entityName)); pathEntry.setOperationId(msg(locale, READ_ID_KEY, entityName)); pathEntry.setProduces(json()); pathEntry.addTag(entity.getClassName()); pathEntry.setParameters(queryParamsParameters(entity.getFieldsExposedByRest(), locale)); pathEntry.addParameter(idQueryParameter(locale)); pathEntry.addResponse(HttpStatus.OK, readResponse(entity, locale)); addCommonResponses(pathEntry, locale); return pathEntry; } private PathEntry postPathEntry(Entity entity, Locale locale) { final PathEntry pathEntry = new PathEntry(); final String entityName = entity.getName(); pathEntry.setDescription(msg(locale, CREATE_DESC_KEY, entityName)); pathEntry.setOperationId(msg(locale, CREATE_ID_KEY, entityName)); pathEntry.setProduces(json()); pathEntry.addTag(entity.getClassName()); pathEntry.addParameter(newEntityParameter(entity, locale)); pathEntry.addResponse(HttpStatus.OK, newItemResponse(entity, locale)); addCommonResponses(pathEntry, locale); return pathEntry; } private PathEntry putPathEntry(Entity entity, Locale locale) { final PathEntry pathEntry = new PathEntry(); final String entityName = entity.getName(); pathEntry.setDescription(msg(locale, UPDATE_DESC_KEY, entityName)); pathEntry.setOperationId(msg(locale, UPDATE_ID_KEY, entityName)); pathEntry.setProduces(json()); pathEntry.addTag(entity.getClassName()); pathEntry.addParameter(updateEntityParameter(entity, locale)); addCommonResponses(pathEntry, locale); pathEntry.addResponse(HttpStatus.OK, updatedItemResponse(entity, locale)); pathEntry.addResponse(HttpStatus.NOT_FOUND, notFoundResponse(entity, locale)); return pathEntry; } private PathEntry deletePathEntry(Entity entity, Locale locale) { final PathEntry pathEntry = new PathEntry(); final String entityName = entity.getName(); pathEntry.setDescription(msg(locale, DELETE_DESC_KEY, entityName)); pathEntry.setOperationId(msg(locale, DELETE_ID_KEY, entityName)); pathEntry.setProduces(json()); pathEntry.addTag(entity.getClassName()); pathEntry.addParameter(deleteIdPathParameter(locale)); addCommonResponses(pathEntry, locale); pathEntry.addResponse(HttpStatus.OK, deleteResponse(entity, locale)); return pathEntry; } private PathEntry lookupPathEntry(Entity entity, Lookup lookup, Locale locale) { final PathEntry pathEntry = new PathEntry(); pathEntry.setDescription(msg(locale, LOOKUP_DESC_KEY, lookup.getLookupName())); pathEntry.setOperationId(lookup.getMethodName()); pathEntry.setProduces(json()); pathEntry.addTag(entity.getClassName()); pathEntry.setParameters(lookupParameters(entity, lookup, locale)); pathEntry.addResponse(HttpStatus.OK, lookupResponse(entity, lookup, locale)); addCommonResponses(pathEntry, locale); if (lookup.isSingleObjectReturn()) { pathEntry.addResponse(HttpStatus.NOT_FOUND, lookup404Response(entity, locale)); } return pathEntry; } private void addCommonResponses(PathEntry pathEntry, Locale locale) { pathEntry.addResponse(HttpStatus.BAD_REQUEST, badRequestResponse(locale)); pathEntry.addResponse(HttpStatus.FORBIDDEN, forbiddenResponse(locale)); } private Field getRelatedField(String entityClassName, String fieldName) { Entity entity = allEntities.retrieveByClassName(entityClassName); return entity.getField(fieldName); } private List<Parameter> lookupParameters(Entity entity, Lookup lookup, Locale locale) { List<Parameter> parameters = new ArrayList<>(); for (String lookupFieldName : lookup.getFieldsOrder()) { LookupFieldType lookupFieldType = lookup.getLookupFieldType(lookupFieldName); Field lookupField; if (lookupFieldName.contains(".")) { lookupField = getRelatedField( lookup.getLookupFieldByName(LookupName.getFieldName(lookupFieldName)) .getMetadata(Constants.MetadataKeys.RELATED_CLASS).getValue(), LookupName.getRelatedFieldName(lookupFieldName)); } else { lookupField = lookup.getLookupFieldByName(lookupFieldName); } String paramDesc = lookupParamDescription(lookupField, lookupFieldType, locale); Parameter parameter = SwaggerFieldConverter.lookupParameter(lookupFieldName, lookupField, lookupFieldType, paramDesc); parameters.add(parameter); } parameters.addAll(queryParamsParameters(entity.getFieldsExposedByRest(), locale)); return parameters; } private List<Parameter> queryParamsParameters(List<Field> restExposedFields, Locale locale) { final List<Parameter> parameters = new ArrayList<>(); parameters.add(pageParameter(locale)); parameters.add(pageSizeParameter(locale)); parameters.add(sortParameter(restExposedFields, locale)); parameters.add(orderParameter(locale)); if (hasBlobField(restExposedFields)) { parameters.add(includeBlobParameter(locale)); } return parameters; } private boolean hasBlobField(List<Field> fields) { for (Field field : fields) { if (field.getType().isBlob()) { return true; } } return false; } private Parameter idQueryParameter(Locale locale) { return queryParameter(Constants.Util.ID_FIELD_NAME, msg(locale, ID_DESC_KEY), INTEGER_TYPE, INT64_FORMAT); } private Parameter deleteIdPathParameter(Locale locale) { return pathParameter(Constants.Util.ID_FIELD_NAME, msg(locale, DELETE_ID_PARAM_KEY), INTEGER_TYPE, INT64_FORMAT); } private Parameter newEntityParameter(Entity entity, Locale locale) { return bodyParameter(entity.getName(), msg(locale, CREATE_BODY_DESC_KEY, entity.getName()), definitionNewPath(entity.getClassName())); } private Parameter updateEntityParameter(Entity entity, Locale locale) { return bodyParameter(entity.getName(), msg(locale, UPDATE_BODY_DESC_KEY, entity.getName()), definitionUpdatePath(entity.getClassName())); } private Parameter pageParameter(Locale locale) { return queryParameter(PAGE_PARAM, msg(locale, PAGE_DESC_KEY), INTEGER_TYPE, INT32_FORMAT); } private Parameter pageSizeParameter(Locale locale) { return queryParameter(PAGE_SIZE_PARAM, msg(locale, PAGESIZE_DESC_KEY), INTEGER_TYPE, INT32_FORMAT); } private Parameter sortParameter(List<Field> restExposedFields, Locale locale) { Parameter sortParameter = queryParameter(SORT_BY_PARAM, msg(locale, SORT_DESC_KEY), STRING_TYPE); List<String> restExposedFieldNames = Lambda.extract(restExposedFields, Lambda.on(Field.class).getName()); sortParameter.setEnumValues(restExposedFieldNames); return sortParameter; } private Parameter orderParameter(Locale locale) { Parameter orderParameter = queryParameter(ORDER_DIR_PARAM, msg(locale, ORDER_DESC_KEY), STRING_TYPE); orderParameter.setEnumValues(Arrays.asList("Ascending", "Descending")); return orderParameter; } private Parameter includeBlobParameter(Locale locale) { Parameter includeBlobParameter = queryParameter(INCLUDE_BLOB_PARAM, msg(locale, BLOB_DESC_KEY), STRING_TYPE); includeBlobParameter.setEnumValues(Arrays.asList("true", "false")); return includeBlobParameter; } private Parameter queryParameter(String name, String description, String type) { return queryParameter(name, description, type, null); } private Parameter queryParameter(String name, String description, String type, String format) { return parameter(name, description, type, format, ParameterType.QUERY, false); } private Parameter pathParameter(String name, String description, String type, String format) { return parameter(name, description, type, format, ParameterType.PATH, true); } private Parameter parameter(String name, String description, String type, String format, ParameterType in, boolean required) { final Parameter param = new Parameter(); param.setName(name); param.setDescription(description); param.setIn(in); param.setRequired(required); param.setType(type); param.setFormat(format); return param; } private Parameter bodyParameter(String name, String description, String ref) { final Parameter bodyParameter = new Parameter(); bodyParameter.setName(name); bodyParameter.setDescription(description); bodyParameter.setIn(ParameterType.BODY); bodyParameter.setRequired(true); bodyParameter.addSchema(REF, ref); return bodyParameter; } private Response lookupResponse(Entity entity, Lookup lookup, Locale locale) { if (lookup.isSingleObjectReturn()) { return new ResponseWithSchema(msg(locale, RESPONSE_SINGLE_DESC_KEY, entity.getName()), definitionWithMetadataPath(entity.getClassName())); } else { return new ResponseWithSchema(msg(locale, RESPONSE_LIST_DESC_KEY, entity.getName()), definitionWithMetadataPath(entity.getClassName())); } } private Response lookup404Response(Entity entity, Locale locale) { return new Response(msg(locale, RESPONSE_LOOKUP_NOT_FOUND_KEY, entity.getName())); } private Response readResponse(Entity entity, Locale locale) { return new ResponseWithSchema(msg(locale, RESPONSE_LIST_DESC_KEY, entity.getName()), definitionWithMetadataPath(entity.getClassName())); } private Response newItemResponse(Entity entity, Locale locale) { return new ResponseWithSchema(msg(locale, RESPONSE_NEW_DESC_KEY, entity.getName()), definitionPath(entity.getClassName())); } private Response updatedItemResponse(Entity entity, Locale locale) { return new ResponseWithSchema(msg(locale, RESPONSE_UPDATED_DESC_KEY, entity.getName()), definitionPath(entity.getClassName())); } private Response deleteResponse(Entity entity, Locale locale) { return new Response(msg(locale, RESPONSE_DELETE_DESC_KEY, entity.getName())); } private Response notFoundResponse(Entity entity, Locale locale) { return new Response(msg(locale, RESPONSE_NOT_FOUND_KEY, entity.getName())); } private Response badRequestResponse(Locale locale) { return new Response(msg(locale, RESPONSE_BAD_REQUEST_KEY)); } private Response forbiddenResponse(Locale locale) { return new Response(msg(locale, RESPONSE_FORBIDDEN_KEY)); } private Definition definition(Entity entity, boolean includeAuto, boolean includeId) { final Definition definition = new Definition(); final List<String> required = new ArrayList<>(); final Map<String, Property> properties = new LinkedHashMap<>(); buildDefinitionProperties(properties, required, entity, includeAuto, includeId); definition.setRequired(required); definition.setProperties(properties); return definition; } private Definition definitionWithMetadata(Entity entity) { final Definition definition = new Definition(); Property metadata = new Property(); metadata.setRef(definitionPath("Metadata")); Property data = new Property(ARRAY_TYPE); data.setRef(definitionPath(entity.getClassName())); final Map<String, Property> properties = new LinkedHashMap<>(); properties.put("metadata", metadata); properties.put("data", data); final List<String> required = new ArrayList<>(); required.add("metadata"); required.add("data"); definition.setProperties(properties); definition.setRequired(required); return definition; } private void buildDefinitionProperties(Map<String, Property> properties, List<String> required, Entity entity, boolean includeAuto, boolean includeId) { if (includeId) { properties.put(Constants.Util.ID_FIELD_NAME, new Property(INTEGER_TYPE, INT64_FORMAT)); } for (Field field : entity.getFields()) { final String fieldName = field.getName(); if (field.isExposedViaRest()) { // auto generated fields included only in responses if (!field.isAutoGenerated() || includeAuto) { Property property = SwaggerFieldConverter.fieldToProperty(field); properties.put(fieldName, property); if (field.isRequired()) { required.add(fieldName); } } } } } private Definition buildMetadataDefinition() { final Definition definition = new Definition(); final Map<String, Property> properties = new LinkedHashMap<>(); properties.put("entity", new Property(STRING_TYPE)); properties.put("className", new Property(STRING_TYPE)); properties.put("module", new Property(STRING_TYPE)); properties.put("namespace", new Property(STRING_TYPE)); properties.put("totalCount", new Property(INTEGER_TYPE, INT64_FORMAT)); properties.put("page", new Property(INTEGER_TYPE, INT32_FORMAT)); properties.put("pageSize", new Property(INTEGER_TYPE, INT32_FORMAT)); final List<String> required = new ArrayList<>(); required.add("totalCount"); required.add("page"); required.add("pageSize"); required.add("module"); required.add("entity"); required.add("namespace"); required.add("className"); definition.setProperties(properties); definition.setRequired(required); return definition; } private List<String> json() { return Arrays.asList(MediaType.APPLICATION_JSON_VALUE); } private String definitionPath(String value) { return String.format("#/definitions/%s", value); } private String definitionNewPath(String entityClassName) { return "#/definitions/" + definitionNewName(entityClassName); } private String definitionUpdatePath(String entityClassName) { return "#/definitions/" + definitionUpdateName(entityClassName); } private String definitionNewName(String entityClassName) { return entityClassName + "-new"; } private String definitionUpdateName(String entityClassName) { return definitionNewName(entityClassName) + "-withId"; } private String definitionWithMetadataPath(String entityClassName) { return definitionPath(entityClassName + "-WithMetadata"); } private String lookupParamDescription(Field field, LookupFieldType lookupFieldType, Locale locale) { // start with tooltip or name if tooltip is not defined // for sets and ranges append appropriate info StringBuilder desc = new StringBuilder( StringUtils.isNotBlank(field.getTooltip()) ? field.getTooltip() : field.getName()); switch (lookupFieldType) { case SET: desc.append(" - ").append(msg(locale, SET_PARAM_DESC_KEY)); break; case RANGE: desc.append(" - ").append(msg(locale, RANGE_PARAM_DESC_KEY)); break; default: break; } return desc.toString(); } private String property(String key) { return swaggerProperties.getProperty(key); } private String msg(Locale locale, String key, Object... args) { return messageSource.getMessage(key, args, locale); } private RestOptions restOptionsOrDefault(Entity entity) { RestOptions restOptions = entity.getRestOptions(); if (restOptions == null) { // everything off restOptions = new RestOptions(); } return restOptions; } private Gson buildGson() { return new GsonBuilder().registerTypeAdapter(ParameterType.class, new ParameterTypeAdapter()) .setPrettyPrinting().create(); } @Autowired @Qualifier("swaggerProperties") public void setSwaggerProperties(Properties swaggerProperties) { this.swaggerProperties = swaggerProperties; } @Autowired public void setAllEntities(AllEntities allEntities) { this.allEntities = allEntities; } @Resource(name = "swaggerMessageSource") public void setSwaggerMessageSource(MessageSource messageSource) { this.messageSource = messageSource; } }