1+ package io .swagger .parser ;
2+
3+ import io .swagger .parser .util .RemoteUrl ;
4+
5+ import com .wordnik .swagger .util .Json ;
6+ import com .wordnik .swagger .models .*;
7+ import com .wordnik .swagger .models .parameters .*;
8+ import com .wordnik .swagger .models .properties .*;
9+ import com .wordnik .swagger .models .auth .AuthorizationValue ;
10+
11+ import com .fasterxml .jackson .databind .JsonNode ;
12+
13+ import org .slf4j .Logger ;
14+ import org .slf4j .LoggerFactory ;
15+
16+ import java .util .ServiceLoader ;
17+ import java .util .*;
18+ import java .io .IOException ;
19+
20+ public class SwaggerResolver {
21+ Logger LOGGER = LoggerFactory .getLogger (SwaggerResolver .class );
22+ protected Swagger swagger ;
23+ protected Map <String , ResolutionContext > resolutionMap = new HashMap <String , ResolutionContext >();
24+
25+ protected ResolverOptions opts ;
26+ public SwaggerResolver (){}
27+ public SwaggerResolver (ResolverOptions opts ) {
28+ this .opts = opts ;
29+ }
30+ public Swagger resolve (Swagger swagger , List <AuthorizationValue > auths ) {
31+ if (swagger == null )
32+ return null ;
33+
34+ this .swagger = swagger ;
35+
36+ // models
37+ detectModelRefs ();
38+
39+ // operations
40+ detectOperationRefs ();
41+
42+ applyResolutions (auths );
43+ return this .swagger ;
44+ }
45+
46+ public void applyResolutions (List <AuthorizationValue > auths ) {
47+ // hosts to call
48+ Map <String , List <Object >> hostToObjectMap = new HashMap <String , List <Object >>();
49+
50+ for (String path : resolutionMap .keySet ()) {
51+ String [] parts = path .split ("#" );
52+ if (parts .length == 2 ) {
53+ String host = parts [0 ];
54+ String definitionPath = parts [1 ];
55+ List <Object > objectList = hostToObjectMap .get (host );
56+ if (objectList == null ) {
57+ objectList = new ArrayList <Object >();
58+ hostToObjectMap .put (host , objectList );
59+ }
60+ ResolutionContext ctx = resolutionMap .get (path );
61+
62+ Object mapping = ctx .object ;
63+ Object target = ctx .parent ;
64+ try {
65+ String contents = null ;
66+ if (host .startsWith ("http" ))
67+ contents = new RemoteUrl ().urlToString (host , auths );
68+ else
69+ contents = Json .mapper ().writeValueAsString (swagger );
70+ JsonNode location = null ;
71+ String locationName = null ;
72+ if (contents != null ) {
73+ location = Json .mapper ().readTree (contents );
74+ String [] objectPath = definitionPath .split ("/" );
75+ for (String objectPathPart : objectPath ) {
76+ LOGGER .debug ("getting part " + objectPathPart );
77+ if (objectPathPart .length () > 0 && location != null ) {
78+ location = location .get (objectPathPart );
79+ locationName = objectPathPart ;
80+ }
81+ }
82+ }
83+ if (location != null ) {
84+ // convert the node to the proper type
85+ if (mapping instanceof Property ) {
86+ Model model = Json .mapper ().convertValue (location , Model .class );
87+ if (mapping instanceof RefProperty ) {
88+ RefProperty ref = (RefProperty ) mapping ;
89+ ref .set$ref (locationName );
90+ swagger .addDefinition (locationName , model );
91+ }
92+ }
93+ else if (target instanceof Parameter ) {
94+ if (mapping instanceof RefModel ) {
95+ Model model = Json .mapper ().convertValue (location , Model .class );
96+ RefModel ref = (RefModel ) mapping ;
97+ ref .set$ref (locationName );
98+ swagger .addDefinition (locationName , model );
99+ }
100+ }
101+ else if (target instanceof Operation ) {
102+
103+ // get the operation position
104+ Operation operation = (Operation ) target ;
105+ int position = 0 ;
106+ for (Parameter param : operation .getParameters ()) {
107+
108+ if (param instanceof RefParameter ) {
109+ RefParameter ref = (RefParameter ) param ;
110+ if (ref .getSimpleRef ().equals (locationName )) {
111+ // found a match!
112+ Parameter remoteParam = Json .mapper ().convertValue (location , Parameter .class );
113+ operation .getParameters ().set (position , remoteParam );
114+ }
115+ }
116+ position += 1 ;
117+ }
118+ }
119+ }
120+ }
121+ catch (Exception e ) {
122+ // failed to get it
123+ e .printStackTrace ();
124+ }
125+ }
126+ }
127+ }
128+
129+ public void detectOperationRefs () {
130+ Map <String , Path > paths = swagger .getPaths ();
131+ if (paths == null ) return ;
132+
133+ for (String pathName : paths .keySet ()) {
134+ Path path = paths .get (pathName );
135+ List <Operation > operations = path .getOperations ();
136+ for (Operation operation : operations ) {
137+ if (operation .getParameters () != null ) {
138+ for (Parameter parameter : operation .getParameters ()) {
139+ if (parameter instanceof BodyParameter ) {
140+ BodyParameter bp = (BodyParameter ) parameter ;
141+ if (bp .getSchema () != null && bp .getSchema () instanceof RefModel ) {
142+ RefModel ref = (RefModel )bp .getSchema ();
143+ if (ref .get$ref ().startsWith ("http" )) {
144+ LOGGER .debug ("added reference to " + ref .get$ref ());
145+ resolutionMap .put (ref .get$ref (), new ResolutionContext (ref , bp , "ref" ));
146+ }
147+ }
148+ }
149+ else if (parameter instanceof RefParameter ) {
150+ RefParameter ref = (RefParameter ) parameter ;
151+ LOGGER .debug ("added reference to " + ref .get$ref ());
152+ resolutionMap .put (ref .get$ref (), new ResolutionContext (ref , operation , "inline" ));
153+ }
154+ }
155+ }
156+ if (operation .getResponses () != null ) {
157+ for (String responseCode : operation .getResponses ().keySet ()) {
158+ Response response = operation .getResponses ().get (responseCode );
159+ if (response .getSchema () != null ) {
160+ Property schema = response .getSchema ();
161+ if (schema instanceof RefProperty ) {
162+ RefProperty ref = (RefProperty ) schema ;
163+ if (ref .get$ref () != null && ref .get$ref ().startsWith ("http" )) {
164+ resolutionMap .put (ref .get$ref (), new ResolutionContext (ref , response , "ref" ));
165+ }
166+ }
167+ }
168+ }
169+ }
170+ }
171+ }
172+ }
173+
174+ public void detectModelRefs () {
175+ Map <String , Model > models = swagger .getDefinitions ();
176+ if (models != null ) {
177+ for (String modelName : models .keySet ()) {
178+ LOGGER .debug ("looking at " + modelName );
179+ Model model = models .get (modelName );
180+ if (model instanceof RefModel ) {
181+ RefModel ref = (RefModel ) model ;
182+ if (ref .get$ref () != null && ref .get$ref ().startsWith ("http" )) {
183+ LOGGER .debug ("added reference to " + ref .get$ref ());
184+ resolutionMap .put (ref .get$ref (), new ResolutionContext (ref , swagger .getDefinitions (), "ref" ));
185+ }
186+ }
187+ else if (model instanceof ArrayModel ) {
188+ ArrayModel arrayModel = (ArrayModel ) model ;
189+ if (arrayModel .getItems () != null && arrayModel .getItems () instanceof RefProperty ) {
190+ RefProperty ref = (RefProperty )arrayModel .getItems ();
191+ if (ref .get$ref () != null && ref .get$ref ().startsWith ("http" )) {
192+ LOGGER .debug ("added reference to " + ref .get$ref ());
193+ resolutionMap .put (ref .get$ref (), new ResolutionContext (ref , swagger .getDefinitions (), "ref" ));
194+ }
195+ }
196+ }
197+ else if (model instanceof ModelImpl ) {
198+ ModelImpl impl = (ModelImpl ) model ;
199+ Map <String , Property > properties = impl .getProperties ();
200+ for (String propertyName : properties .keySet ()) {
201+ Property property = properties .get (propertyName );
202+ if (property instanceof RefProperty ) {
203+ RefProperty ref = (RefProperty )property ;
204+ if (ref .get$ref () != null && ref .get$ref ().startsWith ("http" )) {
205+ LOGGER .debug ("added reference to " + ref .get$ref ());
206+ resolutionMap .put (ref .get$ref (), new ResolutionContext (ref , impl , "ref" ));
207+ }
208+ }
209+ else if (property instanceof ArrayProperty ) {
210+ ArrayProperty arrayProperty = (ArrayProperty ) property ;
211+ if (arrayProperty .getItems () != null && arrayProperty .getItems () instanceof RefProperty ) {
212+ RefProperty ref = (RefProperty )arrayProperty .getItems ();
213+ if (ref .get$ref () != null && ref .get$ref ().startsWith ("http" )) {
214+ LOGGER .debug ("added reference to " + ref .get$ref ());
215+ resolutionMap .put (ref .get$ref (), new ResolutionContext (ref , arrayProperty , "ref" ));
216+ }
217+ }
218+ }
219+ else if (property instanceof MapProperty ) {
220+ MapProperty mp = (MapProperty ) property ;
221+ if (mp .getAdditionalProperties () != null && mp .getAdditionalProperties () instanceof RefProperty ) {
222+ RefProperty ref = (RefProperty )mp .getAdditionalProperties ();
223+ if (ref .get$ref () != null && ref .get$ref ().startsWith ("http" )) {
224+ LOGGER .debug ("added reference to " + ref .get$ref ());
225+ resolutionMap .put (ref .get$ref (), new ResolutionContext (ref , mp , "ref" ));
226+ }
227+ }
228+ }
229+ }
230+ }
231+ }
232+ }
233+ }
234+
235+ static class ResolutionContext {
236+ private Object object , parent ;
237+ private String scope ;
238+
239+ public ResolutionContext (Object object , Object parent , String scope ) {
240+ this .object = object ;
241+ this .parent = parent ;
242+ this .scope = scope ;
243+ }
244+ }
245+ }
0 commit comments