001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.dto.swagger; 014 015import static org.apache.juneau.internal.BeanPropertyUtils.*; 016 017import java.util.*; 018 019import org.apache.juneau.*; 020import org.apache.juneau.annotation.*; 021import org.apache.juneau.json.*; 022import org.apache.juneau.utils.*; 023 024/** 025 * Root class for all Swagger beans. 026 * 027 * <h5 class='section'>See Also:</h5> 028 * <ul class='doctree'> 029 * <li class='link'>{@doc juneau-dto.Swagger} 030 * </ul> 031 */ 032public abstract class SwaggerElement { 033 034 private boolean strict; 035 private Map<String,Object> extra; 036 037 SwaggerElement() {} 038 039 SwaggerElement(SwaggerElement copyFrom) { 040 this.strict = copyFrom.strict; 041 this.extra = copyFrom.extra == null ? null : new LinkedHashMap<>(copyFrom.extra); 042 } 043 044 /** 045 * Returns <jk>true</jk> if contents should be validated per the Swagger spec. 046 * 047 * @return <jk>true</jk> if contents should be validated per the Swagger spec. 048 */ 049 protected boolean isStrict() { 050 return strict; 051 } 052 053 /** 054 * Sets strict mode on this bean. 055 * 056 * @return This object (for method chaining). 057 */ 058 protected SwaggerElement strict() { 059 strict = true; 060 return this; 061 } 062 063 /** 064 * Sets strict mode on this bean. 065 * 066 * @param value 067 * The new value for this property. 068 * <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>. 069 * <br>Can be <jk>null</jk> (interpreted as <jk>false</jk>). 070 * @return This object (for method chaining). 071 */ 072 protected SwaggerElement strict(Object value) { 073 strict = value == null ? false : toBoolean(value); 074 return this; 075 } 076 077 /** 078 * Generic property getter. 079 * 080 * <p> 081 * Can be used to retrieve non-standard Swagger fields such as <js>"$ref"</js>. 082 * 083 * @param property The property name to retrieve. 084 * @param type The datatype to cast the value to. 085 * @return The property value, or <jk>null</jk> if the property does not exist or is not set. 086 */ 087 public <T> T get(String property, Class<T> type) { 088 if (property == null) 089 return null; 090 switch (property) { 091 case "strict": return toType(isStrict(), type); 092 default: return toType(get(property), type); 093 } 094 }; 095 096 /** 097 * Generic property getter. 098 * 099 * <p> 100 * Can be used to retrieve non-standard Swagger fields such as <js>"$ref"</js>. 101 * 102 * @param property The property name to retrieve. 103 * @return The property value, or <jk>null</jk> if the property does not exist or is not set. 104 */ 105 @BeanProperty("*") 106 public Object get(String property) { 107 if (property == null || extra == null) 108 return null; 109 return extra.get(property); 110 }; 111 112 /** 113 * Generic property setter. 114 * 115 * <p> 116 * Can be used to set non-standard Swagger fields such as <js>"$ref"</js>. 117 * 118 * @param property The property name to set. 119 * @param value The new value for the property. 120 * @return This object (for method chaining). 121 */ 122 @BeanProperty("*") 123 public SwaggerElement set(String property, Object value) { 124 if (property == null) 125 return this; 126 switch (property) { 127 case "strict": return strict(value); 128 default: 129 if (extra == null) 130 extra = new LinkedHashMap<>(); 131 extra.put(property, value); 132 return this; 133 } 134 } 135 136 /** 137 * Generic property keyset. 138 * 139 * @return 140 * All the non-standard keys on this element. 141 * <br>Never <jk>null</jk>. 142 */ 143 @BeanProperty("*") 144 public Set<String> extraKeys() { 145 return extra == null ? Collections.EMPTY_SET : extra.keySet(); 146 } 147 148 /** 149 * Returns all the keys on this element. 150 * 151 * @return 152 * All the keys on this element. 153 * <br>Never <jk>null</jk>. 154 */ 155 public Set<String> keySet() { 156 ASet<String> s = new ASet<String>() 157 .appendIf(strict, "strict"); 158 s.addAll(extraKeys()); 159 return s; 160 } 161 162 /** 163 * Returns a copy of this swagger element as a modifiable map. 164 * 165 * <p> 166 * Each call produces a new map. 167 * 168 * @return A map containing all the values in this swagger element. 169 */ 170 public ObjectMap asMap() { 171 ObjectMap m = new ObjectMap(); 172 for (String s : keySet()) 173 m.put(s, get(s, Object.class)); 174 return m; 175 } 176 177 @Override /* Object */ 178 public String toString() { 179 return JsonSerializer.DEFAULT.toString(this); 180 } 181}