You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 79 Next »

Bindy

Available as of Camel 2.0

The idea that the developers have followed to design this component was to allow the binding of non structured data (or to be more precise non-XML data)
to Java Bean using annotations. Using Bindy, you can bind data like :

  • CSV record,
  • Fixedlength record,
  • or any other non-structured data

to one or many POJOS and to convert the data according to the type of the java property. POJOS can be linked together. 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.

For the BigDecimal number, you can also define the precision and the decimal or grouping separators

Type

Format Type

Pattern example

Link

Date

DateFormat

"dd-MM-yyyy"

http://java.sun.com/j2se/1.5.0/docs/api/java/text/SimpleDateFormat.html

Decimal*

Decimalformat

"##.###.###"

http://java.sun.com/j2se/1.5.0/docs/api/java/text/DecimalFormat.html

Decimal* = Double, Integer, Float, Short, Long

Be careful

This first release only support CSV record.

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.

Unknown macro: {table}
Unknown macro: {tr}
Unknown macro: {th}

Annotation name

Unknown macro: {th}

Level

Unknown macro: {th}

Parameter

Unknown macro: {tr}
Unknown macro: {th}
Unknown macro: {th}
Unknown macro: {th}

Name

Unknown macro: {th}

Type

Unknown macro: {th}

Info

Unknown macro: {tr}
Unknown macro: {td}

CsvRecord

Unknown macro: {td}

Class

Unknown macro: {td}

separator

Unknown macro: {td}

string

Unknown macro: {td}

mandatory - can be ',' or ';' or 'anything'

Unknown macro: {tr}
Unknown macro: {td}
Unknown macro: {td}
Unknown macro: {td}

skipFirstLine

Unknown macro: {td}

boolean

Unknown macro: {td}

optional - default value = false - allow to skip the first line of the CSV file

Unknown macro: {tr}
Unknown macro: {td}

This annotation is associated to the root class of the model and must be declared one time.

Unknown macro: {tr}
Unknown macro: {td}

case 1 : separator = ','

Unknown macro: {tr}
Unknown macro: {td}

e.g : If the record represents orders, then this annotation is added to the Order class like this :

Unknown macro: {tr}
Unknown macro: {td}
Unknown macro: {tr}
Unknown macro: {td}

@CsvRecord( separator = "," )

Unknown macro: {tr}
Unknown macro: {td}

public Class Order

Unknown macro: {tr}
Unknown macro: {td}
Unknown macro: {tr}
Unknown macro: {td}

case 2 : separator = ';'

Unknown macro: {tr}
Unknown macro: {td}
Unknown macro: {tr}
Unknown macro: {td}

@CsvRecord( separator = ";" )

Unknown macro: {tr}
Unknown macro: {td}

public Class Order

Unknown macro: {tr}
Unknown macro: {td}
Unknown macro: {tr}
Unknown macro: {td}

case 3 : separator & skipfirstline

Unknown macro: {tr}
Unknown macro: {td}
Unknown macro: {tr}
Unknown macro: {td}

@CsvRecord(separator = ",", skipFirstLine = true)

Unknown macro: {tr}
Unknown macro: {td}

public Class Order

Unknown macro: {tr}
Unknown macro: {td}

 

Unknown macro: {tr}
Unknown macro: {td}

Link

Unknown macro: {td}

Class, Property

Unknown macro: {td}

linkType

Unknown macro: {td}

LinkType

Unknown macro: {td}

optional - by default the value is LinkType.oneToOne

Unknown macro: {tr}
Unknown macro: {td}

Only one-to-one relation is allowed.

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

@Link
private Client client

Unknown macro: {tr}
Unknown macro: {td}

 

Unknown macro: {tr}
Unknown macro: {td}

DataField

Unknown macro: {td}

Property

Unknown macro: {td}

int

Unknown macro: {td}

pos

Unknown macro: {td}

mandatory - digit number

Unknown macro: {tr}
Unknown macro: {td}
Unknown macro: {td}
Unknown macro: {td}

pattern

Unknown macro: {td}

string

Unknown macro: {td}

optional - default value = "" - will be used to format Decimal, Date, ...

Unknown macro: {tr}
Unknown macro: {td}
Unknown macro: {td}
Unknown macro: {td}

length

Unknown macro: {td}

int

Unknown macro: {td}

optional - digit number - represents the length of the field for fixed length format

Unknown macro: {tr}
Unknown macro: {td}
Unknown macro: {td}
Unknown macro: {td}

precision

Unknown macro: {td}

int

Unknown macro: {td}

optional - digit number - represents the precision to be used when the Decimal number will be formatted/parsed

Unknown macro: {tr}
Unknown macro: {td}

case 1 : position

@DataField(pos = 0)
private int orderNr;

@DataField(pos = 1)
private String ref;

case 2 : pattern

@DataField(pos = 8, pattern = "dd-MM-yyyy")
private Date orderDate;

case 3 : precision

@DataField(pos = 6, precision = 2)
private BigDecimal amount;

Unknown macro: {tr}
Unknown macro: {td}

 

Using the Java DSL

The next step consists in instantiaing the DataFormat bindy class associated with this record type and providing Java package name(s) as parameter.

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"
package name to initialize the model objects configured in this package.

DataFormat bindy = new CsvBindyDataFormat("com.acme.model");

from("file://inbox").
  unmarshal(bindy).
  to("bean:handleOrder");

The Camel route will pick-up files in the inbox directory, unmarshall CSV records in a collection of model objects and send the collection
to the bean referenced by 'handleOrder'.

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.

    int count = 0;
			
    List<Map<String, Object>> models = new ArrayList<Map<String, Object>>();
    Map<String, Object> model = new HashMap<String, Object>();
        	
    models = (List<Map<String, Object>>) exchange.getIn().getBody();
    
    Iterator<Map<String, Object>> it = models.iterator();
		
    while(it.hasNext()){
		
          model = it.next();
			  
	  for(String key : model.keySet()) {
	     Object obj = model.get(key); 
	     LOG.info("Count : " + count + ", " + obj.toString());
	  }
			  
	 count++;
    }
			
    LOG.info("Nber of CSV records received by the csv bean : " + count);

To generate CSV records from a collection of model objects, you create the following route :

from("")
marshal(bindy)
to("file://outbox")

You can if you prefer use a named reference to a data format which can then be defined in your Registry such as via your Spring XML file. e.g.

from("file://inbox").
  unmarshal("myBindyDataFormat").
  to("bean:handleOrder");

Using Spring XML

TODO:

Dependencies

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

If you use maven you could just add the following to your pom.xml, substituting the version number for the latest & greatest release (see the download page for the latest versions).

<dependency>
  <groupId>org.apache.camel</groupId>
  <artifactId>camel-bindy</artifactId>
  <version>2.0.0</version>
</dependency>
  • No labels