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