From 0fbd0fd2585226d3725327afc3e664716c29045f Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Thu, 4 Oct 2018 15:10:55 -0700 Subject: Move remaining swagger utility to rest project --- src/main/scala/xyz/driver/core/swagger.scala | 164 --------------------------- 1 file changed, 164 deletions(-) delete mode 100644 src/main/scala/xyz/driver/core/swagger.scala (limited to 'src') diff --git a/src/main/scala/xyz/driver/core/swagger.scala b/src/main/scala/xyz/driver/core/swagger.scala deleted file mode 100644 index 0c1e15d..0000000 --- a/src/main/scala/xyz/driver/core/swagger.scala +++ /dev/null @@ -1,164 +0,0 @@ -package xyz.driver.core - -import java.lang.annotation.Annotation -import java.lang.reflect.Type -import java.util - -import com.fasterxml.jackson.databind.{BeanDescription, ObjectMapper} -import com.fasterxml.jackson.databind.`type`.ReferenceType -import io.swagger.converter._ -import io.swagger.jackson.AbstractModelConverter -import io.swagger.models.{Model, ModelImpl} -import io.swagger.models.properties._ -import io.swagger.util.{Json, PrimitiveType} -import spray.json._ - -object swagger { - - def configureCustomSwaggerModels( - customPropertiesExamples: Map[Class[_], Property], - customObjectsExamples: Map[Class[_], JsValue]) = { - ModelConverters - .getInstance() - .addConverter(new CustomSwaggerJsonConverter(Json.mapper(), customPropertiesExamples, customObjectsExamples)) - } - - object CustomSwaggerJsonConverter { - - def stringProperty(pattern: Option[String] = None, example: Option[String] = None): Property = { - make(new StringProperty()) { sp => - sp.required(true) - example.foreach(sp.example) - pattern.foreach(sp.pattern) - } - } - - def enumProperty[V](values: V*): Property = { - make(new StringProperty()) { sp => - for (v <- values) sp._enum(v.toString) - sp.setRequired(true) - } - } - - def numericProperty(example: Option[AnyRef] = None): Property = { - make(PrimitiveType.DECIMAL.createProperty()) { dp => - dp.setRequired(true) - example.foreach(dp.setExample) - } - } - - def booleanProperty(): Property = { - make(new BooleanProperty()) { bp => - bp.setRequired(true) - } - } - } - - @SuppressWarnings(Array("org.wartremover.warts.Null")) - class CustomSwaggerJsonConverter( - mapper: ObjectMapper, - customProperties: Map[Class[_], Property], - customObjects: Map[Class[_], JsValue]) - extends AbstractModelConverter(mapper) { - import CustomSwaggerJsonConverter._ - - override def resolveProperty( - `type`: Type, - context: ModelConverterContext, - annotations: Array[Annotation], - chain: util.Iterator[ModelConverter]): Property = { - val javaType = Json.mapper().constructType(`type`) - - Option(javaType.getRawClass) - .flatMap { cls => - customProperties.get(cls) - } - .orElse { - `type` match { - case rt: ReferenceType if isOption(javaType.getRawClass) && chain.hasNext => - val nextType = rt.getContentType - val nextResolved = Option(resolveProperty(nextType, context, annotations, chain)).getOrElse( - chain.next().resolveProperty(nextType, context, annotations, chain)) - nextResolved.setRequired(false) - Option(nextResolved) - case t if chain.hasNext => - val nextResolved = chain.next().resolveProperty(t, context, annotations, chain) - nextResolved.setRequired(true) - Option(nextResolved) - case _ => - Option.empty[Property] - } - } - .orNull - } - - @SuppressWarnings(Array("org.wartremover.warts.Null")) - override def resolve(`type`: Type, context: ModelConverterContext, chain: util.Iterator[ModelConverter]): Model = { - - val javaType = Json.mapper().constructType(`type`) - - (getEnumerationInstance(javaType.getRawClass) match { - case Some(_) => Option.empty[Model] // ignore scala enums - case None => - val customObjectModel = customObjects.get(javaType.getRawClass).map { objectExampleJson => - val properties = objectExampleJson.asJsObject.fields.mapValues(parseJsonValueToSwaggerProperty).flatMap { - case (key, value) => value.map(v => key -> v) - } - - val beanDesc = _mapper.getSerializationConfig.introspect[BeanDescription](javaType) - val name = _typeName(javaType, beanDesc) - - make(new ModelImpl()) { model => - model.name(name) - properties.foreach { case (field, property) => model.addProperty(field, property) } - } - } - - customObjectModel.orElse { - if (chain.hasNext) { - val next = chain.next() - Option(next.resolve(`type`, context, chain)) - } else { - Option.empty[Model] - } - } - }).orNull - } - - private def parseJsonValueToSwaggerProperty(jsValue: JsValue): Option[Property] = { - import scala.collection.JavaConverters._ - - jsValue match { - case JsArray(elements) => - elements.headOption.flatMap(parseJsonValueToSwaggerProperty).map { itemProperty => - new ArrayProperty(itemProperty) - } - case JsObject(subFields) => - val subProperties = subFields.mapValues(parseJsonValueToSwaggerProperty).flatMap { - case (key, value) => value.map(v => key -> v) - } - Option(new ObjectProperty(subProperties.asJava)) - case JsBoolean(_) => Option(booleanProperty()) - case JsNumber(value) => Option(numericProperty(example = Option(value))) - case JsString(value) => Option(stringProperty(example = Option(value))) - case _ => Option.empty[Property] - } - } - - private def getEnumerationInstance(cls: Class[_]): Option[Enumeration] = { - if (cls.getFields.map(_.getName).contains("MODULE$")) { - val javaUniverse = scala.reflect.runtime.universe - val m = javaUniverse.runtimeMirror(Thread.currentThread().getContextClassLoader) - val moduleMirror = m.reflectModule(m.staticModule(cls.getName)) - moduleMirror.instance match { - case enumInstance: Enumeration => Some(enumInstance) - case _ => None - } - } else { - None - } - } - - private def isOption(cls: Class[_]): Boolean = cls.equals(classOf[scala.Option[_]]) - } -} -- cgit v1.2.3