1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.juneau.bean.openapi3;
18
19 import static org.apache.juneau.commons.utils.AssertionUtils.*;
20 import static org.apache.juneau.commons.utils.CollectionUtils.*;
21 import static org.apache.juneau.commons.utils.ThrowableUtils.*;
22 import static org.apache.juneau.commons.utils.Utils.*;
23 import static org.apache.juneau.internal.ConverterUtils.*;
24
25 import java.util.*;
26
27 import org.apache.juneau.annotation.*;
28 import org.apache.juneau.collections.*;
29 import org.apache.juneau.json.*;
30
31 /**
32 * Root class for all Swagger beans.
33 */
34 @Bean
35 public abstract class OpenApiElement {
36
37 private boolean strict;
38 private Map<String,Object> extra;
39
40 OpenApiElement() {}
41
42 OpenApiElement(OpenApiElement copyFrom) {
43 this.strict = copyFrom.strict;
44 this.extra = copyOf(copyFrom.extra);
45 }
46
47 /**
48 * Returns a copy of this swagger element as a modifiable map.
49 *
50 * <p>
51 * Each call produces a new map.
52 *
53 * @return A map containing all the values in this swagger element.
54 */
55 public JsonMap asMap() {
56 var m = new JsonMap();
57 for (var s : keySet())
58 m.put(s, get(s, Object.class));
59 return m;
60 }
61
62 /**
63 * Generic property keyset.
64 *
65 * @return
66 * All the non-standard keys on this element.
67 * <br>Never <jk>null</jk>.
68 */
69 @Beanp("*")
70 public Set<String> extraKeys() {
71 return extra == null ? Collections.emptySet() : extra.keySet();
72 }
73
74 /**
75 * Generic property getter.
76 *
77 * <p>
78 * Can be used to retrieve non-standard Swagger fields such as <js>"$ref"</js>.
79 *
80 * @param property The property name to retrieve. Must not be <jk>null</jk>.
81 * @return The property value, or <jk>null</jk> if the property does not exist or is not set.
82 */
83 @Beanp("*")
84 public Object get(String property) {
85 assertArgNotNull("property", property);
86 return opt(extra).map(x -> x.get(property)).orElse(null);
87 }
88
89 /**
90 * Generic property getter.
91 *
92 * <p>
93 * Can be used to retrieve non-standard Swagger fields such as <js>"$ref"</js>.
94 *
95 * @param property The property name to retrieve.
96 * @param type The datatype to cast the value to.
97 * @param <T> The datatype to cast the value to.
98 * @return The property value, or <jk>null</jk> if the property does not exist or is not set.
99 */
100 public <T> T get(String property, Class<T> type) {
101 assertArgNotNull("property", property);
102 return toType(get(property), type);
103 }
104
105 /**
106 * Returns all the keys on this element.
107 *
108 * @return
109 * All the keys on this element.
110 * <br>Never <jk>null</jk>.
111 */
112 public Set<String> keySet() {
113 return extraKeys();
114 }
115
116 /**
117 * Generic property setter.
118 *
119 * <p>
120 * Can be used to set non-standard Swagger fields such as <js>"$ref"</js>.
121 *
122 * @param property The property name to set. Must not be <jk>null</jk>.
123 * @param value The new value for the property.
124 * @return This object
125 * @throws RuntimeException if strict mode is enabled.
126 */
127 @Beanp("*")
128 public OpenApiElement set(String property, Object value) {
129 assertArgNotNull("property", property);
130 if (strict)
131 throw rex("Cannot set property ''{0}'' in strict mode.", property);
132 if (extra == null)
133 extra = map();
134 extra.put(property, value);
135 return this;
136 }
137
138 @Override /* Overridden from Object */
139 public String toString() {
140 return JsonSerializer.DEFAULT_SORTED.toString(this);
141 }
142
143 /**
144 * Returns <jk>true</jk> if contents should be validated per the Swagger spec.
145 *
146 * @return <jk>true</jk> if contents should be validated per the Swagger spec.
147 */
148 protected boolean isStrict() { return strict; }
149
150 /**
151 * Sets strict mode on this bean.
152 *
153 * @return This object
154 */
155 protected OpenApiElement strict() {
156 strict = true;
157 return this;
158 }
159
160 /**
161 * Sets strict mode on this bean.
162 *
163 * @param value
164 * The new value for this property.
165 * <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>.
166 * <br>Can be <jk>null</jk> (interpreted as <jk>false</jk>).
167 * @return This object
168 */
169 protected OpenApiElement strict(Object value) {
170 strict = nn(value) && toBoolean(value);
171 return this;
172 }
173 }