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