1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.forgerock.api;
18
19 import static java.util.Collections.*;
20 import static org.forgerock.api.models.ApiDescription.*;
21 import static org.forgerock.api.models.Definitions.*;
22 import static org.forgerock.api.models.Errors.*;
23 import static org.forgerock.api.models.Paths.*;
24 import static org.forgerock.api.models.Services.services;
25 import static org.forgerock.api.models.VersionedPath.*;
26
27 import java.util.List;
28 import java.util.Set;
29
30 import org.forgerock.api.models.ApiDescription;
31 import org.forgerock.api.models.Definitions;
32 import org.forgerock.api.models.Errors;
33 import org.forgerock.util.i18n.LocalizableString;
34 import org.forgerock.api.models.Paths;
35 import org.forgerock.api.models.Services;
36 import org.forgerock.api.models.VersionedPath;
37 import org.forgerock.http.routing.Version;
38 import org.forgerock.http.ApiProducer;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42
43
44
45 public class CrestApiProducer implements ApiProducer<ApiDescription> {
46
47 private final String version;
48 private final String id;
49 private final LocalizableString description;
50 private static final Logger LOGGER = LoggerFactory.getLogger(CrestApiProducer.class);
51
52
53
54
55
56
57
58 public CrestApiProducer(String id, String apiVersion, LocalizableString description) {
59 this.id = id;
60 this.version = apiVersion;
61 this.description = description;
62 }
63
64
65
66
67
68
69 public CrestApiProducer(String id, String apiVersion) {
70 this(id, apiVersion, null);
71 }
72
73 @Override
74 public ApiDescription withPath(ApiDescription api, String parentPath) {
75 Paths.Builder paths = paths();
76 Set<String> names = api.getPaths().getNames();
77 for (String subpath : names) {
78 paths.put(subpath.equals("") ? parentPath : parentPath + "/" + subpath,
79 api.getPaths().get(subpath));
80 }
81 return createApi(api.getDefinitions(), api.getErrors(), api.getServices(), paths.build());
82 }
83
84 @Override
85 public ApiDescription withVersion(ApiDescription api, Version version) {
86 Paths.Builder paths = paths();
87 Set<String> names = api.getPaths().getNames();
88 for (String path : names) {
89 VersionedPath versionedPath = api.getPaths().get(path);
90 if (singleton(UNVERSIONED).equals(versionedPath.getVersions())) {
91 paths.put(path, versionedPath().put(version, versionedPath.get(UNVERSIONED)).build());
92 } else {
93 throw new IllegalStateException("Trying to version something already versioned: " + versionedPath);
94 }
95 }
96 return createApi(api.getDefinitions(), api.getErrors(), api.getServices(), paths.build());
97 }
98
99 @Override
100 public ApiDescription merge(List<ApiDescription> descriptions) {
101 Paths.Builder paths = paths();
102 Definitions.Builder definitions = definitions();
103 Errors.Builder errors = errors();
104 Services.Builder services = services();
105 for (ApiDescription description : descriptions) {
106 if (description != null) {
107 try {
108 if (description.getDefinitions() != null) {
109 for (String definition : description.getDefinitions().getNames()) {
110 definitions.put(definition, description.getDefinitions().get(definition));
111 }
112 }
113 if (description.getErrors() != null) {
114 for (String error : description.getErrors().getNames()) {
115 errors.put(error, description.getErrors().get(error));
116 }
117 }
118 if (description.getServices() != null) {
119 for (String service : description.getServices().getNames()) {
120 services.put(service, description.getServices().get(service));
121 }
122 }
123 if (description.getPaths() != null) {
124 for (String path : description.getPaths().getNames()) {
125 paths.merge(path, description.getPaths().get(path));
126 }
127 }
128 } catch (RuntimeException re) {
129 LOGGER.error(re.getMessage(), re.fillInStackTrace());
130 throw re;
131 }
132 }
133 }
134 return createApi(definitions.build(), errors.build(), services.build(), paths.build());
135 }
136
137 @Override
138 public ApiDescription addApiInfo(ApiDescription api) {
139 return createApi(api.getDefinitions(), api.getErrors(), api.getServices(), api.getPaths());
140 }
141
142 private ApiDescription createApi(Definitions definitions, Errors errors, Services services, Paths paths) {
143 return apiDescription()
144 .definitions(definitions)
145 .errors(errors)
146 .services(services)
147 .paths(paths)
148 .id(this.id)
149 .version(this.version)
150 .description(this.description)
151 .build();
152 }
153
154 @Override
155 public ApiProducer<ApiDescription> newChildProducer(String idFragment) {
156 return new CrestApiProducer(id + idFragment, version);
157 }
158 }