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.openapi3;
014
015import static org.apache.juneau.common.internal.StringUtils.*;
016import static org.apache.juneau.internal.CollectionUtils.*;
017import static org.apache.juneau.internal.ConverterUtils.*;
018
019import org.apache.juneau.UriResolver;
020import org.apache.juneau.annotation.Bean;
021import org.apache.juneau.internal.*;
022
023import java.net.URI;
024import java.net.URL;
025import java.util.*;
026
027/**
028 * TODO
029 */
030@Bean(properties="contentType,style,explode,headers,allowReserved,*")
031@FluentSetters
032public class Response extends OpenApiElement{
033
034   private String description;
035   private Map<String,HeaderInfo> headers;
036   private Map<String,MediaType> content;
037   private Map<String,Link> links;
038
039   /**
040    * Default constructor.
041    */
042   public Response() { }
043
044   /**
045    * Copy constructor.
046    *
047    * @param copyFrom The object to copy.
048    */
049   public Response(Response copyFrom) {
050      super(copyFrom);
051
052      this.description = copyFrom.description;
053      if (copyFrom.headers == null) {
054         this.headers = null;
055      } else {
056         this.headers = new LinkedHashMap<>();
057         for (Map.Entry<String,HeaderInfo> e : copyFrom.headers.entrySet())
058            this.headers.put(e.getKey(),  e.getValue().copy());
059      }
060
061      if (copyFrom.content == null) {
062         this.content = null;
063      } else {
064         this.content = new LinkedHashMap<>();
065         for (Map.Entry<String,MediaType> e : copyFrom.content.entrySet())
066            this.content.put(e.getKey(),  e.getValue().copy());
067      }
068
069      if (copyFrom.links == null) {
070         this.links = null;
071      } else {
072         this.links = new LinkedHashMap<>();
073         for (Map.Entry<String,Link> e : copyFrom.links.entrySet())
074            this.links.put(e.getKey(), e.getValue().copy());
075      }
076   }
077
078   /**
079    * Make a deep copy of this object.
080    *
081    * @return A deep copy of this object.
082    */
083   public Response copy() {
084      return new Response(this);
085   }
086
087   @Override /* OpenApiElement */
088   protected Response strict() {
089      super.strict();
090      return this;
091   }
092
093   /**
094    * Bean property getter:  <property>Description</property>.
095    *
096    * <p>
097    * The URL pointing to the contact information.
098    *
099    * @return The property value, or <jk>null</jk> if it is not set.
100    */
101   public String getDescription() {
102      return description;
103   }
104
105   /**
106    * Bean property setter:  <property>Description</property>.
107    *
108    * <p>
109    * The value can be of any of the following types: {@link URI}, {@link URL}, {@link String}.
110    * <br>Strings must be valid URIs.
111    *
112    * <p>
113    * URIs defined by {@link UriResolver} can be used for values.
114    *
115    * @param value
116    *    The new value for this property.
117    *    <br>Can be <jk>null</jk> to unset the property.
118    * @return This object
119    */
120   public Response setDescription(String value) {
121      description = value;
122      return this;
123   }
124
125   /**
126    * Bean property getter:  <property>headers</property>.
127    *
128    * @return The property value, or <jk>null</jk> if it is not set.
129    */
130   public Map<String, HeaderInfo> getHeaders() {
131      return headers;
132   }
133
134   /**
135    * Bean property setter:  <property>headers</property>.
136    *
137    * @param value
138    *    The new value for this property.
139    * @return This object
140    */
141   public Response setHeaders(Map<String, HeaderInfo> value) {
142      headers = copyOf(value);
143      return this;
144   }
145
146   /**
147    * Adds one or more values to the <property>variables</property> property.
148    *
149    * @param key The mapping key.
150    * @param value
151    *    The values to add to this property.
152    *    <br>Ignored if <jk>null</jk>.
153    * @return This object
154    */
155   public Response addHeader(String key, HeaderInfo value) {
156      headers = mapBuilder(headers).sparse().add(key, value).build();
157      return this;
158   }
159
160   /**
161    * Bean property getter:  <property>headers</property>.
162    *
163    * @return The property value, or <jk>null</jk> if it is not set.
164    */
165   public Map<String, MediaType> getContent() {
166      return content;
167   }
168
169   /**
170    * Bean property setter:  <property>content</property>.
171    *
172    * @param value
173    *    The new value for this property.
174    * @return This object
175    */
176   public Response setContent(Map<String, MediaType> value) {
177      content = copyOf(value);
178      return this;
179   }
180
181   /**
182    * Adds one or more values to the <property>variables</property> property.
183    *
184    * @param key The mapping key.
185    * @param value
186    *    The values to add to this property.
187    *    <br>Ignored if <jk>null</jk>.
188    * @return This object
189    */
190   public Response addContent(String key, MediaType value) {
191      content = mapBuilder(content).sparse().add(key, value).build();
192      return this;
193   }
194
195   /**
196    * Bean property getter:  <property>link</property>.
197    *
198    * @return The property value, or <jk>null</jk> if it is not set.
199    */
200   public Map<String, Link> getLinks() {
201      return links;
202   }
203
204   /**
205    * Bean property setter:  <property>Link</property>.
206    *
207    * @param value
208    *    The new value for this property.
209    * @return This object
210    */
211   public Response setLinks(Map<String, Link> value) {
212      links = copyOf(value);
213      return this;
214   }
215
216   /**
217    * Adds one or more values to the <property>variables</property> property.
218    *
219    * @param key The mapping key.
220    * @param value
221    *    The values to add to this property.
222    *    <br>Ignored if <jk>null</jk>.
223    * @return This object
224    */
225   public Response addLink(String key, Link value) {
226      links = mapBuilder(links).sparse().add(key, value).build();
227      return this;
228   }
229
230   // <FluentSetters>
231
232   // </FluentSetters>
233
234   @Override /* OpenApiElement */
235   public <T> T get(String property, Class<T> type) {
236      if (property == null)
237         return null;
238      switch (property) {
239         case "description": return toType(getDescription(), type);
240         case "content": return toType(getContent(), type);
241         case "headers": return toType(getHeaders(), type);
242         case "links": return toType(getLinks(), type);
243         default: return super.get(property, type);
244      }
245   }
246
247   @Override /* OpenApiElement */
248   public Response set(String property, Object value) {
249      if (property == null)
250         return this;
251      switch (property) {
252         case "description": return setDescription(stringify(value));
253         case "headers": return setHeaders(mapBuilder(String.class,HeaderInfo.class).sparse().addAny(value).build());
254         case "content": return setContent(mapBuilder(String.class,MediaType.class).sparse().addAny(value).build());
255         case "links": return setLinks(mapBuilder(String.class,Link.class).sparse().addAny(value).build());
256         default:
257            super.set(property, value);
258            return this;
259      }
260   }
261
262   @Override /* OpenApiElement */
263   public Set<String> keySet() {
264      Set<String> s = setBuilder(String.class)
265            .addIf(description != null, "description")
266            .addIf(headers != null, "headers")
267            .addIf(content != null, "content")
268            .addIf(links != null, "links")
269            .build();
270      return new MultiSet<>(s, super.keySet());
271   }
272}