View Javadoc
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 }