Skip to content

Instantly share code, notes, and snippets.

@lucasweb78
Last active August 29, 2015 13:57
Show Gist options
  • Save lucasweb78/9626380 to your computer and use it in GitHub Desktop.
Save lucasweb78/9626380 to your computer and use it in GitHub Desktop.
Custom Swagger Model Converter that hides model properties that have methods annotated with a ApiModelProperty(access = "hidden") annotation.
package uk.co.lucasweb.swagger;
import com.wordnik.swagger.annotations.ApiModelProperty;
import com.wordnik.swagger.converter.SwaggerSchemaConverter;
import com.wordnik.swagger.model.Model;
import org.apache.log4j.Logger;
import scala.Option;
import scala.collection.immutable.Map;
import javax.xml.bind.annotation.XmlElement;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
/**
* Applies application specific rules to the model generated by Swagger.
* <p/>
* Processes all methods annotated with ApiModelProperty. Supports discovering the field name from the XmlElement annotation if present
* otherwise uses bean introspection to determine the field name.
* <p/>
* Applies the following rules:
* <p/>
* <ul>
* <li>Hides model properties that have methods annotated with ApiModelProperty(access = "hidden")</li>
* </ul>
*
* @author Richard Lucas
*/
public class CustomSwaggerModelConverter extends SwaggerSchemaConverter {
private static final Logger log = Logger.getLogger(CustomSwaggerModelConverter.class);
@Override
public Option<Model> read(Class<?> modelClass, Map<String, String> typeMap) {
Option<Model> modelOption = super.read(modelClass, typeMap);
Class<?> currentClass = modelClass;
while (currentClass.getSuperclass() != null) {
for (Method method : modelClass.getDeclaredMethods()) {
processApiModelPropertyMethods(currentClass, method, modelOption);
}
currentClass = currentClass.getSuperclass();
}
return modelOption;
}
private void processApiModelPropertyMethods(Class<?> currentClass, Method method, Option<Model> modelOption) {
try {
if (method.isAnnotationPresent(ApiModelProperty.class)) {
hideFieldsWithHiddenAccess(currentClass, method, modelOption);
}
} catch (SecurityException e) {
log.error("Failed to process method", e);
}
}
private void hideFieldsWithHiddenAccess(Class<?> currentClass, Method method, Option<Model> modelOption) {
if (!method.getAnnotation(ApiModelProperty.class).access().isEmpty() && method.getAnnotation(ApiModelProperty.class).access().equals("hidden")) {
String fieldName;
if (method.isAnnotationPresent(XmlElement.class) && !method.getAnnotation(XmlElement.class).name().isEmpty()) {
fieldName = method.getAnnotation(XmlElement.class).name();
} else {
fieldName = getFieldNameFromMethod(currentClass, method);
}
if (fieldName != null) {
modelOption.get().properties().remove(fieldName);
}
}
}
private String getFieldNameFromMethod(Class<?> currentClass, Method method) {
try {
for (PropertyDescriptor propertyDescriptor : Introspector.getBeanInfo(currentClass).getPropertyDescriptors()) {
if (propertyDescriptor.getReadMethod().getName().equals(method.getName())) {
return propertyDescriptor.getName();
}
}
} catch (IntrospectionException e) {
log.error("Failed to get field name", e);
}
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment