{"id":269,"date":"2009-09-10T11:19:27","date_gmt":"2009-09-10T09:19:27","guid":{"rendered":"http:\/\/loicmathieu.free.fr\/wordpress\/?p=269"},"modified":"2016-12-29T11:55:05","modified_gmt":"2016-12-29T09:55:05","slug":"implementer-une-architecture-de-service-web-restfull-avec-restlet-et-son-extention-spring","status":"publish","type":"post","link":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/implementer-une-architecture-de-service-web-restfull-avec-restlet-et-son-extention-spring\/","title":{"rendered":"Implementer une architecture de service web RESTfull avec Restlet et son extention Spring"},"content":{"rendered":"<p>Cet article fait suite mon article<a title=\"REST - Architecture Orient\u00e9e Ressource \" href=\"http:\/\/loicmathieu.free.fr\/wordpress\/index.php\/informatique\/rest-architecture-orientee-ressource\/\" target=\"_self\"> REST &#8211; Architecture Orient\u00e9e Ressource<\/a> en lui donnant une impl\u00e9mentation bas\u00e9 sur le framework <a href=\"http:\/\/www.restlet.org\/\">Restlet<\/a>.<\/p>\n<h3>Le principe de Restlet :<\/h3>\n<p>Restlet est un framework Java 5.0 qui ob\u00e9it aux standard RESTful et permet de cr\u00e9er facilement des application RESTful. Il remplace la sp\u00e9cification J2EE par une API orient\u00e9e REST : on d\u00e9veloppe des Restlet au lieu de d\u00e9velopper des Servlet.<\/p>\n<p>Il existe deux composant principaux:<\/p>\n<ul><li><strong>Router <\/strong>: permet de router une requ\u00eate HTTP vers une ressource.<\/li>\n\n<li><strong>Resource <\/strong>: la ressource REST d&#8217;un objet, une ressource permet plusieurs repr\u00e9sentations diff\u00e9rentes.<\/li>\n\n<li><strong>Repr\u00e9sentation<\/strong>: la repr\u00e9sentation visuelle de la ressource.<\/li>\n<\/ul>\n<p>Dans cet exemple, je vais utiliser Velocity pour cr\u00e9er des repr\u00e9sentation XML et XHTML et l&#8217;extension Spring de Restlet qui permet de d\u00e9finir un Router directement dans les fichier de configuration des beans de Spring et de faire de l&#8217;injection dans les classes de Resource.<\/p>\n<h3>Le fichier de configuration Spring :<\/h3>\n<p>C&#8217;est la base de l&#8217;utilisation de Restlet avec Spring, voici un exemple de fichier d\u00e9finissant un routeur et des ressources. Le routeur est d\u00e9finit par une map dont les entr\u00e9e ont comme cl\u00e9 le pattern d&#8217;URL (les param\u00e8tres sont entre {}) et en valeur la ressource (dont le bean est localis\u00e9 via le SpringFinder, pour assurer la cr\u00e9ation d&#8217;une ressource diff\u00e9rente \u00e0 chaque requ\u00eate).\nIl faut bien faire attention au fait qu&#8217;une resource soit de type <em>&#8216;prototype&#8217;<\/em>.<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n\n    \n        <map>\n            <!--  product resource -->\n            \n                \n                    \n                \n            \n            \n                \n                    \n                \n            \n            <!--  category resource -->\n            \n                \n                    \n                \n            \n        <\/map>\n    \n\n\n    \n    \n\n\n    \n    \n\n<\/pre>\n<p>J&#8217;utilise ici une BaseResource comme parent \u00e0 toutes mes ressources (ce qui explique le parent=&#8221;baseResource&#8221;, \u00e0 ne pas mettre si vous ne cr\u00e9ez pas de base ressource)\n, celle-ci contient du code commun \u00e0 toutes mes ressources pour g\u00e9rer la langue, le num\u00e9ro de version, les diff\u00e9rentes repr\u00e9sentation&#8230; Je vous conseil de faire de m\u00eame en fonction de ce que vous voulez r\u00e9aliser.<\/p>\n<p>On peut remarquer que j&#8217;ai mapp\u00e9 deux URL vers la ressource product, c&#8217;est tout \u00e0 fait possible. Je vous donnerais plus tard un exemple d&#8217;utilisation.<\/p>\n<h3>La classe org.restlet.resource.Resource<\/h3>\n<p>C&#8217;est la classe de base d&#8217;une ressource, voici les principales m\u00e9thodes qu&#8217;il faut surcharger pour \u00e9crire vos propre ressources:<\/p>\n<ol><li><strong>onInit()<\/strong>: lire les param\u00e8tres de la request<\/li>\n\n<li><strong>represent(Variant v)<\/strong>:\u00a0 pour la m\u00e9thode http &#8216;<em>GET<\/em>&#8216;: r\u00e9cup\u00e9ration d&#8217;une ressource<\/li>\n\n<li><strong>removeRepresentation()<\/strong>: pour la m\u00e9thode http &#8216;<em>DELETE<\/em>&#8216;: suppression d&#8217;une ressource<\/li>\n\n<li><strong>acceptRepresentation ()<\/strong>: pour la m\u00e9thode http &#8216;<em>POST<\/em>&#8216;: cr\u00e9ation d&#8217;une nouvelle ressource<\/li>\n\n<li><strong>storeRepresentation()<\/strong>: pour la m\u00e9thode http &#8216;<em>PUT<\/em>&#8216;: modification d&#8217;une ressource existante<\/li>\n<\/ol>\n<h3>Exemple: la classe ProductResource<\/h3>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\n\/**\n * @author Lo\u00efc Mathieu\n *\/\npublic class ProductResource extends BaseResource {\n    \/\/ request parameters\n    private String productName;\n    private String format;\n\n    \/\/ IoC parameter\n    private ProductService productService;\n\n     \/\/IoC Setter\n    public void setProductService(ProductService productService) {\n        this.productService = productService;\n    }\n\n    @Override protected void onInit(Context context, Request request, Response response) {\n        productName = (String) request.getAttributes().get(\"productName\");\n        format = (String) request.getAttributes().get(\"format\");\n    }\n\n    @Override public Representation represent(Variant variant) throws ResourceException {\n        Product product = productService.findProductByName(productName);\n\n        \/\/ select the desired template\n        String velocityTpl = \"catalog.product.vm\"\";\n            if (format != null &amp;&amp; \"small\".equals(format)) {\n            velocityTpl = \"catalog.product.small.vm\";\n        }\n\n        Map data = new HashMap();\n        data.put(\"product\", product);\n\n        switch (getExtension()) {\n            case HTML:\n                return new VelocityRepresentation(velocityTpl, data, getExtension().getMediaType());\n            case XML:\n                StringRepresentation sr = new StringRepresentation(product.getXmlRepresentation(), getExtension().getMediaType());\n                return new DomRepresentation(sr);\n            case TXT:\n                return new StringRepresentation(product.getDisplayName());\n            default:\n                throw new RessourceException(Status.CLIENT_ERROR_BAD_REQUEST,\n                        \"a problem occured, please contact the administrator.\",\n                        \" Unable to find a representation of type: \" + getExtension());\n        }\n    }\n}\n<\/pre>\n<p>Ce qu&#8217;il faut remarquer dans ce code source:<\/p>\n<ul><li>ligne 18 et 19: lecture des param\u00e8tre depuis la requ\u00eate<\/li>\n\n<li>ligne 26: celons la valeur du param\u00e8tre <em>format<\/em> j&#8217;utilise des templates Velocity diff\u00e9rent<\/li>\n\n<li>ligne 34: je switch sur l&#8217;extension de la ressource (la classe Extension est une enum qui lie .txt -&gt; Extension.TXT, .html -&gt; Extention.html, &#8230; Et qui est calcul\u00e9 dans ma base resource)<\/li>\n\n<li>Pour chaque type d&#8217;extension, je g\u00e9n\u00e8re un type de repr\u00e9sentation diff\u00e9rent\n<ul><li>HTML: une repr\u00e9sentation VelocityRepresentation qui utilise un template <a href=\"http:\/\/velocity.apache.org\/\" target=\"_blank\">Velocity <\/a>pour cr\u00e9er l&#8217;HTML. VelocityRepresentation est une sous classe de TemplateRepresentation qui facilite l&#8217;utilisation de Velocity. J&#8217;en donne l&#8217;impl\u00e9mentation plus bas.<\/li>\n\n<li>TXT: une StringRepr\u00e9sentation<\/li>\n\n<li>XML: pour plus de facilit\u00e9 je pr\u00e9sume qu&#8217;un produit peut cr\u00e9er son propre XML. J&#8217;utilise ensuite une DomRepresentation.<\/li>\n\n<li>ligne 42: tr\u00e8s important, si l&#8217;extension n&#8217;est pas de type support\u00e9 pour la ressource, alors je lance une exception qui contient un code d&#8217;erreur HTTP. Ici une <em>400 Bad Request<\/em>.<\/li>\n<\/ul><\/li>\n<\/ul>\n<h3>La classe VelocityRepresentation:<\/h3>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\n\/**\n * @author Lo\u00efc Mathieu - LBI\n *\/\npublic class VelocityRepresentation extends TemplateRepresentation {\n\n    public VelocityRepresentation(String templateName, Map dataModel, MediaType mediaType) {\n        super(templateName, dataModel, mediaType);\n        configureEngine();\n    }\n\n    public VelocityRepresentation(String templateName, MediaType mediaType) {\n        super(templateName, mediaType);\n        configureEngine();\n    }\n\n    \/**\n     * This method sets some configuration properties to the VelocityEngine.\n     *\/\n    protected void configureEngine() {\n        getEngine().setProperty(RuntimeConstants.RESOURCE_LOADER, \"class\");\n        getEngine().setProperty(\"class.resource.loader.class\",\n                \"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader\");\n        getEngine().setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, new Log4JLogChute());\n        getEngine().setProperty(Log4JLogChute.RUNTIME_LOG_LOG4J_LOGGER, \"ELNINO\");\n    }\n}\n<\/pre>\n<h3>Utilisation de l&#8217;HTTP Component<\/h3>\n<p>Restlet peut utiliser un composant HTTP basique, tr\u00e8s l\u00e9ger et tr\u00e8s rapide qui permet de tester facilement une application, il peut aussi \u00eatre utilis\u00e9 en production bien que pour ma part je d\u00e9ploie l&#8217;application sur un serveur WebSphere en production donc je ne peut vous donner du feedback sur une utilisation en production.<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n\n    \n        \n            \n            \n        \n    \n    \n\n\n\n    \n        <map>\n            \n                \n            \n        <\/map>\n    \n\n<\/pre>\n<p>Ici, on d\u00e9finit un SpringComponent qui sera un serveur HTTP qui servira les ressource. Celui-ci a comme routeur par d\u00e9faut un SpringRouter qui contient en unique attachement notre routeur de catalog. Mais on pourrais lui ajouter d&#8217;autre routeur pour d\u00e9finir un ensemble de ressources.<\/p>\n<p>Il ne nous reste plus qu&#8217;\u00e0 faire une classe java dont le main va charger nos fichier Spring, rechercher le bin du SpringComponent et le d\u00e9marrer.<\/p>\n<p>On acc\u00e9dera ensuite \u00e0 l&#8217;application via une URL du type: <a href=\"http:\/\/localhost:3001\/catalog\/product\/monProduct.en.html\">http:\/\/localhost:3001\/catalog\/product\/monProduct.en.html<\/a><\/p>\n<h3>Deployement comme une servlet<\/h3>\n<p>On peut aussi facillement inclure notre application restlet dans une servlet. Pour ceci il faut utiliser la RestletFrameworkServlet de l&#8217;extension Spring dans notre web.xml comme ci-dessous<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n<!-- Restlet adapter -->\n\n    api\n    com.noelios.restlet.ext.spring.RestletFrameworkServlet\n    \n        targetRestletBeanName\n        restletApplication\n    \n    1\n \n\n \n     api\n     \/*\n \n<\/pre>\n<p>Puis d\u00e9finir un context pour notre servlet qui va d\u00e9finir une application restlet qui utilisera, comme notre http component pr\u00e9c\u00e9dent, le d\u00e9fault routeur.<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n\n    \n\n\n\n    \n        <map>\n            \n                \n            \n        <\/map>\n    \n\n<\/pre>\n<p>On acc\u00e9dera ensuite \u00e0 l&#8217;application via une URL du type: <a href=\"http:\/\/localhost:8080\/&lt;webContext&gt;catalog\/product\/monProduct.en.html\">http:\/\/localhost:8080\/&lt;webContext&gt;catalog\/product\/monProduct.en.html<\/a> o\u00f9 <em>webContext <\/em>est le context du WAR de votre application.<\/p>\n<p>J&#8217;esp\u00e8re que ceci vous aura montrer toute la puissance de Restlet et de son extension Spring. Le code montr\u00e9 ici est un exemple <em>non fonctionnel<\/em> tir\u00e9 du code que j&#8217;ai cr\u00e9\u00e9e pour ma soci\u00e9t\u00e9 et qui tourne en production depuis plus d&#8217;un an.<\/p>\n<h3>Source des exemples<\/h3>\n<p><a href=\"http:\/\/www.loicmathieu.fr\/wordpress\/wp-content\/uploads\/catalog-ctx.xml\">catalog-ctx.xml<\/a>\n<a href=\"http:\/\/www.loicmathieu.fr\/wordpress\/wp-content\/uploads\/productresource.java\">ProductResource.java<\/a>\n<a href=\"http:\/\/www.loicmathieu.fr\/wordpress\/wp-content\/uploads\/velocityrepresentation.java\">VelocityRepresentation.java\n<\/a>\n<a href=\"http:\/\/www.loicmathieu.fr\/wordpress\/wp-content\/uploads\/restletcomponent-ctx.xml\">restletComponent-ctx.xml<\/a>\n<a href=\"http:\/\/www.loicmathieu.fr\/wordpress\/wp-content\/uploads\/web.xml\">web.xml<\/a>\n<a href=\"http:\/\/www.loicmathieu.fr\/wordpress\/wp-content\/uploads\/api-servelt.xml\">api-servelt.xml<\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Cet article fait suite mon article REST &#8211; Architecture Orient\u00e9e Ressource en lui donnant une impl\u00e9mentation bas\u00e9 sur le framework Restlet. Le principe de Restlet : Restlet est un framework Java 5.0 qui ob\u00e9it aux standard RESTful et permet de cr\u00e9er facilement des application RESTful. Il remplace la sp\u00e9cification J2EE par une API orient\u00e9e REST : on d\u00e9veloppe des Restlet au lieu de d\u00e9velopper des Servlet. Il existe deux composant principaux: Router : permet de router une requ\u00eate HTTP vers&#8230;<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/implementer-une-architecture-de-service-web-restfull-avec-restlet-et-son-extention-spring\/\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[9],"tags":[151,11,86,89,101],"class_list":["post-269","post","type-post","status-publish","format-standard","hentry","category-informatique","tag-informatique","tag-java","tag-rest","tag-restful","tag-restlet"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":92,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/rest-architecture-orientee-ressource\/","url_meta":{"origin":269,"position":0},"title":"REST &#8211; Architecture Orient\u00e9e Ressource","author":"admin","date":"Wednesday March 25th, 2009","format":false,"excerpt":"Au menu aujourd'hui, un sujet tr\u00e8s tendance: REST. Abord\u00e9\u00a0 par le biais de l'Architecture Orient\u00e9 Ressource (ou ROA: Resource Oriented Architecture), autrement dit, comment cr\u00e9er une architecture de service bas\u00e9 sur REST. D\u00e9finitions Comme toujours, commen\u00e7ons par quelques d\u00e9finitions. Je vais les faire assez th\u00e9orique sinon apr\u00e8s, il ne me\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":69,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/rdf-et-la-forme-n3\/","url_meta":{"origin":269,"position":1},"title":"RDF et la forme N3","author":"admin","date":"Monday April 21st, 2008","format":false,"excerpt":"Bonjour, au menu ajourd'hui: RDF et la forme N3, avec quelques exemples en JAVA avec l'aide du framework Jena. D\u00e9finition Bon, je pense qu'une petite d\u00e9finition de ces termes barbare s'impose: RDF: Resource Description Framework. Difficile d'expliquer en quelque mots ce que veut dire RDF! C'est une repr\u00e9sentation de donn\u00e9es\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":377,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/session-chti-jug-sur-les-technologies-google\/","url_meta":{"origin":269,"position":2},"title":"Ch&#8217;ti Jug: les technologies Google","author":"admin","date":"Wednesday November 11th, 2009","format":false,"excerpt":"Hello, Lundi j'ai \u00e9t\u00e9 \u00e0 la session du Ch'ti Jug sur les technologies Google qui s'est pass\u00e9 \u00e0 l'ISEN et \u00e9tait sponsoris\u00e9e par SII. C'\u00e9tait la premi\u00e8re fois que j'assistais \u00e0 un \u00e9v\u00e8nement organis\u00e9 par le Ch'ti Jug et comme c'\u00e9tait int\u00e9ressant, j'aimerais partager avec vous l\u00e0 dessus. Ch'ti Jug?\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"Google Wave","src":"https:\/\/i0.wp.com\/loicmathieu.free.fr\/wordpress\/wp-content\/uploads\/google-wave.jpg?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.free.fr\/wordpress\/wp-content\/uploads\/google-wave.jpg?resize=350%2C200 1x, https:\/\/i0.wp.com\/loicmathieu.free.fr\/wordpress\/wp-content\/uploads\/google-wave.jpg?resize=525%2C300 1.5x"},"classes":[]},{"id":761,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/cache-http-client-avec-cxf\/","url_meta":{"origin":269,"position":3},"title":"(Fran\u00e7ais) Cache HTTP Client avec CXF","author":"admin","date":"Thursday February  8th, 2018","format":false,"excerpt":"Sorry, this entry is only available in Fran\u00e7ais.","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":73,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/owl-language-rdf-d-ontologie\/","url_meta":{"origin":269,"position":4},"title":"OWL &#8211; language RDF d&#8217;ontologie","author":"admin","date":"Wednesday May 28th, 2008","format":false,"excerpt":"Introduction OWL est vraiment un gros morceau! Et la notion d'ontologie (ou ontology si on utilise le terme anglais) web aussi. Bien sur il existe de nombreux articles, la plupart r\u00e9dig\u00e9s en anglais, sur ce domaine et la plupart totalement obscure. En fait, quand j'ai commenc\u00e9 \u00e0 travailler sur OWL,\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"Cr\u00e9ation d'une ontologie OWL avec prot\u00e9g\u00e9 - \u00e9tape 1","src":"https:\/\/i0.wp.com\/loicmathieu.free.fr\/wordpress\/wp-content\/uploads\/owl-protege-1.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":64,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/convention-over-configuration\/","url_meta":{"origin":269,"position":5},"title":"convention over configuration","author":"admin","date":"Wednesday December 19th, 2007","format":false,"excerpt":"\"Convention over Configuration\" (on trouve parfois une traduction par \"convention plut\u00f4t que configuration), ce design pattern (ou patron de conception, pour faire plaisir aux francophones intransigeant) est un des plus int\u00e9r\u00e9ssant de ceux \u00e0 la mode en ce moment. Le principe en est tr\u00e8s simple: les applications se basent sur\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/posts\/269","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/comments?post=269"}],"version-history":[{"count":0,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/posts\/269\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/media?parent=269"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/categories?post=269"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/tags?post=269"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}