camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Bindy
Date Fri, 02 Mar 2012 13:23:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CAMEL/Bindy">Bindy</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~bbarin">Bruno Barin</a>
    </h4>
        <br/>
                         <h4>Changes (9)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>|| Parameter name || type || Info || <br></td></tr>
            <tr><td class="diff-changed-lines" >| separator | string | mandatory - can be &#39;,&#39; or &#39;;&#39; or &#39;anything&#39;. This value is interpreted as a regular expression. If you want to use a sign which has a special meaning in regular expressions, e.g. the &#39;\|&#39; sign, than you have to mask it, like &#39; <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">|&#39; |</span> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">\|&#39; | <br></td></tr>
            <tr><td class="diff-unchanged" >| skipFirstLine | boolean | optional - default value = false - allow to skip the first line of the CSV file | <br>| crlf | string | optional - default value = WINDOWS - allow to define the carriage return character to use | <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >| isOrdered | boolean | optional - default value = false - allow to change the order of the fields when CSV is generated | <br>| quote | String | *Camel 2.8.3/2.9:* option - allow to specify a quote character of the fields when CSV is generated | <br></td></tr>
            <tr><td class="diff-unchanged" >| | | This annotation is associated to the root class of the model and must be declared one time. | <br></td></tr>
            <tr><td class="diff-unchanged" > <br>*case 1 : separator = &#39;,&#39;* <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >*case 3 : separator = <span class="diff-changed-words">&#39;<span class="diff-added-chars"style="background-color: #dfd;">\</span>|&#39;*</span> <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >Compare to the previous case, the separator here is <span class="diff-changed-words">&#39;<span class="diff-added-chars"style="background-color: #dfd;">\</span>|&#39;</span> instead of &#39;;&#39; : <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">10| J| Pauline| M| XD12345678| Fortis Dynamic 15/15| 2500| USD| 08-01-2009 <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">10\| J\| Pauline\| M\| XD12345678\| Fortis Dynamic 15/15\| 2500\| USD\| 08-01-2009 <br></td></tr>
            <tr><td class="diff-unchanged" > <br>{code} <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >to tell camel bindy how to handle this case. To define the field containing the data with a comma, you will use simple or double quotes <br>as delimiter (e.g : &#39;10&#39;, &#39;Street 10, NY&#39;, &#39;USA&#39; or &quot;10&quot;, &quot;Street 10, NY&quot;, &quot;USA&quot;). <br></td></tr>
            <tr><td class="diff-unchanged" >Remark : In this case, the first and last character of the line which are a simple or double quotes will removed by bindy <br></td></tr>
            <tr><td class="diff-unchanged" > <br>&quot;10&quot;,&quot;J&quot;,&quot;Pauline&quot;,&quot; M&quot;,&quot;XD12345678&quot;,&quot;Fortis Dynamic 15,15&quot; 2500&quot;,&quot;USD&quot;,&quot;08-01-2009&quot; <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >*case 5 : separator &amp; skipfirstline* <br> <br></td></tr>
            <tr><td class="diff-unchanged" >The feature is interesting when the client wants to have in the first line of the file, the name of the data fields : <br></td></tr>
            <tr><td class="diff-unchanged" > <br>order id, client id, first name, last name, isin code, instrument name, quantity, currency, date <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >*case 6 : generateHeaderColumns* <br> <br></td></tr>
            <tr><td class="diff-unchanged" >To add at the first line of the CSV generated, the attribute generateHeaderColumns must be set to true in the annotation like this : <br></td></tr>
            <tr><td class="diff-unchanged" > <br>{code} <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >h3. 2. Link <br> <br></td></tr>
            <tr><td class="diff-unchanged" >The link annotation will allow to link objects together. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>|| Annotation name || Record type || Level || <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >| required | boolean | optional - default value = &quot;false&quot; | <br>| trim | boolean | optional - default value = &quot;false&quot; | <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">| defaultValue | string | optional - default value = &quot;&quot; - defines the field&#39;s default value when the respective CSV field is empty/not available | <br></td></tr>
            <tr><td class="diff-unchanged" > <br>*case 1 : pos* <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >The position attribute will inform bindy how to place the field in the CSV record generated. By default, the position used corresponds to the position defined with the attribute &#39;pos&#39;. If the position is different (that means that we have an asymetric processus comparing marshaling from unmarshaling) than we can use &#39;position&#39; to indicate this. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >Here is an example <br></td></tr>
            <tr><td class="diff-unchanged" > <br>{code:title=Position is different in output} <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >If this field is not present in the record, than an error will be raised by the parser with the following information : <br> <br></td></tr>
            <tr><td class="diff-unchanged" >Some fields are missing (optional or mandatory), line : <br></td></tr>
            <tr><td class="diff-unchanged" > <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">*case 7 : defaultValue* <br> <br>If a field is not defined then uses the value indicated by the defaultValue attribute <br> <br>{code:title=Default value} <br>@CsvRecord(separator = &quot;,&quot;) <br>public class Order { <br> <br>    @DataField(pos = 1) <br>    private int orderNr; <br> <br>    @DataField(pos = 2) <br>    private Integer clientNr; <br> <br>    @DataField(pos = 3, required = true) <br>    private String firstName; <br> <br>    @DataField(pos = 4, defaultValue = &quot;Barin&quot;) <br>    private String lastName; <br>... <br>} <br>{code} <br>{note} <br>This attribute is only applicable to optional fields. <br>{note} <br> <br>h3. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h3. 4. FixedLengthRecord <br> <br>The FixedLengthRecord annotation is used to identified the root class of the model. It represents a record = a line of a file/message containing data fixed length formatted <br></td></tr>
            <tr><td class="diff-unchanged" >and can be linked to several children model classes. This format is a bit particular beause data of a field can be aligned to the right or to the left.
When the size of the data does not fill completely the length of the field, then we add &#39;padd&#39; characters. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>|| Annotation name || Record type || Level || <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >| length | int | mandatory = size of the fixed length record | <br>| hasHeader | boolean | optional - NOT YET IMPLEMENTED | <br></td></tr>
            <tr><td class="diff-unchanged" >| hasFooter | boolean | optional - NOT YET IMPLEMENTED |
| | | This annotation is associated to the root class of the model and must be declared one time. | <br></td></tr>
            <tr><td class="diff-unchanged" > <br>*case 1 : Simple fixed length record* <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >|| Parameter name || type || Info || <br>| pairSeparator | string | mandatory - can be &#39;=&#39; or &#39;;&#39; or &#39;anything&#39; | <br></td></tr>
            <tr><td class="diff-unchanged" >| keyValuePairSeparair | string | mandatory - can be &#39;\u0001&#39;, &#39;\u0009&#39;, &#39;#&#39; or &#39;anything&#39; | <br></td></tr>
            <tr><td class="diff-unchanged" >| crlf | string | optional - default value = WINDOWS - allow to define the carriage return character to use | <br>| type | string | optional - define the type of message (e.g. FIX, EMX, ...) | <br>| version | string | optional - version of the message (e.g. 4.1) | <br>| isOrdered | boolean | optional - default value = false - allow to change the order of the fields when FIX message is generated | <br></td></tr>
            <tr><td class="diff-unchanged" >| | | This annotation is associated to the message class of the model and must be declared one time. | <br></td></tr>
            <tr><td class="diff-unchanged" > <br>*case 1 : separator = &#39;u0001&#39;* <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>|| Annotation name || Record type || Level || <br></td></tr>
            <tr><td class="diff-unchanged" >| *KeyValuePairField* | Key Value Pair - FIX | Property | <br></td></tr>
            <tr><td class="diff-unchanged" > <br>|| Parameter name || type || Info || <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >@Message(keyValuePairSeparator = &quot;=&quot;, pairSeparator = &quot;\u0001&quot;, type=&quot;FIX&quot;, version=&quot;4.1&quot;) <br>public class Order { <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @Link Header header; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @Link Trailer trailer; <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >    @KeyValuePairField(tag = 11) // Order reference <br>    private String ClOrdId; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @KeyValuePairField(tag = 22) // Fund ID type (Sedol, ISIN, ...) <br>    private String IDSource; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @KeyValuePairField(tag = 48) // Fund code <br>    private String SecurityId; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @KeyValuePairField(tag = 54) // Movement type ( 1 = Buy, 2 = sell) <br>    private String Side; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @KeyValuePairField(tag = 58) // Free text <br>    private String Text; <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >@Message(keyValuePairSeparator = &quot;=&quot;, pairSeparator = &quot;\\u0001&quot;, type = &quot;FIX&quot;, version = &quot;4.1&quot;, isOrdered = true) <br>public class Order { <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @Link Header header; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @Link Trailer trailer; <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>|| Annotation name || Record type || Level || <br></td></tr>
            <tr><td class="diff-unchanged" >| *Section* | FIX | Class | <br></td></tr>
            <tr><td class="diff-unchanged" > <br>|| Parameter name || type || Info || <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >@Message(keyValuePairSeparator = &quot;=&quot;, pairSeparator = &quot;\\u0001&quot;, type = &quot;FIX&quot;, version = &quot;4.1&quot;, isOrdered = true) <br>public class Order { <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @Link Header header; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @Link Trailer trailer; <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >h3. 8. OneToMany <br> <br></td></tr>
            <tr><td class="diff-unchanged" >The purpose of the annotation @OneToMany is to allow to work with a List&lt;?&gt; field defined a POJO class or from a record containing repetitive groups. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>{note:title=Restrictions OneToMany} <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>|| Parameter name || type || Info || <br></td></tr>
            <tr><td class="diff-unchanged" >| mappedTo | string | optional - string - class name associated to the type of the List&lt;Type of the Class&gt; | <br></td></tr>
            <tr><td class="diff-unchanged" > <br>*case 1 : Generating CSV with repetitive data* <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>{code:title=Generate CSV with repetitive data} <br></td></tr>
            <tr><td class="diff-unchanged" >@CsvRecord(separator=&quot;,&quot;) <br>public class Author { <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >	@DataField(pos = 1) <br>	private String firstName; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >	@DataField(pos = 2) <br>	private String lastName; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >	@OneToMany <br>	private List&lt;Book&gt; books; <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >	@DataField(pos = 3) <br>	private String title; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >	@DataField(pos = 4) <br>	private String year; <br>{code} <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >Very simple isn&#39;t it <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">!!!</span> <span class="diff-added-words"style="background-color: #dfd;">\!\!\!</span> <br></td></tr>
            <tr><td class="diff-unchanged" > <br>*case 2 : Reading FIX message containing group of tags/keys* <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>&quot;8=FIX 4.19=2034=135=049=INVMGR56=BRKR&quot; <br></td></tr>
            <tr><td class="diff-unchanged" >&quot;1=BE.CHM.00111=CHM0001-0158=this is a camel - bindy test&quot; <br></td></tr>
            <tr><td class="diff-unchanged" >&quot;22=448=BE000124567854=1&quot; <br></td></tr>
            <tr><td class="diff-unchanged" >&quot;22=548=BE000987654354=2&quot; <br></td></tr>
            <tr><td class="diff-unchanged" >&quot;22=648=BE000999999954=3&quot; <br>&quot;10=220&quot; <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>{code:title=Reading FIX message containing group of tags/keys} <br></td></tr>
            <tr><td class="diff-unchanged" >public class Order { <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @Link Header header; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @Link Trailer trailer; <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >    @KeyValuePairField(tag = 11) // Order reference <br>    private String clOrdId; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @KeyValuePairField(tag = 58) // Free text <br>    private String text; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @OneToMany(mappedTo = &quot;org.apache.camel.dataformat.bindy.model.fix.complex.onetomany.Security&quot;) <br>    List&lt;Security&gt; securities; <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>public class Security { <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @KeyValuePairField(tag = 22) // Fund ID type (Sedol, ISIN, ...) <br>    private String idSource; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @KeyValuePairField(tag = 48) // Fund code <br>    private String securityCode; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >    @KeyValuePairField(tag = 54) // Movement type ( 1 = Buy, 2 = sell) <br>    private String side; <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >        } <br>    } <br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h3. Using Spring XML <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >	&lt;bean id=&quot;csv&quot; class=&quot;org.apache.camel.bindy.csv.HandleOrderBean&quot; /&gt; <br> <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >        &lt;!-- Queuing engine - ActiveMq - work locally in mode virtual memory --&gt; <br>	&lt;bean id=&quot;activemq&quot; class=&quot;org.apache.activemq.camel.component.ActiveMQComponent&quot;&gt; <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >			&lt;to uri=&quot;activemq:queue:in&quot; /&gt; <br>		&lt;/route&gt; <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-unchanged" >		&lt;route&gt; <br>			&lt;from uri=&quot;activemq:queue:in&quot; /&gt; <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h2><a name="Bindy-Bindy"></a>Bindy</h2>

<p><b>Available as of Camel 2.0</b></p>

<p>The idea that the developers has followed to design this component was to allow the parsing/binding of non structured data (or to be more precise non-XML data)<br/>
to Java Bean using annotations. Using Bindy, you can bind data like :</p>
<ul class="alternate" type="square">
	<li>CSV record,</li>
	<li>Fixedlength record,</li>
	<li>FIX messages,</li>
	<li>or any other non-structured data</li>
</ul>


<p>to one or many Plain Old Java Object (POJO) and to convert the data according to the type of the java property. POJO  can be linked together and relation one to many is available in some cases. Moreover, for data type like Date, Double, Float, Integer, Short, Long and BigDecimal, you can provide the pattern to apply during the formatting of the property.</p>

<p>For the BigDecimal number, you can also define the precision and the decimal or grouping separators</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Type </th>
<th class='confluenceTh'> Format Type </th>
<th class='confluenceTh'> Pattern example </th>
<th class='confluenceTh'> Link </th>
</tr>
<tr>
<td class='confluenceTd'> Date </td>
<td class='confluenceTd'> DateFormat </td>
<td class='confluenceTd'> "dd-MM-yyyy" </td>
<td class='confluenceTd'> <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/text/SimpleDateFormat.html" class="external-link" rel="nofollow">http://java.sun.com/j2se/1.5.0/docs/api/java/text/SimpleDateFormat.html</a> </td>
</tr>
<tr>
<td class='confluenceTd'> Decimal&#42; </td>
<td class='confluenceTd'> Decimalformat </td>
<td class='confluenceTd'> "##.###.###" </td>
<td class='confluenceTd'> <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/text/DecimalFormat.html" class="external-link" rel="nofollow">http://java.sun.com/j2se/1.5.0/docs/api/java/text/DecimalFormat.html</a> </td>
</tr>
</tbody></table>
</div>

<p>Decimal&#42; = Double, Integer, Float, Short, Long</p>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>Format supported</b><br />This first release only support comma separated values fields and key value pair fields (e.g. : FIX messages).</td></tr></table></div>
<p>To work with camel-bindy, you must first define your model in a package (e.g. com.acme.model) and for each model class (e.g. Order, Client, Instrument, ...) associate the required annotations (described hereafter) with Class or property name.</p>

<h2><a name="Bindy-Annotations"></a>Annotations</h2>

<p>The annotations created allow to map different concept of your model to the POJO like :</p>

<ul class="alternate" type="square">
	<li>Type of record (csv, key value pair (e.g. FIX message), fixed length ...),</li>
	<li>Link (to link object in another object),</li>
	<li>DataField and their properties (int, type, ...),</li>
	<li>KeyValuePairField (for key = value format like we have in FIX financial messages),</li>
	<li>Section (to identify header, body and footer section),</li>
	<li>OneToMany</li>
</ul>


<p>This section will describe them :</p>

<h3><a name="Bindy-1.CsvRecord"></a>1. CsvRecord</h3>

<p>The CsvRecord annotation is used to identified the root class of the model. It represents a record = a line of a CSV file and can be linked to several children model classes.</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Annotation name </th>
<th class='confluenceTh'> Record type </th>
<th class='confluenceTh'> Level </th>
</tr>
<tr>
<td class='confluenceTd'> <b>CsvRecord</b> </td>
<td class='confluenceTd'> csv </td>
<td class='confluenceTd'> Class </td>
</tr>
</tbody></table>
</div>


<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Parameter name </th>
<th class='confluenceTh'> type </th>
<th class='confluenceTh'> Info </th>
</tr>
<tr>
<td class='confluenceTd'> separator </td>
<td class='confluenceTd'> string </td>
<td class='confluenceTd'> mandatory - can be ',' or ';' or 'anything'. This value is interpreted as a regular expression. If you want to use a sign which has a special meaning in regular expressions, e.g. the '&#124;' sign, than you have to mask it, like ' <br class="atl-forced-newline" />
&#124;' </td>
</tr>
<tr>
<td class='confluenceTd'> skipFirstLine </td>
<td class='confluenceTd'> boolean </td>
<td class='confluenceTd'> optional - default value = false - allow to skip the first line of the CSV file </td>
</tr>
<tr>
<td class='confluenceTd'> crlf </td>
<td class='confluenceTd'> string </td>
<td class='confluenceTd'> optional - default value = WINDOWS - allow to define the carriage return character to use </td>
</tr>
<tr>
<td class='confluenceTd'> generateHeaderColumns </td>
<td class='confluenceTd'> boolean </td>
<td class='confluenceTd'> optional - default value = false - uses to generate the header columns of the CSV generates </td>
</tr>
<tr>
<td class='confluenceTd'> isOrdered </td>
<td class='confluenceTd'> boolean </td>
<td class='confluenceTd'> optional - default value = false - allow to change the order of the fields when CSV is generated </td>
</tr>
<tr>
<td class='confluenceTd'> quote </td>
<td class='confluenceTd'> String </td>
<td class='confluenceTd'> <b>Camel 2.8.3/2.9:</b> option - allow to specify a quote character of the fields when CSV is generated </td>
</tr>
<tr>
<td class='confluenceTd'>&nbsp;</td>
<td class='confluenceTd'>&nbsp;</td>
<td class='confluenceTd'> This annotation is associated to the root class of the model and must be declared one time. </td>
</tr>
</tbody></table>
</div>


<p><b>case 1 : separator = ','</b></p>

<p>The separator used to segregate the fields in the CSV record is ',' :</p>

<p>10, J, Pauline, M, XD12345678, Fortis Dynamic 15/15, 2500, USD,08-01-2009</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord( separator = <span class="code-quote">","</span> )
<span class="code-keyword">public</span> <span class="code-object">Class</span> Order {
...
}
</pre>
</div></div>

<p><b>case 2 : separator = ';'</b></p>

<p>Compare to the previous case, the separator here is ';' instead of ',' :</p>

<p>10; J; Pauline; M; XD12345678; Fortis Dynamic 15/15; 2500; USD; 08-01-2009</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord( separator = <span class="code-quote">";"</span> )
<span class="code-keyword">public</span> <span class="code-object">Class</span> Order {
...
}
</pre>
</div></div>

<p><b>case 3 : separator = '&#124;'</b></p>

<p>Compare to the previous case, the separator here is '&#124;' instead of ';' :</p>

<p>10&#124; J&#124; Pauline&#124; M&#124; XD12345678&#124; Fortis Dynamic 15/15&#124; 2500&#124; USD&#124; 08-01-2009</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord( separator = <span class="code-quote">"\\|"</span> )
<span class="code-keyword">public</span> <span class="code-object">Class</span> Order {
...
}
</pre>
</div></div>

<p><b>case 4 : separator = '\",\"'</b><br/>
<b>Applies for Camel 2.8.2 or older</b></p>

<p>When the field to be parsed of the CSV record contains ',' or ';' which is also used as separator, we whould find another strategy<br/>
to tell camel bindy how to handle this case. To define the field containing the data with a comma, you will use simple or double quotes<br/>
as delimiter (e.g : '10', 'Street 10, NY', 'USA' or "10", "Street 10, NY", "USA").<br/>
Remark : In this case, the first and last character of the line which are a simple or double quotes will removed by bindy</p>

<p>"10","J","Pauline"," M","XD12345678","Fortis Dynamic 15,15" 2500","USD","08-01-2009"</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord( separator = <span class="code-quote">"\"</span>,\"" )
<span class="code-keyword">public</span> <span class="code-object">Class</span> Order {
...
}
</pre>
</div></div>

<p>From <b>Camel 2.8.3/2.9 or never</b> bindy will automatic detect if the record is enclosed with either single or double quotes and automatic remove those quotes when unmarshalling from CSV to Object. Therefore do <b>not</b> include the quotes in the separator, but simple do as below:</p>

<p>"10","J","Pauline"," M","XD12345678","Fortis Dynamic 15,15" 2500","USD","08-01-2009"</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord( separator = <span class="code-quote">","</span> )
<span class="code-keyword">public</span> <span class="code-object">Class</span> Order {
...
}
</pre>
</div></div>

<p>Notice that if you want to marshal from Object to CSV and use quotes, then you need to specify which quote character to use, using the <tt>quote</tt> attribute on the @CsvRecord as shown below:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord( separator = <span class="code-quote">","</span>, quote = <span class="code-quote">"\"</span>" )
<span class="code-keyword">public</span> <span class="code-object">Class</span> Order {
...
}
</pre>
</div></div>


<p><b>case 5 : separator &amp; skipfirstline</b></p>

<p>The feature is interesting when the client wants to have in the first line of the file, the name of the data fields :</p>

<p>order id, client id, first name, last name, isin code, instrument name, quantity, currency, date</p>

<p>To inform bindy that this first line must be skipped during the parsing process, then we use the attribute :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord(separator = <span class="code-quote">","</span>, skipFirstLine = <span class="code-keyword">true</span>)
<span class="code-keyword">public</span> <span class="code-object">Class</span> Order {
...
}
</pre>
</div></div>

<p><b>case 6 : generateHeaderColumns</b></p>

<p>To add at the first line of the CSV generated, the attribute generateHeaderColumns must be set to true in the annotation like this :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord( generateHeaderColumns = <span class="code-keyword">true</span> )
<span class="code-keyword">public</span> <span class="code-object">Class</span> Order {
...
}
</pre>
</div></div>

<p>As a result, Bindy during the unmarshaling process will generate CSV like this :</p>

<p>order id, client id, first name, last name, isin code, instrument name, quantity, currency, date<br/>
10, J, Pauline, M, XD12345678, Fortis Dynamic 15/15, 2500, USD,08-01-2009</p>

<p><b>case 7 : carriage return</b></p>

<p>If the platform where camel-bindy will run is not Windows but Macintosh or Unix, than you can change the crlf property like this. Three values are available : WINDOWS, UNIX or MAC</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord(separator = <span class="code-quote">","</span>, crlf=<span class="code-quote">"MAC"</span>)
<span class="code-keyword">public</span> <span class="code-object">Class</span> Order {
...
}
</pre>
</div></div>

<p><b>case 8 : isOrdered</b></p>

<p>Sometimes, the order to follow during the creation of the CSV record from the model is different from the order used during the parsing. Then, in this case, we can use the attribute isOrdered = true to indicate this in combination with attribute 'position' of the DataField annotation.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord(isOrdered = <span class="code-keyword">true</span>)
<span class="code-keyword">public</span> <span class="code-object">Class</span> Order {

   @DataField(pos = 1, position = 11)
   <span class="code-keyword">private</span> <span class="code-object">int</span> orderNr;

   @DataField(pos = 2, position = 10)
   <span class="code-keyword">private</span> <span class="code-object">String</span> clientNr;

...
}
</pre>
</div></div>

<p>Remark : pos is used to parse the file, stream while positions is used to generate the CSV</p>


<h3><a name="Bindy-2.Link"></a>2. Link</h3>

<p>The link annotation will allow to link objects together.</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Annotation name </th>
<th class='confluenceTh'> Record type </th>
<th class='confluenceTh'> Level </th>
</tr>
<tr>
<td class='confluenceTd'> <b>Link</b> </td>
<td class='confluenceTd'> all </td>
<td class='confluenceTd'> Class &amp; Property </td>
</tr>
</tbody></table>
</div>


<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Parameter name </th>
<th class='confluenceTh'> type </th>
<th class='confluenceTh'> Info </th>
</tr>
<tr>
<td class='confluenceTd'> linkType </td>
<td class='confluenceTd'> LinkType </td>
<td class='confluenceTd'> optional - by default the value is LinkType.oneToOne - so you are not obliged to mention it </td>
</tr>
<tr>
<td class='confluenceTd'>&nbsp;</td>
<td class='confluenceTd'>&nbsp;</td>
<td class='confluenceTd'> Only one-to-one relation is allowed. </td>
</tr>
</tbody></table>
</div>


<p>e.g : If the model Class Client is linked to the Order class, then use annotation Link in the Order class like this :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Property Link</b></div><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord(separator = <span class="code-quote">","</span>)
<span class="code-keyword">public</span> class Order {

    @DataField(pos = 1)
    <span class="code-keyword">private</span> <span class="code-object">int</span> orderNr;

    @Link
    <span class="code-keyword">private</span> Client client;
...
</pre>
</div></div>

<p>AND for the class Client :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Class Link</b></div><div class="codeContent panelContent">
<pre class="code-java">
@Link
<span class="code-keyword">public</span> class Client {
...
}
</pre>
</div></div>


<h3><a name="Bindy-3.DataField"></a>3. DataField</h3>

<p>The DataField annotation defines the property of the field. Each datafield is identified by its position in the record, a type (string, int, date, ...) and optionally of a pattern</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Annotation name </th>
<th class='confluenceTh'> Record type </th>
<th class='confluenceTh'> Level </th>
</tr>
<tr>
<td class='confluenceTd'> <b>DataField</b> </td>
<td class='confluenceTd'> all </td>
<td class='confluenceTd'> Property </td>
</tr>
</tbody></table>
</div>


<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Parameter name </th>
<th class='confluenceTh'> type </th>
<th class='confluenceTh'> Info </th>
</tr>
<tr>
<td class='confluenceTd'> pos </td>
<td class='confluenceTd'> int </td>
<td class='confluenceTd'> mandatory - digit number starting from 1 to ... </td>
</tr>
<tr>
<td class='confluenceTd'> pattern </td>
<td class='confluenceTd'> string </td>
<td class='confluenceTd'> optional - default value = "" - will be used to format Decimal, Date, ... </td>
</tr>
<tr>
<td class='confluenceTd'> length </td>
<td class='confluenceTd'> int </td>
<td class='confluenceTd'> optional - represents the length of the field for fixed length format </td>
</tr>
<tr>
<td class='confluenceTd'> precision </td>
<td class='confluenceTd'> int </td>
<td class='confluenceTd'> optional - represents the precision to be used when the Decimal number will be formatted/parsed </td>
</tr>
<tr>
<td class='confluenceTd'> pattern </td>
<td class='confluenceTd'> string </td>
<td class='confluenceTd'> optional - default value = "" - is used by the Java Formater (SimpleDateFormat by example) to format/validate data </td>
</tr>
<tr>
<td class='confluenceTd'> position </td>
<td class='confluenceTd'> int </td>
<td class='confluenceTd'> optional - must be used when the position of the field in the CSV generated must be different compare to pos </td>
</tr>
<tr>
<td class='confluenceTd'> required </td>
<td class='confluenceTd'> boolean </td>
<td class='confluenceTd'> optional - default value = "false" </td>
</tr>
<tr>
<td class='confluenceTd'> trim </td>
<td class='confluenceTd'> boolean </td>
<td class='confluenceTd'> optional - default value = "false" </td>
</tr>
<tr>
<td class='confluenceTd'> defaultValue </td>
<td class='confluenceTd'> string </td>
<td class='confluenceTd'> optional - default value = "" - defines the field's default value when the respective CSV field is empty/not available </td>
</tr>
</tbody></table>
</div>


<p><b>case 1 : pos</b></p>

<p>This parameter/attribute represents the position of the field in the csv record</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Position</b></div><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord(separator = <span class="code-quote">","</span>)
<span class="code-keyword">public</span> class Order {

    @DataField(pos = 1)
    <span class="code-keyword">private</span> <span class="code-object">int</span> orderNr;

    @DataField(pos = 5)
    <span class="code-keyword">private</span> <span class="code-object">String</span> isinCode;

...
}
</pre>
</div></div>

<p>As you can see in this example the position starts at '1' but continues at '5' in the class Order. The numbers from '2' to '4' are defined in the class Client (see here after).</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Position continues in another model class</b></div><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Client {

    @DataField(pos = 2)
    <span class="code-keyword">private</span> <span class="code-object">String</span> clientNr;

    @DataField(pos = 3)
    <span class="code-keyword">private</span> <span class="code-object">String</span> firstName;

    @DataField(pos = 4)
    <span class="code-keyword">private</span> <span class="code-object">String</span> lastName;
...
}
</pre>
</div></div>

<p><b>case 2 : pattern</b></p>

<p>The pattern allows to enrich or validates the format of your data</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Pattern</b></div><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord(separator = <span class="code-quote">","</span>)
<span class="code-keyword">public</span> class Order {

    @DataField(pos = 1)
    <span class="code-keyword">private</span> <span class="code-object">int</span> orderNr;

    @DataField(pos = 5)
    <span class="code-keyword">private</span> <span class="code-object">String</span> isinCode;

    @DataField(name = <span class="code-quote">"Name"</span>, pos = 6)
    <span class="code-keyword">private</span> <span class="code-object">String</span> instrumentName;

    @DataField(pos = 7, precision = 2)
    <span class="code-keyword">private</span> BigDecimal amount;

    @DataField(pos = 8)
    <span class="code-keyword">private</span> <span class="code-object">String</span> currency;

    @DataField(pos = 9, pattern = <span class="code-quote">"dd-MM-yyyy"</span>) -- pattern used during parsing or when the date is created
    <span class="code-keyword">private</span> Date orderDate;
...
}
</pre>
</div></div>

<p><b>case 3 : precision</b></p>

<p>The precision is helpful when you want to define the decimal part of your number</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Precision</b></div><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord(separator = <span class="code-quote">","</span>)
<span class="code-keyword">public</span> class Order {

    @DataField(pos = 1)
    <span class="code-keyword">private</span> <span class="code-object">int</span> orderNr;

    @Link
    <span class="code-keyword">private</span> Client client;

    @DataField(pos = 5)
    <span class="code-keyword">private</span> <span class="code-object">String</span> isinCode;

    @DataField(name = <span class="code-quote">"Name"</span>, pos = 6)
    <span class="code-keyword">private</span> <span class="code-object">String</span> instrumentName;

    @DataField(pos = 7, precision = 2) -- precision
    <span class="code-keyword">private</span> BigDecimal amount;

    @DataField(pos = 8)
    <span class="code-keyword">private</span> <span class="code-object">String</span> currency;

    @DataField(pos = 9, pattern = <span class="code-quote">"dd-MM-yyyy"</span>)
    <span class="code-keyword">private</span> Date orderDate;
...
}
</pre>
</div></div>

<p><b>case 4 : Position is different in output</b></p>

<p>The position attribute will inform bindy how to place the field in the CSV record generated. By default, the position used corresponds to the position defined with the attribute 'pos'. If the position is different (that means that we have an asymetric processus comparing marshaling from unmarshaling) than we can use 'position' to indicate this.</p>

<p>Here is an example</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Position is different in output</b></div><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord(separator = <span class="code-quote">","</span>)
<span class="code-keyword">public</span> class Order {
@CsvRecord(separator = <span class="code-quote">","</span>, isOrdered = <span class="code-keyword">true</span>)
<span class="code-keyword">public</span> class Order {

    <span class="code-comment">// Positions of the fields start from 1 and not from 0
</span>
    @DataField(pos = 1, position = 11)
    <span class="code-keyword">private</span> <span class="code-object">int</span> orderNr;

    @DataField(pos = 2, position = 10)
    <span class="code-keyword">private</span> <span class="code-object">String</span> clientNr;

    @DataField(pos = 3, position = 9)
    <span class="code-keyword">private</span> <span class="code-object">String</span> firstName;

    @DataField(pos = 4, position = 8)
    <span class="code-keyword">private</span> <span class="code-object">String</span> lastName;

    @DataField(pos = 5, position = 7)
    <span class="code-keyword">private</span> <span class="code-object">String</span> instrumentCode;

    @DataField(pos = 6, position = 6)
    <span class="code-keyword">private</span> <span class="code-object">String</span> instrumentNumber;
...
}
</pre>
</div></div>

<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>This attribute of the annotation @DataField must be used in combination with attribute isOrdered = true of the annotation @CsvRecord</td></tr></table></div>


<p><b>case 5 : required</b></p>

<p>If a field is mandatory, simply use the attribute 'required' setted to true</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Required</b></div><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord(separator = <span class="code-quote">","</span>)
<span class="code-keyword">public</span> class Order {

    @DataField(pos = 1)
    <span class="code-keyword">private</span> <span class="code-object">int</span> orderNr;

    @DataField(pos = 2, required = <span class="code-keyword">true</span>)
    <span class="code-keyword">private</span> <span class="code-object">String</span> clientNr;

    @DataField(pos = 3, required = <span class="code-keyword">true</span>)
    <span class="code-keyword">private</span> <span class="code-object">String</span> firstName;

    @DataField(pos = 4, required = <span class="code-keyword">true</span>)
    <span class="code-keyword">private</span> <span class="code-object">String</span> lastName;
...
}
</pre>
</div></div>

<p>If this field is not present in the record, than an error will be raised by the parser with the following information :</p>

<p>Some fields are missing (optional or mandatory), line :</p>


<p><b>case 6 : trim</b></p>

<p>If a field has leading and/or trailing spaces which should be removed before they are processed, simply use the attribute 'trim' setted to true</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Trim</b></div><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord(separator = <span class="code-quote">","</span>)
<span class="code-keyword">public</span> class Order {

    @DataField(pos = 1, trim = <span class="code-keyword">true</span>)
    <span class="code-keyword">private</span> <span class="code-object">int</span> orderNr;

    @DataField(pos = 2, trim = <span class="code-keyword">true</span>)
    <span class="code-keyword">private</span> <span class="code-object">Integer</span> clientNr;

    @DataField(pos = 3, required = <span class="code-keyword">true</span>)
    <span class="code-keyword">private</span> <span class="code-object">String</span> firstName;

    @DataField(pos = 4)
    <span class="code-keyword">private</span> <span class="code-object">String</span> lastName;
...
}
</pre>
</div></div>

<p><b>case 7 : defaultValue</b></p>

<p>If a field is not defined then uses the value indicated by the defaultValue attribute</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Default value</b></div><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord(separator = <span class="code-quote">","</span>)
<span class="code-keyword">public</span> class Order {

    @DataField(pos = 1)
    <span class="code-keyword">private</span> <span class="code-object">int</span> orderNr;

    @DataField(pos = 2)
    <span class="code-keyword">private</span> <span class="code-object">Integer</span> clientNr;

    @DataField(pos = 3, required = <span class="code-keyword">true</span>)
    <span class="code-keyword">private</span> <span class="code-object">String</span> firstName;

    @DataField(pos = 4, defaultValue = <span class="code-quote">"Barin"</span>)
    <span class="code-keyword">private</span> <span class="code-object">String</span> lastName;
...
}
</pre>
</div></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>This attribute is only applicable to optional fields.</td></tr></table></div>

<h3><a name="Bindy-"></a></h3>

<h3><a name="Bindy-4.FixedLengthRecord"></a>4. FixedLengthRecord</h3>

<p>The FixedLengthRecord annotation is used to identified the root class of the model. It represents a record = a line of a file/message containing data fixed length formatted<br/>
and can be linked to several children model classes. This format is a bit particular beause data of a field can be aligned to the right or to the left.<br/>
When the size of the data does not fill completely the length of the field, then we add 'padd' characters.</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Annotation name </th>
<th class='confluenceTh'> Record type </th>
<th class='confluenceTh'> Level </th>
</tr>
<tr>
<td class='confluenceTd'> <b>FixedLengthRecord</b> </td>
<td class='confluenceTd'> fixed </td>
<td class='confluenceTd'> Class </td>
</tr>
</tbody></table>
</div>


<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Parameter name </th>
<th class='confluenceTh'> type </th>
<th class='confluenceTh'> Info </th>
</tr>
<tr>
<td class='confluenceTd'> crlf </td>
<td class='confluenceTd'> string </td>
<td class='confluenceTd'> optional - default value = WINDOWS - allow to define the carriage return character to use </td>
</tr>
<tr>
<td class='confluenceTd'> paddingChar </td>
<td class='confluenceTd'> char </td>
<td class='confluenceTd'> mandatory - default value = '  ' </td>
</tr>
<tr>
<td class='confluenceTd'> length </td>
<td class='confluenceTd'> int </td>
<td class='confluenceTd'> mandatory = size of the fixed length record </td>
</tr>
<tr>
<td class='confluenceTd'> hasHeader </td>
<td class='confluenceTd'> boolean </td>
<td class='confluenceTd'> optional - NOT YET IMPLEMENTED </td>
</tr>
<tr>
<td class='confluenceTd'> hasFooter </td>
<td class='confluenceTd'> boolean </td>
<td class='confluenceTd'> optional - NOT YET IMPLEMENTED </td>
</tr>
<tr>
<td class='confluenceTd'>&nbsp;</td>
<td class='confluenceTd'>&nbsp;</td>
<td class='confluenceTd'> This annotation is associated to the root class of the model and must be declared one time. </td>
</tr>
</tbody></table>
</div>


<p><b>case 1 : Simple fixed length record</b></p>

<p>This simple example shows how to design the model to parse/format a fixed message</p>

<p>10A9PaulineMISINXD12345678BUYShare2500.45USD01-08-2009</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Fixed-simple</b></div><div class="codeContent panelContent">
<pre class="code-java">
   @FixedLengthRecord(length=54, paddingChar=' ')
    <span class="code-keyword">public</span> <span class="code-keyword">static</span> class Order {

        @DataField(pos = 1, length=2)
        <span class="code-keyword">private</span> <span class="code-object">int</span> orderNr;

        @DataField(pos = 3, length=2)
        <span class="code-keyword">private</span> <span class="code-object">String</span> clientNr;

        @DataField(pos = 5, length=7)
        <span class="code-keyword">private</span> <span class="code-object">String</span> firstName;

        @DataField(pos = 12, length=1, align=<span class="code-quote">"L"</span>)
        <span class="code-keyword">private</span> <span class="code-object">String</span> lastName;

        @DataField(pos = 13, length=4)
        <span class="code-keyword">private</span> <span class="code-object">String</span> instrumentCode;

        @DataField(pos = 17, length=10)
        <span class="code-keyword">private</span> <span class="code-object">String</span> instrumentNumber;

        @DataField(pos = 27, length=3)
        <span class="code-keyword">private</span> <span class="code-object">String</span> orderType;

        @DataField(pos = 30, length=5)
        <span class="code-keyword">private</span> <span class="code-object">String</span> instrumentType;

        @DataField(pos = 35, precision = 2, length=7)
        <span class="code-keyword">private</span> BigDecimal amount;

        @DataField(pos = 42, length=3)
        <span class="code-keyword">private</span> <span class="code-object">String</span> currency;

        @DataField(pos = 45, length=10, pattern = <span class="code-quote">"dd-MM-yyyy"</span>)
        <span class="code-keyword">private</span> Date orderDate;
        ...
</pre>
</div></div>

<p><b>case 2 : Fixed length record with alignment and padding</b></p>

<p>This more elaborated example show how to define the alignment for a field and how to assign a padding character which is ' ' here''</p>

<p>10A9  PaulineM    ISINXD12345678BUYShare2500.45USD01-08-2009</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Fixed-padding-align</b></div><div class="codeContent panelContent">
<pre class="code-java">
   @FixedLengthRecord(length=60, paddingChar=' ')
    <span class="code-keyword">public</span> <span class="code-keyword">static</span> class Order {

        @DataField(pos = 1, length=2)
        <span class="code-keyword">private</span> <span class="code-object">int</span> orderNr;

        @DataField(pos = 3, length=2)
        <span class="code-keyword">private</span> <span class="code-object">String</span> clientNr;

        @DataField(pos = 5, length=9)
        <span class="code-keyword">private</span> <span class="code-object">String</span> firstName;

        @DataField(pos = 14, length=5, align=<span class="code-quote">"L"</span>)   <span class="code-comment">// align text to the LEFT zone of the block
</span>        <span class="code-keyword">private</span> <span class="code-object">String</span> lastName;

        @DataField(pos = 19, length=4)
        <span class="code-keyword">private</span> <span class="code-object">String</span> instrumentCode;

        @DataField(pos = 23, length=10)
        <span class="code-keyword">private</span> <span class="code-object">String</span> instrumentNumber;

        @DataField(pos = 33, length=3)
        <span class="code-keyword">private</span> <span class="code-object">String</span> orderType;

        @DataField(pos = 36, length=5)
        <span class="code-keyword">private</span> <span class="code-object">String</span> instrumentType;

        @DataField(pos = 41, precision = 2, length=7)
        <span class="code-keyword">private</span> BigDecimal amount;

        @DataField(pos = 48, length=3)
        <span class="code-keyword">private</span> <span class="code-object">String</span> currency;

        @DataField(pos = 51, length=10, pattern = <span class="code-quote">"dd-MM-yyyy"</span>)
        <span class="code-keyword">private</span> Date orderDate;
        ...
</pre>
</div></div>

<p><b>case 3 : Field padding</b></p>

<p>Sometimes, the default padding defined for record cannnot be applied to the field as we have a number format where we would like to padd with '0' instead of ' '. In this case, you can use in the model the attribute paddingField to set this value.</p>

<p>10A9  PaulineM    ISINXD12345678BUYShare000002500.45USD01-08-2009</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Fixed-padding-field</b></div><div class="codeContent panelContent">
<pre class="code-java">
    @FixedLengthRecord(length = 65, paddingChar = ' ')
    <span class="code-keyword">public</span> <span class="code-keyword">static</span> class Order {

        @DataField(pos = 1, length = 2)
        <span class="code-keyword">private</span> <span class="code-object">int</span> orderNr;

        @DataField(pos = 3, length = 2)
        <span class="code-keyword">private</span> <span class="code-object">String</span> clientNr;

        @DataField(pos = 5, length = 9)
        <span class="code-keyword">private</span> <span class="code-object">String</span> firstName;

        @DataField(pos = 14, length = 5, align = <span class="code-quote">"L"</span>)
        <span class="code-keyword">private</span> <span class="code-object">String</span> lastName;

        @DataField(pos = 19, length = 4)
        <span class="code-keyword">private</span> <span class="code-object">String</span> instrumentCode;

        @DataField(pos = 23, length = 10)
        <span class="code-keyword">private</span> <span class="code-object">String</span> instrumentNumber;

        @DataField(pos = 33, length = 3)
        <span class="code-keyword">private</span> <span class="code-object">String</span> orderType;

        @DataField(pos = 36, length = 5)
        <span class="code-keyword">private</span> <span class="code-object">String</span> instrumentType;

        @DataField(pos = 41, precision = 2, length = 12, paddingChar = '0')
        <span class="code-keyword">private</span> BigDecimal amount;

        @DataField(pos = 53, length = 3)
        <span class="code-keyword">private</span> <span class="code-object">String</span> currency;

        @DataField(pos = 56, length = 10, pattern = <span class="code-quote">"dd-MM-yyyy"</span>)
        <span class="code-keyword">private</span> Date orderDate;
        ...
</pre>
</div></div>

<h3><a name="Bindy-5.Message"></a>5. Message</h3>

<p>The Message annotation is used to identified the class of your model who will contain key value pairs fields. This kind of format is used mainly in Financial Exchange Protocol Messages (FIX). Nevertheless, this annotation can be used for any other format where data are identified by keys. The key pair values are separated each other by a separator which can be a special character like a tab delimitor (unicode representation : \u0009) or a start of heading (unicode representation : \u0001)</p>

<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>"FIX information"</b><br />More information about FIX can be found on this web site : <a href="http://www.fixprotocol.org/" class="external-link" rel="nofollow">http://www.fixprotocol.org/</a>. To work with FIX messages, the model must contain a Header and Trailer classes linked to the root message class which could be a Order class. This is not mandatory but will be very helpful when you will use camel-bindy in combination with camel-fix which is a Fix gateway based on quickFix project <a href="http://www.quickfixj.org/" class="external-link" rel="nofollow">http://www.quickfixj.org/</a>.</td></tr></table></div>


<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Annotation name </th>
<th class='confluenceTh'> Record type </th>
<th class='confluenceTh'> Level </th>
</tr>
<tr>
<td class='confluenceTd'> <b>Message</b> </td>
<td class='confluenceTd'> key value pair </td>
<td class='confluenceTd'> Class </td>
</tr>
</tbody></table>
</div>


<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Parameter name </th>
<th class='confluenceTh'> type </th>
<th class='confluenceTh'> Info </th>
</tr>
<tr>
<td class='confluenceTd'> pairSeparator </td>
<td class='confluenceTd'> string </td>
<td class='confluenceTd'> mandatory - can be '=' or ';' or 'anything' </td>
</tr>
<tr>
<td class='confluenceTd'> keyValuePairSeparair </td>
<td class='confluenceTd'> string </td>
<td class='confluenceTd'> mandatory - can be '\u0001', '\u0009', '#' or 'anything' </td>
</tr>
<tr>
<td class='confluenceTd'> crlf </td>
<td class='confluenceTd'> string </td>
<td class='confluenceTd'> optional - default value = WINDOWS - allow to define the carriage return character to use </td>
</tr>
<tr>
<td class='confluenceTd'> type </td>
<td class='confluenceTd'> string </td>
<td class='confluenceTd'> optional - define the type of message (e.g. FIX, EMX, ...) </td>
</tr>
<tr>
<td class='confluenceTd'> version </td>
<td class='confluenceTd'> string </td>
<td class='confluenceTd'> optional - version of the message (e.g. 4.1) </td>
</tr>
<tr>
<td class='confluenceTd'> isOrdered </td>
<td class='confluenceTd'> boolean </td>
<td class='confluenceTd'> optional - default value = false - allow to change the order of the fields when FIX message is generated </td>
</tr>
<tr>
<td class='confluenceTd'>&nbsp;</td>
<td class='confluenceTd'>&nbsp;</td>
<td class='confluenceTd'> This annotation is associated to the message class of the model and must be declared one time. </td>
</tr>
</tbody></table>
</div>


<p><b>case 1 : separator = 'u0001'</b></p>

<p>The separator used to segregate the key value pair fields in a FIX message is the ASCII '01' character or in unicode format '\u0001'. This character must be escaped a second time to avoid a java runtime error. Here is an example :</p>

<p>8=FIX.4.1 9=20 34=1 35=0 49=INVMGR 56=BRKR 1=BE.CHM.001 11=CHM0001-01 22=4 ...</p>

<p>and how to use the annotation</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>FIX - message</b></div><div class="codeContent panelContent">
<pre class="code-java">
@Message(keyValuePairSeparator = <span class="code-quote">"="</span>, pairSeparator = <span class="code-quote">"\u0001"</span>, type=<span class="code-quote">"FIX"</span>, version=<span class="code-quote">"4.1"</span>)
<span class="code-keyword">public</span> class Order {
...
}
</pre>
</div></div>

<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>Look at test cases</b><br />The ASCII character like tab, ... cannot be displayed in WIKI page. So, have a look to the test case of camel-bindy to see exactly how the FIX message looks like (src\test\data\fix\fix.txt) and the Order, Trailer, Header classes (src\test\java\org\apache\camel\dataformat\bindy\model\fix\simple\Order.java)</td></tr></table></div>

<h3><a name="Bindy-6.KeyValuePairField"></a>6. KeyValuePairField</h3>

<p>The KeyValuePairField annotation defines the property of a key value pair field. Each KeyValuePairField is identified by a tag (= key) and its value associated, a type (string, int, date, ...), optionaly a pattern and if the field is required</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Annotation name </th>
<th class='confluenceTh'> Record type </th>
<th class='confluenceTh'> Level </th>
</tr>
<tr>
<td class='confluenceTd'> <b>KeyValuePairField</b> </td>
<td class='confluenceTd'> Key Value Pair - FIX </td>
<td class='confluenceTd'> Property </td>
</tr>
</tbody></table>
</div>


<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Parameter name </th>
<th class='confluenceTh'> type </th>
<th class='confluenceTh'> Info </th>
</tr>
<tr>
<td class='confluenceTd'> tag </td>
<td class='confluenceTd'> int </td>
<td class='confluenceTd'> mandatory - digit number identifying the field in the message - must be unique </td>
</tr>
<tr>
<td class='confluenceTd'> pattern </td>
<td class='confluenceTd'> string </td>
<td class='confluenceTd'> optional - default value = "" - will be used to format Decimal, Date, ... </td>
</tr>
<tr>
<td class='confluenceTd'> precision </td>
<td class='confluenceTd'> int </td>
<td class='confluenceTd'> optional - digit number - represents the precision to be used when the Decimal number will be formatted/parsed </td>
</tr>
<tr>
<td class='confluenceTd'> position </td>
<td class='confluenceTd'> int </td>
<td class='confluenceTd'> optional - must be used when the position of the key/tag in the FIX message must be different </td>
</tr>
<tr>
<td class='confluenceTd'> required </td>
<td class='confluenceTd'> boolean </td>
<td class='confluenceTd'> optional - default value = "false" </td>
</tr>
</tbody></table>
</div>


<p><b>case 1 : tag</b></p>

<p>This parameter represents the key of the field in the message</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>FIX message - Tag</b></div><div class="codeContent panelContent">
<pre class="code-java">
@Message(keyValuePairSeparator = <span class="code-quote">"="</span>, pairSeparator = <span class="code-quote">"\u0001"</span>, type=<span class="code-quote">"FIX"</span>, version=<span class="code-quote">"4.1"</span>)
<span class="code-keyword">public</span> class Order {

    @Link Header header;

    @Link Trailer trailer;

    @KeyValuePairField(tag = 1) <span class="code-comment">// Client reference
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> Account;

    @KeyValuePairField(tag = 11) <span class="code-comment">// Order reference
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> ClOrdId;

    @KeyValuePairField(tag = 22) <span class="code-comment">// Fund ID type (Sedol, ISIN, ...)
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> IDSource;

    @KeyValuePairField(tag = 48) <span class="code-comment">// Fund code
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> SecurityId;

    @KeyValuePairField(tag = 54) <span class="code-comment">// Movement type ( 1 = Buy, 2 = sell)
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> Side;

    @KeyValuePairField(tag = 58) <span class="code-comment">// Free text
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> Text;

...
}
</pre>
</div></div>

<p><b>case 2 : Different position in output</b></p>

<p>If the tags/keys that we will put in the FIX message must be sorted according to a predefine order, then use the attribute 'position' of the annotation @KeyValuePairField</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>FIX message - Tag - sort</b></div><div class="codeContent panelContent">
<pre class="code-java">
@Message(keyValuePairSeparator = <span class="code-quote">"="</span>, pairSeparator = <span class="code-quote">"\\u0001"</span>, type = <span class="code-quote">"FIX"</span>, version = <span class="code-quote">"4.1"</span>, isOrdered = <span class="code-keyword">true</span>)
<span class="code-keyword">public</span> class Order {

    @Link Header header;

    @Link Trailer trailer;

    @KeyValuePairField(tag = 1, position = 1) <span class="code-comment">// Client reference
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> account;

    @KeyValuePairField(tag = 11, position = 3) <span class="code-comment">// Order reference
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> clOrdId;

...
}
</pre>
</div></div>

<h3><a name="Bindy-7.Section"></a>7. Section</h3>

<p>In FIX message of fixed length records, it is common to have different sections in the representation of the information : header, body and section. The purpose of the annotation @Section is to inform bindy about which class of the model represents the header (= section 1), body (= section 2) and footer (= section 3)</p>

<p>Only one attribute/parameter exists for this annotation.</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Annotation name </th>
<th class='confluenceTh'> Record type </th>
<th class='confluenceTh'> Level </th>
</tr>
<tr>
<td class='confluenceTd'> <b>Section</b> </td>
<td class='confluenceTd'> FIX </td>
<td class='confluenceTd'> Class </td>
</tr>
</tbody></table>
</div>


<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Parameter name </th>
<th class='confluenceTh'> type </th>
<th class='confluenceTh'> Info </th>
</tr>
<tr>
<td class='confluenceTd'> number </td>
<td class='confluenceTd'> int </td>
<td class='confluenceTd'> digit number identifying the section position </td>
</tr>
</tbody></table>
</div>


<p><b>case 1 : Section</b></p>

<p>A. Definition of the header section</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>FIX message - Section - Header</b></div><div class="codeContent panelContent">
<pre class="code-java">
@Section(number = 1)
<span class="code-keyword">public</span> class Header {

    @KeyValuePairField(tag = 8, position = 1) <span class="code-comment">// Message Header
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> beginString;

    @KeyValuePairField(tag = 9, position = 2) <span class="code-comment">// Checksum
</span>    <span class="code-keyword">private</span> <span class="code-object">int</span> bodyLength;
...
}
</pre>
</div></div>

<p>B. Definition of the body section</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>FIX message - Section - Body</b></div><div class="codeContent panelContent">
<pre class="code-java">
@Section(number = 2)
@Message(keyValuePairSeparator = <span class="code-quote">"="</span>, pairSeparator = <span class="code-quote">"\\u0001"</span>, type = <span class="code-quote">"FIX"</span>, version = <span class="code-quote">"4.1"</span>, isOrdered = <span class="code-keyword">true</span>)
<span class="code-keyword">public</span> class Order {

    @Link Header header;

    @Link Trailer trailer;

    @KeyValuePairField(tag = 1, position = 1) <span class="code-comment">// Client reference
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> account;

    @KeyValuePairField(tag = 11, position = 3) <span class="code-comment">// Order reference
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> clOrdId;
</pre>
</div></div>


<p>C. Definition of the footer section</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>FIX message - Section - Footer</b></div><div class="codeContent panelContent">
<pre class="code-java">
@Section(number = 3)
<span class="code-keyword">public</span> class Trailer {

    @KeyValuePairField(tag = 10, position = 1)
    <span class="code-comment">// CheckSum
</span>    <span class="code-keyword">private</span> <span class="code-object">int</span> checkSum;

    <span class="code-keyword">public</span> <span class="code-object">int</span> getCheckSum() {
        <span class="code-keyword">return</span> checkSum;
    }
</pre>
</div></div>

<h3><a name="Bindy-8.OneToMany"></a>8. OneToMany</h3>

<p>The purpose of the annotation @OneToMany is to allow to work with a List&lt;?&gt; field defined a POJO class or from a record containing repetitive groups.</p>

<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>Restrictions OneToMany</b><br />Be careful, the one to many of bindy does not allow to handle repetitions defined on several levels of the hierarchy</td></tr></table></div>

<p>The relation OneToMany ONLY WORKS in the following cases :</p>

<ul class="alternate" type="square">
	<li>Reading a FIX message containing repetitive groups (= group of tags/keys)</li>
	<li>Generating a CSV with repetitive data</li>
</ul>


<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Annotation name </th>
<th class='confluenceTh'> Record type </th>
<th class='confluenceTh'> Level </th>
</tr>
<tr>
<td class='confluenceTd'> <b>OneToMany</b> </td>
<td class='confluenceTd'> all </td>
<td class='confluenceTd'> property </td>
</tr>
</tbody></table>
</div>


<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Parameter name </th>
<th class='confluenceTh'> type </th>
<th class='confluenceTh'> Info </th>
</tr>
<tr>
<td class='confluenceTd'> mappedTo </td>
<td class='confluenceTd'> string </td>
<td class='confluenceTd'> optional - string - class name associated to the type of the List&lt;Type of the Class&gt; </td>
</tr>
</tbody></table>
</div>


<p><b>case 1 : Generating CSV with repetitive data</b></p>

<p>Here is the CSV output that we want :</p>

<p>Claus,Ibsen,Camel in Action 1,2010,35<br/>
Claus,Ibsen,Camel in Action 2,2012,35<br/>
Claus,Ibsen,Camel in Action 3,2013,35<br/>
Claus,Ibsen,Camel in Action 4,2014,35</p>

<p>Remark : the repetitive data concern the title of the book and its publication date while first, last name and age are common</p>

<p>and the classes used to modeling this. The Author class contains a List of Book.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Generate CSV with repetitive data</b></div><div class="codeContent panelContent">
<pre class="code-java">
@CsvRecord(separator=<span class="code-quote">","</span>)
<span class="code-keyword">public</span> class Author {

	@DataField(pos = 1)
	<span class="code-keyword">private</span> <span class="code-object">String</span> firstName;

	@DataField(pos = 2)
	<span class="code-keyword">private</span> <span class="code-object">String</span> lastName;

	@OneToMany
	<span class="code-keyword">private</span> List&lt;Book&gt; books;

	@DataField(pos = 5)
	<span class="code-keyword">private</span> <span class="code-object">String</span> Age;
...


<span class="code-keyword">public</span> class Book {

	@DataField(pos = 3)
	<span class="code-keyword">private</span> <span class="code-object">String</span> title;

	@DataField(pos = 4)
	<span class="code-keyword">private</span> <span class="code-object">String</span> year;
</pre>
</div></div>

<p>Very simple isn't it &#33;&#33;&#33;</p>

<p><b>case 2 : Reading FIX message containing group of tags/keys</b></p>

<p>Here is the message that we would like to process in our model :</p>

<p>"8=FIX 4.19=2034=135=049=INVMGR56=BRKR"<br/>
"1=BE.CHM.00111=CHM0001-0158=this is a camel - bindy test"<br/>
"22=448=BE000124567854=1"<br/>
"22=548=BE000987654354=2"<br/>
"22=648=BE000999999954=3"<br/>
"10=220"</p>

<p>tags 22, 48 and 54 are repeated</p>

<p>and the code</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Reading FIX message containing group of tags/keys</b></div><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Order {

    @Link Header header;

    @Link Trailer trailer;

    @KeyValuePairField(tag = 1) <span class="code-comment">// Client reference
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> account;

    @KeyValuePairField(tag = 11) <span class="code-comment">// Order reference
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> clOrdId;

    @KeyValuePairField(tag = 58) <span class="code-comment">// Free text
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> text;

    @OneToMany(mappedTo = <span class="code-quote">"org.apache.camel.dataformat.bindy.model.fix.complex.onetomany.Security"</span>)
    List&lt;Security&gt; securities;
...

<span class="code-keyword">public</span> class Security {

    @KeyValuePairField(tag = 22) <span class="code-comment">// Fund ID type (Sedol, ISIN, ...)
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> idSource;

    @KeyValuePairField(tag = 48) <span class="code-comment">// Fund code
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> securityCode;

    @KeyValuePairField(tag = 54) <span class="code-comment">// Movement type ( 1 = Buy, 2 = sell)
</span>    <span class="code-keyword">private</span> <span class="code-object">String</span> side;

</pre>
</div></div>

<h3><a name="Bindy-UsingtheJavaDSL"></a>Using the Java DSL</h3>

<p>The next step consists in instantiating the DataFormat <em>bindy</em> class associated with this record type and providing Java package name(s) as parameter.</p>

<p>For example the following uses the class CsvBindyFormat (who correspond to the class associated with the CSV record type) which is configured with "com.acme.model"<br/>
package name to initialize the model objects configured in this package.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
DataFormat bindy = <span class="code-keyword">new</span> CsvBindyDataFormat(<span class="code-quote">"com.acme.model"</span>);

from(<span class="code-quote">"file:<span class="code-comment">//inbox"</span>).
</span>  unmarshal(bindy).
  to(<span class="code-quote">"bean:handleOrder"</span>);
</pre>
</div></div>
<p>The Camel route will pick-up files in the inbox directory, unmarshall CSV records in a collection of model objects and send the collection<br/>
to the bean referenced by 'handleOrder'.</p>

<p>The collection is a list of Map. Each Map of the list contains the objects of the model. Each object can be retrieve using its class name.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-object">int</span> count = 0;

    List&lt;Map&lt;<span class="code-object">String</span>, <span class="code-object">Object</span>&gt;&gt; models = <span class="code-keyword">new</span> ArrayList&lt;Map&lt;<span class="code-object">String</span>, <span class="code-object">Object</span>&gt;&gt;();
    Map&lt;<span class="code-object">String</span>, <span class="code-object">Object</span>&gt; model = <span class="code-keyword">new</span> HashMap&lt;<span class="code-object">String</span>, <span class="code-object">Object</span>&gt;();

    models = (List&lt;Map&lt;<span class="code-object">String</span>, <span class="code-object">Object</span>&gt;&gt;) exchange.getIn().getBody();

    Iterator&lt;Map&lt;<span class="code-object">String</span>, <span class="code-object">Object</span>&gt;&gt; it = models.iterator();

    <span class="code-keyword">while</span>(it.hasNext()){

          model = it.next();

	  <span class="code-keyword">for</span>(<span class="code-object">String</span> key : model.keySet()) {
	     <span class="code-object">Object</span> obj = model.get(key);
	     LOG.info(<span class="code-quote">"Count : "</span> + count + <span class="code-quote">", "</span> + obj.toString());
	  }

	 count++;
    }

    LOG.info(<span class="code-quote">"Nber of CSV records received by the csv bean : "</span> + count);
</pre>
</div></div>
<p>To generate CSV records from a collection of model objects, you create the following route :</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
from(<span class="code-quote">"bean:handleOrder"</span>)
   marshal(bindy)
   to(<span class="code-quote">"file:<span class="code-comment">//outbox"</span>)</span>
</pre>
</div></div>
<p>You can if you prefer use a named reference to a data format which can then be defined in your <a href="/confluence/display/CAMEL/Registry" title="Registry">Registry</a> such as via your <a href="/confluence/display/CAMEL/Spring" title="Spring">Spring</a> XML file. e.g.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
from(<span class="code-quote">"file:<span class="code-comment">//inbox"</span>).
</span>  unmarshal(<span class="code-quote">"myBindyDataFormat"</span>).
  to(<span class="code-quote">"bean:handleOrder"</span>);
</pre>
</div></div>

<h3><a name="Bindy-Unittest"></a>Unit test</h3>

<p>Here is two examples showing how to marshall or unmarshall a CSV file with Camel</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Marshall</b></div><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> org.apache.camel.dataformat.bindy.csv;

<span class="code-keyword">import</span> java.math.BigDecimal;
<span class="code-keyword">import</span> java.util.ArrayList;
<span class="code-keyword">import</span> java.util.Calendar;
<span class="code-keyword">import</span> java.util.GregorianCalendar;
<span class="code-keyword">import</span> java.util.HashMap;
<span class="code-keyword">import</span> java.util.List;
<span class="code-keyword">import</span> java.util.Map;

<span class="code-keyword">import</span> org.apache.camel.EndpointInject;
<span class="code-keyword">import</span> org.apache.camel.Produce;
<span class="code-keyword">import</span> org.apache.camel.ProducerTemplate;
<span class="code-keyword">import</span> org.apache.camel.builder.RouteBuilder;
<span class="code-keyword">import</span> org.apache.camel.component.mock.MockEndpoint;
<span class="code-keyword">import</span> org.apache.camel.dataformat.bindy.model.complex.twoclassesandonelink.Client;
<span class="code-keyword">import</span> org.apache.camel.dataformat.bindy.model.complex.twoclassesandonelink.Order;
<span class="code-keyword">import</span> org.apache.camel.spring.javaconfig.SingleRouteCamelConfiguration;
<span class="code-keyword">import</span> org.junit.Test;
<span class="code-keyword">import</span> org.springframework.config.java.annotation.Bean;
<span class="code-keyword">import</span> org.springframework.config.java.annotation.Configuration;
<span class="code-keyword">import</span> org.springframework.config.java.test.JavaConfigContextLoader;
<span class="code-keyword">import</span> org.springframework.test.context.ContextConfiguration;
<span class="code-keyword">import</span> org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;

@ContextConfiguration(locations = <span class="code-quote">"org.apache.camel.dataformat.bindy.csv.BindyComplexCsvMarshallTest$ContextConfig"</span>, loader = JavaConfigContextLoader.class)
<span class="code-keyword">public</span> class BindyComplexCsvMarshallTest <span class="code-keyword">extends</span> AbstractJUnit4SpringContextTests {

    <span class="code-keyword">private</span> List&lt;Map&lt;<span class="code-object">String</span>, <span class="code-object">Object</span>&gt;&gt; models = <span class="code-keyword">new</span> ArrayList&lt;Map&lt;<span class="code-object">String</span>, <span class="code-object">Object</span>&gt;&gt;();
    <span class="code-keyword">private</span> <span class="code-object">String</span> result = <span class="code-quote">"10,A1,Julia,Roberts,BE123456789,Belgium Ventage 10/12,150,USD,14-01-2009"</span>;

    @Produce(uri = <span class="code-quote">"direct:start"</span>)
    <span class="code-keyword">private</span> ProducerTemplate template;

    @EndpointInject(uri = <span class="code-quote">"mock:result"</span>)
    <span class="code-keyword">private</span> MockEndpoint resultEndpoint;

    @Test
    <span class="code-keyword">public</span> void testMarshallMessage() <span class="code-keyword">throws</span> Exception {
        resultEndpoint.expectedBodiesReceived(result);

        template.sendBody(generateModel());

        resultEndpoint.assertIsSatisfied();
    }

    <span class="code-keyword">private</span> List&lt;Map&lt;<span class="code-object">String</span>, <span class="code-object">Object</span>&gt;&gt; generateModel() {
        Map&lt;<span class="code-object">String</span>, <span class="code-object">Object</span>&gt; model = <span class="code-keyword">new</span> HashMap&lt;<span class="code-object">String</span>, <span class="code-object">Object</span>&gt;();

        Order order = <span class="code-keyword">new</span> Order();
        order.setOrderNr(10);
        order.setAmount(<span class="code-keyword">new</span> BigDecimal(<span class="code-quote">"150"</span>));
        order.setIsinCode(<span class="code-quote">"BE123456789"</span>);
        order.setInstrumentName(<span class="code-quote">"Belgium Ventage 10/12"</span>);
        order.setCurrency(<span class="code-quote">"USD"</span>);

        Calendar calendar = <span class="code-keyword">new</span> GregorianCalendar();
        calendar.set(2009, 0, 14);
        order.setOrderDate(calendar.getTime());

        Client client = <span class="code-keyword">new</span> Client();
        client.setClientNr(<span class="code-quote">"A1"</span>);
        client.setFirstName(<span class="code-quote">"Julia"</span>);
        client.setLastName(<span class="code-quote">"Roberts"</span>);

        order.setClient(client);

        model.put(order.getClass().getName(), order);
        model.put(client.getClass().getName(), client);

        models.add(0, model);

        <span class="code-keyword">return</span> models;
    }

    @Configuration
    <span class="code-keyword">public</span> <span class="code-keyword">static</span> class ContextConfig <span class="code-keyword">extends</span> SingleRouteCamelConfiguration {
        BindyCsvDataFormat camelDataFormat = <span class="code-keyword">new</span> BindyCsvDataFormat(<span class="code-quote">"org.apache.camel.dataformat.bindy.model.complex.twoclassesandonelink"</span>);

        @Override
        @Bean
        <span class="code-keyword">public</span> RouteBuilder route() {
            <span class="code-keyword">return</span> <span class="code-keyword">new</span> RouteBuilder() {
                @Override
                <span class="code-keyword">public</span> void configure() {
                    from(<span class="code-quote">"direct:start"</span>).marshal(camelDataFormat).to(<span class="code-quote">"mock:result"</span>);
                }
            };
        }
    }

}
</pre>
</div></div>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Unmarshall</b></div><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> org.apache.camel.dataformat.bindy.csv;

<span class="code-keyword">import</span> org.apache.camel.EndpointInject;
<span class="code-keyword">import</span> org.apache.camel.builder.RouteBuilder;
<span class="code-keyword">import</span> org.apache.camel.component.mock.MockEndpoint;
<span class="code-keyword">import</span> org.apache.camel.spring.javaconfig.SingleRouteCamelConfiguration;
<span class="code-keyword">import</span> org.junit.Test;
<span class="code-keyword">import</span> org.springframework.config.java.annotation.Bean;
<span class="code-keyword">import</span> org.springframework.config.java.annotation.Configuration;
<span class="code-keyword">import</span> org.springframework.config.java.test.JavaConfigContextLoader;
<span class="code-keyword">import</span> org.springframework.test.context.ContextConfiguration;
<span class="code-keyword">import</span> org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;

@ContextConfiguration(locations = <span class="code-quote">"org.apache.camel.dataformat.bindy.csv.BindyComplexCsvUnmarshallTest$ContextConfig"</span>, loader = JavaConfigContextLoader.class)
<span class="code-keyword">public</span> class BindyComplexCsvUnmarshallTest <span class="code-keyword">extends</span> AbstractJUnit4SpringContextTests {

    @EndpointInject(uri = <span class="code-quote">"mock:result"</span>)
    <span class="code-keyword">private</span> MockEndpoint resultEndpoint;

    @Test
    <span class="code-keyword">public</span> void testUnMarshallMessage() <span class="code-keyword">throws</span> Exception {
        resultEndpoint.expectedMessageCount(1);
        resultEndpoint.assertIsSatisfied();
    }

    @Configuration
    <span class="code-keyword">public</span> <span class="code-keyword">static</span> class ContextConfig <span class="code-keyword">extends</span> SingleRouteCamelConfiguration {
        BindyCsvDataFormat csvBindyDataFormat = <span class="code-keyword">new</span> BindyCsvDataFormat(<span class="code-quote">"org.apache.camel.dataformat.bindy.model.complex.twoclassesandonelink"</span>);

        @Override
        @Bean
        <span class="code-keyword">public</span> RouteBuilder route() {
            <span class="code-keyword">return</span> <span class="code-keyword">new</span> RouteBuilder() {
                @Override
                <span class="code-keyword">public</span> void configure() {
                    from(<span class="code-quote">"file:<span class="code-comment">//src/test/data?noop=<span class="code-keyword">true</span>"</span>).unmarshal(csvBindyDataFormat).to(<span class="code-quote">"mock:result"</span>);
</span>                }
            };
        }
    }

}
</pre>
</div></div>

<p>In this example, BindyCsvDataFormat class has been instantiated in a traditional way but it is also possible to provide information directly to the function (un)marshal like this where BindyType corresponds to the Bindy DataFormat class to instantiate and the parameter contains the list of package names.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
    <span class="code-keyword">public</span> <span class="code-keyword">static</span> class ContextConfig <span class="code-keyword">extends</span> SingleRouteCamelConfiguration {
        @Override
        @Bean
        <span class="code-keyword">public</span> RouteBuilder route() {
            <span class="code-keyword">return</span> <span class="code-keyword">new</span> RouteBuilder() {
                @Override
                <span class="code-keyword">public</span> void configure() {
                    from(<span class="code-quote">"direct:start"</span>)
                    .marshal().bindy(BindyType.Csv, <span class="code-quote">"org.apache.camel.dataformat.bindy.model.simple.oneclass"</span>)
                    .to(<span class="code-quote">"mock:result"</span>);
                }
            };
        }
    }
</pre>
</div></div>

<h3><a name="Bindy-UsingSpringXML"></a>Using Spring XML</h3>

<p>This is really easy to use Spring as your favorite DSL language to declare the routes to be used for camel-bindy. The following example shows two routes where the first will pick-up records from files, unmarshal the content and bind it to their model. The result is then send to a pojo (doing nothing special) and place them into a queue.</p>

<p>The second route will extract the pojos from the queue and marshal the content to generate a file containing the csv record</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>spring dsl</b></div><div class="codeContent panelContent">
<pre class="code-java">
&lt;?xml version=<span class="code-quote">"1.0"</span> encoding=<span class="code-quote">"UTF-8"</span>?&gt;

&lt;beans xmlns=<span class="code-quote">"http:<span class="code-comment">//www.springframework.org/schema/beans"</span>
</span>	xmlns:xsi=<span class="code-quote">"http:<span class="code-comment">//www.w3.org/2001/XMLSchema-instance"</span>
</span>	xsi:schemaLocation="
       http:<span class="code-comment">//www.springframework.org/schema/beans
</span>       http:<span class="code-comment">//www.springframework.org/schema/beans/spring-beans.xsd
</span>       http:<span class="code-comment">//camel.apache.org/schema/spring
</span>       http:<span class="code-comment">//camel.apache.org/schema/spring/camel-spring.xsd"&gt;
</span>
	&lt;bean id=<span class="code-quote">"bindyDataformat"</span> class=<span class="code-quote">"org.apache.camel.dataformat.bindy.csv.BindyCsvDataFormat"</span>&gt;
		&lt;constructor-arg value=<span class="code-quote">"org.apache.camel.bindy.model"</span> /&gt;
	&lt;/bean&gt;

	&lt;bean id=<span class="code-quote">"csv"</span> class=<span class="code-quote">"org.apache.camel.bindy.csv.HandleOrderBean"</span> /&gt;


        &lt;!-- Queuing engine - ActiveMq - work locally in mode virtual memory --&gt;
	&lt;bean id=<span class="code-quote">"activemq"</span> class=<span class="code-quote">"org.apache.activemq.camel.component.ActiveMQComponent"</span>&gt;
		&lt;property name=<span class="code-quote">"brokerURL"</span> value=<span class="code-quote">"vm:<span class="code-comment">//localhost:61616"</span>/&gt;
</span>	&lt;/bean&gt;


	&lt;camelContext xmlns=<span class="code-quote">"http:<span class="code-comment">//camel.apache.org/schema/spring"</span>&gt;
</span>		&lt;jmxAgent id=<span class="code-quote">"agent"</span> disabled=<span class="code-quote">"<span class="code-keyword">false</span>"</span> /&gt;

		&lt;route&gt;
			&lt;from uri=<span class="code-quote">"file:<span class="code-comment">//src/data/csv/?noop=<span class="code-keyword">true</span>"</span> /&gt;
</span>			&lt;unmarshal ref=<span class="code-quote">"bindyDataformat"</span> /&gt;
			&lt;to uri=<span class="code-quote">"bean:csv"</span> /&gt;
			&lt;to uri=<span class="code-quote">"activemq:queue:in"</span> /&gt;
		&lt;/route&gt;

		&lt;route&gt;
			&lt;from uri=<span class="code-quote">"activemq:queue:in"</span> /&gt;
			&lt;marshal ref=<span class="code-quote">"bindyDataformat"</span> /&gt;
			&lt;to uri=<span class="code-quote">"file:<span class="code-comment">//src/data/csv/out/"</span> /&gt;
</span>		&lt;/route&gt;
	&lt;/camelContext&gt;
&lt;/beans&gt;
</pre>
</div></div>

<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>Be careful</b><br />Please verify that your model classes implements serializable otherwise the queue manager will raise an error</td></tr></table></div>

<h3><a name="Bindy-Dependencies"></a>Dependencies</h3>

<p>To use Bindy in your camel routes you need to add the a dependency on <b>camel-bindy</b> which implements this data format.</p>

<p>If you use maven you could just add the following to your pom.xml, substituting the version number for the latest &amp; greatest release (see <a href="/confluence/display/CAMEL/Download" title="Download">the download page for the latest versions</a>).</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
&lt;dependency&gt;
  &lt;groupId&gt;org.apache.camel&lt;/groupId&gt;
  &lt;artifactId&gt;camel-bindy&lt;/artifactId&gt;
  &lt;version&gt;2.1.0&lt;/version&gt;
&lt;/dependency&gt;
</pre>
</div></div>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action" class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Bindy">View Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=108680&revisedVersion=172&originalVersion=171">View Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Bindy?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message