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