@@ -30,6 +30,13 @@ trait JaxrsApiReader extends ClassReader with ClassReaderUtils {
30
30
// In case it's not a subresource locator the entity type is returned
31
31
def findSubresourceType (method : Method ): Class [_]
32
32
33
+ def readRecursive (
34
+ docRoot : String ,
35
+ parentPath : String , cls : Class [_],
36
+ config : SwaggerConfig ,
37
+ operations : ListBuffer [Tuple3 [String , String , ListBuffer [Operation ]]],
38
+ parentMethods : ListBuffer [Method ]): Option [ApiListing ]
39
+
33
40
def processDataType (paramType : Class [_], genericParamType : Type ) = {
34
41
paramType.getName match {
35
42
case " [I" => " Array[int]"
@@ -79,14 +86,17 @@ trait JaxrsApiReader extends ClassReader with ClassReaderUtils {
79
86
parentMethods : ListBuffer [Method ]
80
87
) = {
81
88
val api = method.getAnnotation(classOf [Api ])
82
- val responseClass = {
89
+ val responseClass = if (apiOperation != null ) {
83
90
val baseName = apiOperation.response.getName
84
91
val output = apiOperation.responseContainer match {
85
92
case " " => baseName
86
93
case e : String => " %s[%s]" .format(e, baseName)
87
94
}
88
95
output
89
96
}
97
+ else {
98
+ " void"
99
+ }
90
100
91
101
var paramAnnotations : Array [Array [java.lang.annotation.Annotation ]] = null
92
102
var paramTypes : Array [java.lang.Class [_]] = null
@@ -102,30 +112,35 @@ trait JaxrsApiReader extends ClassReader with ClassReaderUtils {
102
112
genericParamTypes = parentMethods.map(pm => pm.getGenericParameterTypes).reduceRight(_ ++ _) ++ method.getGenericParameterTypes
103
113
}
104
114
105
- val produces = Option (apiOperation.produces) match {
106
- case Some (e) if (e != " " ) => e.split(" ," ).map(_.trim).toList
107
- case _ => method.getAnnotation(classOf [Produces ]) match {
108
- case e : Produces => e.value.toList
109
- case _ => List ()
110
- }
111
- }
112
- val consumes = Option (apiOperation.consumes) match {
113
- case Some (e) if (e != " " ) => e.split(" ," ).map(_.trim).toList
114
- case _ => method.getAnnotation(classOf [Consumes ]) match {
115
- case e : Consumes => e.value.toList
116
- case _ => List ()
115
+ val (produces, consumes, protocols, authorizations) = {
116
+ if (apiOperation != null ) {
117
+ (Option (apiOperation.produces) match {
118
+ case Some (e) if (e != " " ) => e.split(" ," ).map(_.trim).toList
119
+ case _ => method.getAnnotation(classOf [Produces ]) match {
120
+ case e : Produces => e.value.toList
121
+ case _ => List ()
122
+ }
123
+ },
124
+ Option (apiOperation.consumes) match {
125
+ case Some (e) if (e != " " ) => e.split(" ," ).map(_.trim).toList
126
+ case _ => method.getAnnotation(classOf [Consumes ]) match {
127
+ case e : Consumes => e.value.toList
128
+ case _ => List ()
129
+ }
130
+ },
131
+ Option (apiOperation.protocols) match {
132
+ case Some (e) if (e != " " ) => e.split(" ," ).map(_.trim).toList
133
+ case _ => List ()
134
+ },
135
+ Option (apiOperation.authorizations) match {
136
+ case Some (e) => (for (a <- e) yield {
137
+ val scopes = (for (s <- a.scopes) yield com.wordnik.swagger.model.AuthorizationScope (s.scope, s.description)).toArray
138
+ new com.wordnik.swagger.model.Authorization (a.value, scopes)
139
+ }).toList
140
+ case _ => List ()
141
+ })
117
142
}
118
- }
119
- val protocols = Option (apiOperation.protocols) match {
120
- case Some (e) if (e != " " ) => e.split(" ," ).map(_.trim).toList
121
- case _ => List ()
122
- }
123
- val authorizations : List [com.wordnik.swagger.model.Authorization ] = Option (apiOperation.authorizations) match {
124
- case Some (e) => (for (a <- e) yield {
125
- val scopes = (for (s <- a.scopes) yield com.wordnik.swagger.model.AuthorizationScope (s.scope, s.description)).toArray
126
- new com.wordnik.swagger.model.Authorization (a.value, scopes)
127
- }).toList
128
- case _ => List ()
143
+ else ((List (), List (), List (), List ()))
129
144
}
130
145
val params = parentParams ++ (for ((annotations, paramType, genericParamType) <- (paramAnnotations, paramTypes, genericParamTypes).zipped.toList) yield {
131
146
if (annotations.length > 0 ) {
@@ -169,13 +184,18 @@ trait JaxrsApiReader extends ClassReader with ClassReaderUtils {
169
184
}
170
185
}
171
186
187
+ val (summary, notes, position) = {
188
+ if (apiOperation != null ) (apiOperation.value, apiOperation.notes, apiOperation.position)
189
+ else (" " ," " ,0 )
190
+ }
191
+
172
192
Operation (
173
193
parseHttpMethod(method, apiOperation),
174
- apiOperation.value ,
175
- apiOperation. notes,
194
+ summary ,
195
+ notes,
176
196
responseClass,
177
197
method.getName,
178
- apiOperation. position,
198
+ position,
179
199
produces,
180
200
consumes,
181
201
protocols,
@@ -185,7 +205,7 @@ trait JaxrsApiReader extends ClassReader with ClassReaderUtils {
185
205
Option (isDeprecated))
186
206
}
187
207
188
- def readMethod (method : Method , parentParams : List [Parameter ], parentMethods : ListBuffer [Method ]) = {
208
+ def readMethod (method : Method , parentParams : List [Parameter ], parentMethods : ListBuffer [Method ]): Option [ Operation ] = {
189
209
val apiOperation = method.getAnnotation(classOf [ApiOperation ])
190
210
val responseAnnotation = method.getAnnotation(classOf [ApiResponses ])
191
211
val apiResponses = {
@@ -201,7 +221,12 @@ trait JaxrsApiReader extends ClassReader with ClassReaderUtils {
201
221
}
202
222
val isDeprecated = Option (method.getAnnotation(classOf [Deprecated ])).map(m => " true" ).getOrElse(null )
203
223
204
- parseOperation(method, apiOperation, apiResponses, isDeprecated, parentParams, parentMethods)
224
+ val hidden = if (apiOperation != null )
225
+ apiOperation.hidden
226
+ else false
227
+
228
+ if (! hidden) Some (parseOperation(method, apiOperation, apiResponses, isDeprecated, parentParams, parentMethods))
229
+ else None
205
230
}
206
231
207
232
def appendOperation (endpoint : String , path : String , op : Operation , operations : ListBuffer [Tuple3 [String , String , ListBuffer [Operation ]]]) = {
@@ -218,128 +243,9 @@ trait JaxrsApiReader extends ClassReader with ClassReaderUtils {
218
243
case _ => " "
219
244
}
220
245
}
221
-
222
246
readRecursive(docRoot, parentPath.replace(" //" ," /" ), cls, config, new ListBuffer [Tuple3 [String , String , ListBuffer [Operation ]]], new ListBuffer [Method ])
223
247
}
224
248
225
- def readRecursive (
226
- docRoot : String ,
227
- parentPath : String , cls : Class [_],
228
- config : SwaggerConfig ,
229
- operations : ListBuffer [Tuple3 [String , String , ListBuffer [Operation ]]],
230
- parentMethods : ListBuffer [Method ]): Option [ApiListing ] = {
231
- val api = cls.getAnnotation(classOf [Api ])
232
-
233
- // must have @Api annotation to process!
234
- if (api != null ) {
235
- val consumes = Option (api.consumes) match {
236
- case Some (e) if (e != " " ) => e.split(" ," ).map(_.trim).toList
237
- case _ => cls.getAnnotation(classOf [Consumes ]) match {
238
- case e : Consumes => e.value.toList
239
- case _ => List ()
240
- }
241
- }
242
- val produces = Option (api.produces) match {
243
- case Some (e) if (e != " " ) => e.split(" ," ).map(_.trim).toList
244
- case _ => cls.getAnnotation(classOf [Produces ]) match {
245
- case e : Produces => e.value.toList
246
- case _ => List ()
247
- }
248
- }
249
- val protocols = Option (api.protocols) match {
250
- case Some (e) if (e != " " ) => e.split(" ," ).map(_.trim).toList
251
- case _ => List ()
252
- }
253
- val description = api.description match {
254
- case e : String if (e != " " ) => Some (e)
255
- case _ => None
256
- }
257
- // look for method-level annotated properties
258
- val parentParams : List [Parameter ] = (for (field <- getAllFields(cls))
259
- yield {
260
- // only process fields with @ApiParam, @QueryParam, @HeaderParam, @PathParam
261
- if (field.getAnnotation(classOf [QueryParam ]) != null || field.getAnnotation(classOf [HeaderParam ]) != null ||
262
- field.getAnnotation(classOf [HeaderParam ]) != null || field.getAnnotation(classOf [PathParam ]) != null ||
263
- field.getAnnotation(classOf [ApiParam ]) != null ) {
264
- val param = new MutableParameter
265
- param.dataType = field.getType.getName
266
- Option (field.getAnnotation(classOf [ApiParam ])) match {
267
- case Some (annotation) => toAllowableValues(annotation.allowableValues)
268
- case _ =>
269
- }
270
- val annotations = field.getAnnotations
271
- processParamAnnotations(param, annotations)
272
- }
273
- else None
274
- }
275
- ).flatten.toList
276
-
277
- for (method <- cls.getMethods) {
278
- val returnType = findSubresourceType(method)
279
- val path = method.getAnnotation(classOf [Path ]) match {
280
- case e : Path => e.value()
281
- case _ => " "
282
- }
283
- val endpoint = (parentPath + /* api.value + */ pathFromMethod(method)).replace(" //" , " /" )
284
- Option (returnType.getAnnotation(classOf [Api ])) match {
285
- case Some (e) => {
286
- val root = docRoot + api.value + pathFromMethod(method)
287
- parentMethods += method
288
- readRecursive(root, endpoint, returnType, config, operations, parentMethods)
289
- parentMethods -= method
290
- }
291
- case _ => {
292
- if (method.getAnnotation(classOf [ApiOperation ]) != null ) {
293
- val op = readMethod(method, parentParams, parentMethods)
294
- appendOperation(endpoint, path, op, operations)
295
- }
296
- }
297
- }
298
- }
299
- // sort them by min position in the operations
300
- val s = (for (op <- operations) yield {
301
- (op, op._3.map(_.position).toList.min)
302
- }).sortWith(_._2 < _._2).toList
303
- val orderedOperations = new ListBuffer [Tuple3 [String , String , ListBuffer [Operation ]]]
304
- s.foreach(op => {
305
- val ops = op._1._3.sortWith(_.position < _.position)
306
- orderedOperations += Tuple3 (op._1._1, op._1._2, ops)
307
- })
308
- val apis = (for ((endpoint, resourcePath, operationList) <- orderedOperations) yield {
309
- val orderedOperations = new ListBuffer [Operation ]
310
- operationList.sortWith(_.position < _.position).foreach(e => orderedOperations += e)
311
- ApiDescription (
312
- addLeadingSlash(endpoint),
313
- None ,
314
- orderedOperations.toList)
315
- }).toList
316
-
317
- val authorizations : List [com.wordnik.swagger.model.Authorization ] = Option (api.authorizations) match {
318
- case Some (e) => (for (a <- e) yield {
319
- val scopes = (for (s <- a.scopes) yield com.wordnik.swagger.model.AuthorizationScope (s.scope, s.description)).toArray
320
- new com.wordnik.swagger.model.Authorization (a.value, scopes)
321
- }).toList
322
- case _ => List ()
323
- }
324
- val models = ModelUtil .modelsFromApis(apis)
325
- Some (ApiListing (
326
- apiVersion = config.apiVersion,
327
- swaggerVersion = config.swaggerVersion,
328
- basePath = config.basePath,
329
- resourcePath = addLeadingSlash(api.value),
330
- apis = ModelUtil .stripPackages(apis),
331
- models = models,
332
- description = description,
333
- produces = produces,
334
- consumes = consumes,
335
- protocols = protocols,
336
- authorizations = authorizations,
337
- position = api.position)
338
- )
339
- }
340
- else None
341
- }
342
-
343
249
def getAllFields (cls : Class [_]): List [Field ] = {
344
250
var fields = cls.getDeclaredFields().toList;
345
251
if (cls.getSuperclass() != null ) {
@@ -379,7 +285,7 @@ trait JaxrsApiReader extends ClassReader with ClassReaderUtils {
379
285
}
380
286
381
287
def parseHttpMethod (method : Method , op : ApiOperation ): String = {
382
- if (op.httpMethod() != null && op.httpMethod().trim().length() > 0 )
288
+ if (op != null && op .httpMethod() != null && op.httpMethod().trim().length() > 0 )
383
289
op.httpMethod().trim
384
290
else {
385
291
if (method.getAnnotation(classOf [GET ]) != null ) " GET"
0 commit comments