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<>();
051
052    @XmlElementRef
053    private List<RestOperationResponseMsgDefinition> responseMsgs = new ArrayList<>();
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 clientRequestValidation;
076
077    @XmlAttribute
078    private Boolean enableCORS;
079
080    @XmlAttribute
081    private String type;
082
083    @XmlAttribute
084    private String outType;
085
086    // used by XML DSL to either select a <to>, <toD>, or <route>
087    // so we need to use the common type OptionalIdentifiedDefinition
088    // 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
089    @XmlElements({
090            @XmlElement(required = true, name = "to", type = ToDefinition.class),
091            @XmlElement(required = true, name = "toD", type = ToDynamicDefinition.class),
092            @XmlElement(required = true, name = "route", type = RouteDefinition.class)}
093        )
094    private OptionalIdentifiedDefinition<?> toOrRoute;
095
096    // the Java DSL uses the to or route definition directory
097    @XmlTransient
098    private ToDefinition to;
099    @XmlTransient
100    private ToDynamicDefinition toD;
101    @XmlTransient
102    private RouteDefinition route;
103    @XmlTransient
104    private RestDefinition rest;
105    @XmlAttribute
106    private String routeId;
107    @XmlAttribute
108    private Boolean apiDocs;
109
110    @XmlTransient
111    private Boolean usedForGeneratingNodeId = Boolean.FALSE;
112
113    @Override
114    public String getLabel() {
115        if (method != null) {
116            return method;
117        } else {
118            return "verb";
119        }
120    }
121
122    public List<RestOperationParamDefinition> getParams() {
123        return params;
124    }
125
126    /**
127     * To specify the REST operation parameters using Swagger.
128     */
129    public void setParams(List<RestOperationParamDefinition> params) {
130        this.params = params;
131    }
132
133    public List<RestOperationResponseMsgDefinition> getResponseMsgs() {
134        return responseMsgs;
135    }
136
137    /**
138     * Sets swagger operation response messages.
139     */
140    public void setResponseMsgs(List<RestOperationResponseMsgDefinition> params) {
141        this.responseMsgs = responseMsgs;
142    }
143
144    public List<SecurityDefinition> getSecurity() {
145        return security;
146    }
147
148    /**
149     * Sets the swagger security settings for this verb.
150     */
151    public void setSecurity(List<SecurityDefinition> security) {
152        this.security = security;
153    }
154
155    public String getMethod() {
156        return method;
157    }
158
159    /**
160     * The HTTP verb such as GET, POST, DELETE, etc.
161     */
162    public void setMethod(String method) {
163        this.method = method;
164    }
165
166    public String getUri() {
167        return uri;
168    }
169
170    /**
171     * Uri template of this REST service such as /{id}.
172     */
173    public void setUri(String uri) {
174        this.uri = uri;
175    }
176
177    public String getConsumes() {
178        return consumes;
179    }
180
181    /**
182     * To define the content type what the REST service consumes (accept as input), such as application/xml or application/json.
183     * This option will override what may be configured on a parent level
184     */
185    public void setConsumes(String consumes) {
186        this.consumes = consumes;
187    }
188
189    public String getProduces() {
190        return produces;
191    }
192
193    /**
194     * To define the content type what the REST service produces (uses for output), such as application/xml or application/json
195     * This option will override what may be configured on a parent level
196     */
197    public void setProduces(String produces) {
198        this.produces = produces;
199    }
200
201    public RestBindingMode getBindingMode() {
202        return bindingMode;
203    }
204
205    /**
206     * Sets the binding mode to use.
207     * This option will override what may be configured on a parent level
208     * <p/>
209     * The default value is auto
210     */
211    public void setBindingMode(RestBindingMode bindingMode) {
212        this.bindingMode = bindingMode;
213    }
214
215    public Boolean getSkipBindingOnErrorCode() {
216        return skipBindingOnErrorCode;
217    }
218
219    /**
220     * Whether to skip binding on output if there is a custom HTTP error code header.
221     * This allows to build custom error messages that do not bind to json / xml etc, as success messages otherwise will do.
222     * This option will override what may be configured on a parent level
223     */
224    public void setSkipBindingOnErrorCode(Boolean skipBindingOnErrorCode) {
225        this.skipBindingOnErrorCode = skipBindingOnErrorCode;
226    }
227
228    public Boolean getClientRequestValidation() {
229        return clientRequestValidation;
230    }
231
232    /**
233     * Whether to enable validation of the client request to check whether the Content-Type and Accept headers from
234     * the client is supported by the Rest-DSL configuration of its consumes/produces settings.
235     * <p/>
236     * This can be turned on, to enable this check. In case of validation error, then HTTP Status codes 415 or 406 is returned.
237     * <p/>
238     * The default value is false.
239     */
240    public void setClientRequestValidation(Boolean clientRequestValidation) {
241        this.clientRequestValidation = clientRequestValidation;
242    }
243
244    public Boolean getEnableCORS() {
245        return enableCORS;
246    }
247
248    /**
249     * Whether to enable CORS headers in the HTTP response.
250     * This option will override what may be configured on a parent level
251     * <p/>
252     * The default value is false.
253     */
254    public void setEnableCORS(Boolean enableCORS) {
255        this.enableCORS = enableCORS;
256    }
257
258    public String getType() {
259        return type;
260    }
261
262    /**
263     * Sets the class name to use for binding from input to POJO for the incoming data
264     * This option will override what may be configured on a parent level.
265     * <p/>
266     * The canonical name of the class of the input data. Append a [] to the end of the canonical name
267     * if you want the input to be an array type.
268     */
269    public void setType(String type) {
270        this.type = type;
271    }
272
273    public String getOutType() {
274        return outType;
275    }
276
277    /**
278     * Sets the class name to use for binding from POJO to output for the outgoing data
279     * This option will override what may be configured on a parent level
280     * <p/>
281     * The canonical name of the class of the input data. Append a [] to the end of the canonical name
282     * if you want the input to be an array type.
283     */
284    public void setOutType(String outType) {
285        this.outType = outType;
286    }
287
288    public String getRouteId() {
289        return routeId;
290    }
291
292    /**
293     * The route id this rest-dsl is using (read-only)
294     */
295    public void setRouteId(String routeId) {
296        this.routeId = routeId;
297    }
298
299    public Boolean getApiDocs() {
300        return apiDocs;
301    }
302
303    /**
304     * Whether to include or exclude the VerbDefinition in API documentation.
305     * <p/>
306     * The default value is true.
307     */
308    public void setApiDocs(Boolean apiDocs) {
309        this.apiDocs = apiDocs;
310    }
311
312    public RestDefinition getRest() {
313        return rest;
314    }
315
316    public void setRest(RestDefinition rest) {
317        this.rest = rest;
318    }
319
320    public RouteDefinition getRoute() {
321        if (route != null) {
322            return route;
323        } else if (toOrRoute instanceof RouteDefinition) {
324            return (RouteDefinition) toOrRoute;
325        } else {
326            return null;
327        }
328    }
329
330    public void setRoute(RouteDefinition route) {
331        this.route = route;
332        this.toOrRoute = route;
333    }
334
335    public ToDefinition getTo() {
336        if (to != null) {
337            return to;
338        } else if (toOrRoute instanceof ToDefinition) {
339            return (ToDefinition) toOrRoute;
340        } else {
341            return null;
342        }
343    }
344
345    public ToDynamicDefinition getToD() {
346        if (toD != null) {
347            return toD;
348        } else if (toOrRoute instanceof ToDynamicDefinition) {
349            return (ToDynamicDefinition) toOrRoute;
350        } else {
351            return null;
352        }
353    }
354
355    public void setTo(ToDefinition to) {
356        this.to = to;
357        this.toD = null;
358        this.toOrRoute = to;
359    }
360
361    public void setToD(ToDynamicDefinition to) {
362        this.to = null;
363        this.toD = to;
364        this.toOrRoute = to;
365    }
366
367    public OptionalIdentifiedDefinition<?> getToOrRoute() {
368        return toOrRoute;
369    }
370
371    /**
372     * To route from this REST service to a Camel endpoint, or an inlined route
373     */
374    public void setToOrRoute(OptionalIdentifiedDefinition<?> toOrRoute) {
375        this.toOrRoute = toOrRoute;
376    }
377
378    // Fluent API
379    // -------------------------------------------------------------------------
380
381    public RestDefinition get() {
382        return rest.get();
383    }
384
385    public RestDefinition get(String uri) {
386        return rest.get(uri);
387    }
388
389    public RestDefinition post() {
390        return rest.post();
391    }
392
393    public RestDefinition post(String uri) {
394        return rest.post(uri);
395    }
396
397    public RestDefinition put() {
398        return rest.put();
399    }
400
401    public RestDefinition put(String uri) {
402        return rest.put(uri);
403    }
404
405    public RestDefinition delete() {
406        return rest.delete();
407    }
408
409    public RestDefinition delete(String uri) {
410        return rest.delete(uri);
411    }
412
413    public RestDefinition head() {
414        return rest.head();
415    }
416
417    public RestDefinition head(String uri) {
418        return rest.head(uri);
419    }
420
421    public RestDefinition verb(String verb) {
422        return rest.verb(verb);
423    }
424
425    public RestDefinition verb(String verb, String uri) {
426        return rest.verb(verb, uri);
427    }
428
429    public String asVerb() {
430        // we do not want the jaxb model to repeat itself, by outputting <get method="get">
431        // so we infer the verb from the instance type
432        if (this instanceof GetVerbDefinition) {
433            return "get";
434        } else if (this instanceof PostVerbDefinition) {
435            return "post";
436        } else if (this instanceof PutVerbDefinition) {
437            return "put";
438        } else if (this instanceof PatchVerbDefinition) {
439            return "patch";
440        } else if (this instanceof DeleteVerbDefinition) {
441            return "delete";
442        } else if (this instanceof HeadVerbDefinition) {
443            return "head";
444        } else if (this instanceof OptionsVerbDefinition) {
445            return "options";
446        } else {
447            return method;
448        }
449    }
450
451    public Boolean getUsedForGeneratingNodeId() {
452        return usedForGeneratingNodeId;
453    }
454
455    public void setUsedForGeneratingNodeId(Boolean usedForGeneratingNodeId) {
456        this.usedForGeneratingNodeId = usedForGeneratingNodeId;
457    }
458}