001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.model.rest;
018
019import java.util.ArrayList;
020import java.util.List;
021
022import javax.xml.bind.annotation.XmlAccessType;
023import javax.xml.bind.annotation.XmlAccessorType;
024import javax.xml.bind.annotation.XmlAttribute;
025import javax.xml.bind.annotation.XmlElement;
026import javax.xml.bind.annotation.XmlElementRef;
027import javax.xml.bind.annotation.XmlElements;
028import javax.xml.bind.annotation.XmlRootElement;
029import javax.xml.bind.annotation.XmlTransient;
030
031
032import org.apache.camel.model.OptionalIdentifiedDefinition;
033import org.apache.camel.model.RouteDefinition;
034import org.apache.camel.model.ToDefinition;
035import org.apache.camel.model.ToDynamicDefinition;
036import org.apache.camel.spi.Metadata;
037
038/**
039 * Rest command
040 */
041@Metadata(label = "rest")
042@XmlRootElement(name = "verb")
043@XmlAccessorType(XmlAccessType.FIELD)
044public class VerbDefinition extends OptionalIdentifiedDefinition<VerbDefinition> {
045
046    @XmlAttribute
047    private String method;
048
049    @XmlElementRef
050    private List<RestOperationParamDefinition> params = new ArrayList<RestOperationParamDefinition>();
051
052    @XmlElementRef
053    private List<RestOperationResponseMsgDefinition> responseMsgs = new ArrayList<RestOperationResponseMsgDefinition>();
054
055    @XmlElementRef
056    private List<SecurityDefinition> security = new ArrayList<>();
057
058    @XmlAttribute
059    private String uri;
060
061    @XmlAttribute
062    private String consumes;
063
064    @XmlAttribute
065    private String produces;
066
067    @XmlAttribute
068    @Metadata(defaultValue = "auto")
069    private RestBindingMode bindingMode;
070
071    @XmlAttribute
072    private Boolean skipBindingOnErrorCode;
073
074    @XmlAttribute
075    private Boolean enableCORS;
076
077    @XmlAttribute
078    private String type;
079
080    @XmlAttribute
081    private String outType;
082
083    // used by XML DSL to either select a <to>, <toD>, or <route>
084    // so we need to use the common type OptionalIdentifiedDefinition
085    // must select one of them, and hence why they are all set to required = true, but the XSD is set to only allow one of the element
086    @XmlElements({
087            @XmlElement(required = true, name = "to", type = ToDefinition.class),
088            @XmlElement(required = true, name = "toD", type = ToDynamicDefinition.class),
089            @XmlElement(required = true, name = "route", type = RouteDefinition.class)}
090        )
091    private OptionalIdentifiedDefinition<?> toOrRoute;
092
093    // the Java DSL uses the to or route definition directory
094    @XmlTransient
095    private ToDefinition to;
096    @XmlTransient
097    private ToDynamicDefinition toD;
098    @XmlTransient
099    private RouteDefinition route;
100    @XmlTransient
101    private RestDefinition rest;
102    @XmlAttribute
103    private String routeId;
104    @XmlAttribute
105    private Boolean apiDocs;
106
107    @XmlTransient
108    private Boolean usedForGeneratingNodeId = Boolean.FALSE;
109
110    @Override
111    public String getLabel() {
112        if (method != null) {
113            return method;
114        } else {
115            return "verb";
116        }
117    }
118
119    public List<RestOperationParamDefinition> getParams() {
120        return params;
121    }
122
123    /**
124     * To specify the REST operation parameters using Swagger.
125     */
126    public void setParams(List<RestOperationParamDefinition> params) {
127        this.params = params;
128    }
129
130    public List<RestOperationResponseMsgDefinition> getResponseMsgs() {
131        return responseMsgs;
132    }
133
134    /**
135     * Sets swagger operation response messages.
136     */
137    public void setResponseMsgs(List<RestOperationResponseMsgDefinition> params) {
138        this.responseMsgs = responseMsgs;
139    }
140
141    public List<SecurityDefinition> getSecurity() {
142        return security;
143    }
144
145    /**
146     * Sets the swagger security settings for this verb.
147     */
148    public void setSecurity(List<SecurityDefinition> security) {
149        this.security = security;
150    }
151
152    public String getMethod() {
153        return method;
154    }
155
156    /**
157     * The HTTP verb such as GET, POST, DELETE, etc.
158     */
159    public void setMethod(String method) {
160        this.method = method;
161    }
162
163    public String getUri() {
164        return uri;
165    }
166
167    /**
168     * Uri template of this REST service such as /{id}.
169     */
170    public void setUri(String uri) {
171        this.uri = uri;
172    }
173
174    public String getConsumes() {
175        return consumes;
176    }
177
178    /**
179     * To define the content type what the REST service consumes (accept as input), such as application/xml or application/json.
180     * This option will override what may be configured on a parent level
181     */
182    public void setConsumes(String consumes) {
183        this.consumes = consumes;
184    }
185
186    public String getProduces() {
187        return produces;
188    }
189
190    /**
191     * To define the content type what the REST service produces (uses for output), such as application/xml or application/json
192     * This option will override what may be configured on a parent level
193     */
194    public void setProduces(String produces) {
195        this.produces = produces;
196    }
197
198    public RestBindingMode getBindingMode() {
199        return bindingMode;
200    }
201
202    /**
203     * Sets the binding mode to use.
204     * This option will override what may be configured on a parent level
205     * <p/>
206     * The default value is auto
207     */
208    public void setBindingMode(RestBindingMode bindingMode) {
209        this.bindingMode = bindingMode;
210    }
211
212    public Boolean getSkipBindingOnErrorCode() {
213        return skipBindingOnErrorCode;
214    }
215
216    /**
217     * Whether to skip binding on output if there is a custom HTTP error code header.
218     * This allows to build custom error messages that do not bind to json / xml etc, as success messages otherwise will do.
219     * This option will override what may be configured on a parent level
220     */
221    public void setSkipBindingOnErrorCode(Boolean skipBindingOnErrorCode) {
222        this.skipBindingOnErrorCode = skipBindingOnErrorCode;
223    }
224
225    public Boolean getEnableCORS() {
226        return enableCORS;
227    }
228
229    /**
230     * Whether to enable CORS headers in the HTTP response.
231     * This option will override what may be configured on a parent level
232     * <p/>
233     * The default value is false.
234     */
235    public void setEnableCORS(Boolean enableCORS) {
236        this.enableCORS = enableCORS;
237    }
238
239    public String getType() {
240        return type;
241    }
242
243    /**
244     * Sets the class name to use for binding from input to POJO for the incoming data
245     * This option will override what may be configured on a parent level.
246     * <p/>
247     * The canonical name of the class of the input data. Append a [] to the end of the canonical name
248     * if you want the input to be an array type.
249     */
250    public void setType(String type) {
251        this.type = type;
252    }
253
254    public String getOutType() {
255        return outType;
256    }
257
258    /**
259     * Sets the class name to use for binding from POJO to output for the outgoing data
260     * This option will override what may be configured on a parent level
261     * <p/>
262     * The canonical name of the class of the input data. Append a [] to the end of the canonical name
263     * if you want the input to be an array type.
264     */
265    public void setOutType(String outType) {
266        this.outType = outType;
267    }
268
269    public String getRouteId() {
270        return routeId;
271    }
272
273    /**
274     * The route id this rest-dsl is using (read-only)
275     */
276    public void setRouteId(String routeId) {
277        this.routeId = routeId;
278    }
279
280    public Boolean getApiDocs() {
281        return apiDocs;
282    }
283
284    /**
285     * Whether to include or exclude the VerbDefinition in API documentation.
286     * <p/>
287     * The default value is true.
288     */
289    public void setApiDocs(Boolean apiDocs) {
290        this.apiDocs = apiDocs;
291    }
292
293    public RestDefinition getRest() {
294        return rest;
295    }
296
297    public void setRest(RestDefinition rest) {
298        this.rest = rest;
299    }
300
301    public RouteDefinition getRoute() {
302        if (route != null) {
303            return route;
304        } else if (toOrRoute instanceof RouteDefinition) {
305            return (RouteDefinition) toOrRoute;
306        } else {
307            return null;
308        }
309    }
310
311    public void setRoute(RouteDefinition route) {
312        this.route = route;
313        this.toOrRoute = route;
314    }
315
316    public ToDefinition getTo() {
317        if (to != null) {
318            return to;
319        } else if (toOrRoute instanceof ToDefinition) {
320            return (ToDefinition) toOrRoute;
321        } else {
322            return null;
323        }
324    }
325
326    public ToDynamicDefinition getToD() {
327        if (toD != null) {
328            return toD;
329        } else if (toOrRoute instanceof ToDynamicDefinition) {
330            return (ToDynamicDefinition) toOrRoute;
331        } else {
332            return null;
333        }
334    }
335
336    public void setTo(ToDefinition to) {
337        this.to = to;
338        this.toD = null;
339        this.toOrRoute = to;
340    }
341
342    public void setToD(ToDynamicDefinition to) {
343        this.to = null;
344        this.toD = to;
345        this.toOrRoute = to;
346    }
347
348    public OptionalIdentifiedDefinition<?> getToOrRoute() {
349        return toOrRoute;
350    }
351
352    /**
353     * To route from this REST service to a Camel endpoint, or an inlined route
354     */
355    public void setToOrRoute(OptionalIdentifiedDefinition<?> toOrRoute) {
356        this.toOrRoute = toOrRoute;
357    }
358
359    // Fluent API
360    // -------------------------------------------------------------------------
361
362    public RestDefinition get() {
363        return rest.get();
364    }
365
366    public RestDefinition get(String uri) {
367        return rest.get(uri);
368    }
369
370    public RestDefinition post() {
371        return rest.post();
372    }
373
374    public RestDefinition post(String uri) {
375        return rest.post(uri);
376    }
377
378    public RestDefinition put() {
379        return rest.put();
380    }
381
382    public RestDefinition put(String uri) {
383        return rest.put(uri);
384    }
385
386    public RestDefinition delete() {
387        return rest.delete();
388    }
389
390    public RestDefinition delete(String uri) {
391        return rest.delete(uri);
392    }
393
394    public RestDefinition head() {
395        return rest.head();
396    }
397
398    public RestDefinition head(String uri) {
399        return rest.head(uri);
400    }
401
402    public RestDefinition verb(String verb) {
403        return rest.verb(verb);
404    }
405
406    public RestDefinition verb(String verb, String uri) {
407        return rest.verb(verb, uri);
408    }
409
410    public String asVerb() {
411        // we do not want the jaxb model to repeat itself, by outputting <get method="get">
412        // so we infer the verb from the instance type
413        if (this instanceof GetVerbDefinition) {
414            return "get";
415        } else if (this instanceof PostVerbDefinition) {
416            return "post";
417        } else if (this instanceof PutVerbDefinition) {
418            return "put";
419        } else if (this instanceof PatchVerbDefinition) {
420            return "patch";
421        } else if (this instanceof DeleteVerbDefinition) {
422            return "delete";
423        } else if (this instanceof HeadVerbDefinition) {
424            return "head";
425        } else if (this instanceof OptionsVerbDefinition) {
426            return "options";
427        } else {
428            return method;
429        }
430    }
431
432    public Boolean getUsedForGeneratingNodeId() {
433        return usedForGeneratingNodeId;
434    }
435
436    public void setUsedForGeneratingNodeId(Boolean usedForGeneratingNodeId) {
437        this.usedForGeneratingNodeId = usedForGeneratingNodeId;
438    }
439}