This is an automated email from the ASF dual-hosted git repository. tsato pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new ddecb46 CAMEL-16517 - Add annotation processing feature to camel-package:update-readme ddecb46 is described below commit ddecb46f06e6ba1a73667497ee8b6be0f0794189 Author: Tadayoshi Sato <sato.tadayo...@gmail.com> AuthorDate: Mon May 10 16:20:27 2021 +0900 CAMEL-16517 - Add annotation processing feature to camel-package:update-readme It is introduced to sync annotation options tables in bindy-dataformat.adoc with code automatically. --- .../camel/catalog/docs/bindy-dataformat.adoc | 330 +++++++++++--------- .../src/main/docs/bindy-dataformat.adoc | 330 +++++++++++--------- .../dataformat/bindy/annotation/CsvRecord.java | 17 +- .../dataformat/bindy/annotation/DataField.java | 13 +- .../bindy/annotation/FixedLengthRecord.java | 17 +- .../bindy/annotation/KeyValuePairField.java | 9 +- .../camel/dataformat/bindy/annotation/Link.java | 2 +- .../camel/dataformat/bindy/annotation/Message.java | 13 +- .../dataformat/bindy/annotation/OneToMany.java | 3 + .../dataformats/pages/bindy-dataformat.adoc | 332 ++++++++++++--------- .../camel/tooling/model/AnnotationModel.java | 103 +++++++ .../camel/maven/packaging/UpdateReadmeMojo.java | 160 +++++++++- .../src/main/resources/annotation-options.mvel | 9 + 13 files changed, 871 insertions(+), 467 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/bindy-dataformat.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/bindy-dataformat.adoc index 3a41560..dc98be7 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/bindy-dataformat.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/bindy-dataformat.adoc @@ -106,46 +106,52 @@ to several children model classes. |CsvRecord |csv |Class |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.CsvRecord +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info -|separator |string |mandatory - can be ',' or ';' or 'anything'. The only whitespace character supported is tab (\t). No other whitespace characters (spaces) are not supported. 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 '\|' sign, than you have to mask -it, like '\|' +| separator | String | ✓ | a| Separator used to split a record in tokens (mandatory) - can be ',' or ';' or 'anything'. The only whitespace +character supported is tab (\t). No other whitespace characters (spaces) are not supported. 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 '\|' sign, than you have to mask it, like '\|' -|skipFirstLine |boolean |optional - default value = false - allow to skip the first line of the -CSV file +| allowEmptyStream | boolean | | false | The allowEmptyStream parameter will allow to prcoess the unavaiable stream for CSV file. -|crlf |string |optional - possible values = WINDOWS,UNIX,MAC, or custom; default value. -WINDOWS - allow to define the carriage return character to use. If you -specify a value other than the three listed before, the value you enter -(custom) will be used as the CRLF character(s) +| autospanLine | boolean | | false a| Last record spans rest of line (optional) - if enabled then the last column is auto spanned to end of line, for +example if its a comment, etc this allows the line to contain all characters, also the delimiter char. -|generateHeaderColumns |boolean |optional - default value = false - uses to generate the header columns -of the CSV generates +| crlf | String | | WINDOWS a| Character to be used to add a carriage return after each record (optional) - allow to define the carriage return +character to use. If you specify a value other than the three listed before, the value you enter (custom) will be +used as the CRLF character(s). Three values can be used : WINDOWS, UNIX, MAC, or custom. -|autospanLine |boolean |optional - default value = false - if enabled then -the last column is auto spanned to end of line, for example if its a -comment, etc this allows the line to contain all characters, also the -delimiter char. +| endWithLineBreak | boolean | | true | The endWithLineBreak parameter flags if the CSV file should end with a line break or not (optional) -|isOrdered |boolean |optional - default value = false - allow to change the order of the -fields when CSV is generated +| generateHeaderColumns | boolean | | false | The generateHeaderColumns parameter allow to add in the CSV generated the header containing names of the columns -|quote |String |optional - allow to specify a quote character of the -fields when CSV is generated. This annotation is associated to the root class of the model and must be -declared one time. +| isOrdered | boolean | | false | Indicates if the message must be ordered in output -|quoting |boolean |optional - default value = false - Indicate if the values (and headers) -must be quoted when marshaling when CSV is generated. +| name | String | | | Name describing the record (optional) -|endWithLineBreak |boolean |optional - default value = true - Indicate if the CSV generated file -should end with a line break. +| quote | String | | " a| Whether to marshal columns with the given quote character (optional) - allow to specify a quote character of the +fields when CSV is generated. This annotation is associated to the root class of the model and must be declared +one time. + +| quoting | boolean | | false | Indicate if the values (and headers) must be quoted when marshaling (optional) + +| quotingEscaped | boolean | | false | Indicate if the values must be escaped when quoting (optional) + +| removeQuotes | boolean | | true | The remove quotes parameter flags if unmarshalling should try to remove quotes for each field + +| skipField | boolean | | false a| The skipField parameter will allow to skip fields of a CSV file. If some fields are not necessary, they can be +skipped. + +| skipFirstLine | boolean | | false a| The skipFirstLine parameter will allow to skip or not the first line of a CSV file. This line often contains +columns definition -| |=== +// annotation options: END *case 1 : separator = ','* @@ -350,23 +356,25 @@ to generate the CSV The link annotation will allow to link objects together. -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*Link* |all |Class & Property +|Link |all |Class & Property |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.Link +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info -|linkType |LinkType |optional - by default the value is LinkType.oneToOne - so you are not -obliged to mention it +| linkType | LinkType | | OneToOne | Type of link identifying the relation between the classes |=== +// annotation options: END -Only one-to-one relation is allowed. +Only one-to-one relation is allowed as of the current version. e.g : If the model Class Client is linked to the Order class, then use annotation Link in the Order class like this : @@ -404,59 +412,72 @@ 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 -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*DataField* |all |Property +|DataField |all |Property |=== - -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.DataField +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| pos | int | ✓ | | Position of the data in the input record, must start from 1 (mandatory). See the position parameter. -|pos |int |mandatory - The *input* position of the field. digit number starting -from 1 to ... - See the position parameter. +| align | String | | R | Align the text to the right or left. Use values <tt>R</tt> or <tt>L</tt>. -|pattern |string |optional - default value = "" - will be used to format Decimal, Date, +| clip | boolean | | false | Indicates to clip data in the field if it exceeds the allowed length when using fixed length. -|length |int |optional - represents the length of the field (number of characters) for fixed length format +| columnName | String | | a| Name of the header column (optional). Uses the name of the property as default. Only applicable when `CsvRecord` +has `generateHeaderColumns = true` -|precision |int |optional - represents the precision to be used when the Decimal number -will be formatted/parsed +| decimalSeparator | String | | | Decimal Separator to be used with BigDecimal number -|pattern |string |optional - default value = "" - is used by the Java formatter -(SimpleDateFormat by example) to format/validate data. If using pattern, -then setting locale on bindy data format is recommended. Either set to a -known locale such as "us" or use "default" to use platform default -locale. +| defaultValue | String | | | Field's default value in case no value is set -|position |int |optional - must be used when the position of the field in the CSV -generated (output message) must be different compare to input position -(pos). See the pos parameter. +| delimiter | String | | | Optional delimiter to be used if the field has a variable length -|required |boolean |optional - default value = "false" +| groupingSeparator | String | | a| Grouping Separator to be used with BigDecimal number when we would like to format/parse to number with grouping +e.g. 123,456.789 -|trim |boolean |optional - default value = "false" +| impliedDecimalSeparator | boolean | | false | Indicates if there is a decimal point implied at a specified location -|defaultValue |string |optional - default value = "" - defines the field's -default value when the respective CSV field is empty/not available +| length | int | | 0 | Length of the data block (number of characters) if the record is set to a fixed length -|columnName |string |optional - default value = "" - defines the field's -header name; uses the name of the property as default. Only applicable when `CsvRecord` has `generateHeaderColumns = true` +| lengthPos | int | | 0 | Identifies a data field in the record that defines the expected fixed length for this field -|impliedDecimalSeparator |boolean |optional - default value = "false" - Indicates if there is -a decimal point implied at a specified location +| method | String | | a| Method name to call to apply such customization on DataField. This must be the method on the datafield itself or +you must provide static fully qualified name of the class's method e.g: see unit test +org.apache.camel.dataformat.bindy.csv.BindySimpleCsvFunctionWithExternalMethodTest.replaceToBar -|lengthPos |int |optional - can be used to identify a data field in a -fixed-length record that defines the fixed length for this field +| name | String | | | Name of the field (optional) -|align |string |optional - default value = "R" - Align the text to the right or left within a fixed-length field. -Use values 'R' or 'L' +| paddingChar | char | | | The char to pad with if the record is set to a fixed length + +| pattern | String | | a| Pattern that the Java formatter (SimpleDateFormat by example) will use to transform the data (optional). If using +pattern, then setting locale on bindy data format is recommended. Either set to a known locale such as "us" or +use "default" to use platform default locale. + +| position | int | | 0 a| Position of the field in the output message generated (should start from 1). Must be used when the position of +the field in the CSV generated (output message) must be different compare to input position (pos). See the pos +parameter. + +| precision | int | | 0 | precision of the {@link java.math.BigDecimal} number to be created + +| required | boolean | | false | Indicates if the field is mandatory + +| rounding | String | | CEILING a| Round mode to be used to round/scale a BigDecimal Values : UP, DOWN, CEILING, FLOOR, HALF_UP, +HALF_DOWN,HALF_EVEN, UNNECESSARY e.g : Number = 123456.789, Precision = 2, Rounding = CEILING Result : 123456.79 + +| timezone | String | | | @return String timezone ID + +| trim | boolean | | false | Indicates if the value should be trimmed -|delimiter |string |optional - can be used to demarcate the end of a variable-length field within a fixed-length record |=== +// annotation options: END *case 1 : pos* @@ -726,59 +747,55 @@ aligned to the right or to the left. + When the size of the data does not fill completely the length of the field, we can then add 'padd' characters. -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*FixedLengthRecord* |fixed |Class +|FixedLengthRecord |fixed |Class |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.FixedLengthRecord +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info -|crlf |string |optional - possible values = WINDOWS,UNIX,MAC, or custom; default value. -WINDOWS - allow to define the carriage return character to use. If you -specify a value other than the three listed before, the value you enter -(custom) will be used as the CRLF character(s). This option is used only during marshalling, -whereas unmarshalling uses system default JDK provided line delimiter unless eol is customized +| countGrapheme | boolean | | false | Indicates how chars are counted -|eol |string |optional - default="" which is empty string. Character to be used to process -considering end of line after each record while unmarshalling (optional - default = "" -which help default JDK provided line delimiter to be used unless any other line delimiter -provided). This option is used only during unmarshalling, where marshalling uses system default -provided line delimiter as "WINDOWS" unless any other value is provided +| crlf | String | | WINDOWS a| Character to be used to add a carriage return after each record (optional). Possible values: WINDOWS, UNIX, MAC, +or custom. This option is used only during marshalling, whereas unmarshalling uses system default JDK provided +line delimiter unless eol is customized. -|paddingChar |char |mandatory - default value = ' ' +| eol | String | | a| Character to be used to process considering end of line after each record while unmarshalling (optional - default += "" which help default JDK provided line delimiter to be used unless any other line delimiter provided) This +option is used only during unmarshalling, where marshalling uses system default provided line delimiter as +"WINDOWS" unless any other value is provided. -|length |int |mandatory = size of the fixed length record (number of characters) +| footer | Class | | void | Indicates that the record(s) of this type may be followed by a single footer record at the end of the file -|hasHeader |boolean |optional - Indicates that the record(s) of this type may -be preceded by a single header record at the beginning of the file / -stream +| header | Class | | void a| Indicates that the record(s) of this type may be preceded by a single header record at the beginning of in the +file -|hasFooter |boolean |optional - Indicates that the record(s) of this type may -be followed by a single footer record at the end of the file / stream +| ignoreMissingChars | boolean | | false | Indicates whether too short lines will be ignored -|skipHeader |boolean |optional - Configures the data format to skip marshalling -/ unmarshalling of the header record. Configure this parameter on the -primary record (e.g., not the header or footer). +| ignoreTrailingChars | boolean | | false a| Indicates that characters beyond the last mapped filed can be ignored when unmarshalling / parsing. This +annotation is associated to the root class of the model and must be declared one time. -|skipFooter |boolean |optional - Configures the data format to skip marshalling -/ unmarshalling of the footer record Configure this parameter on the -primary record (e.g., not the header or footer).. +| length | int | | 0 a| The fixed length of the record (number of characters). It means that the record will always be that long padded +with {#paddingChar()}'s -|isHeader |boolean |optional - Identifies this FixedLengthRecord as a header -record +| name | String | | | Name describing the record (optional) -|isFooter |boolean |optional - Identifies this FixedLengthRecords as a footer -record +| paddingChar | char | | | The char to pad with. -|ignoreTrailingChars |boolean |optional - Indicates that characters beyond the last -mapped filed can be ignored when unmarshalling / parsing. This annotation is associated to the root class of the model and must be -declared one time. -|=== +| skipFooter | boolean | | false a| Configures the data format to skip marshalling / unmarshalling of the footer record. Configure this parameter on +the primary record (e.g., not the header or footer). +| skipHeader | boolean | | false a| Configures the data format to skip marshalling / unmarshalling of the header record. Configure this parameter on +the primary record (e.g., not the header or footer). + +|=== +// annotation options: END The hasHeader/hasFooter parameters are mutually exclusive with isHeader/isFooter. A record may not be both a header/footer and a @@ -1127,7 +1144,7 @@ public class OrderFooter { } ---- -*case 7 : Skipping content when parsing a fixed length record. +*case 7 : Skipping content when parsing a fixed length record* It is common to integrate with systems that provide fixed-length records containing more information than needed for the target use case. It is @@ -1169,7 +1186,9 @@ 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) - *"FIX information"* +[NOTE] +==== +*FIX information* More information about FIX can be found on this web site : http://www.fixprotocol.org/[http://www.fixprotocol.org/]. To work with @@ -1178,35 +1197,41 @@ 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 http://www.quickfixj.org/[http://www.quickfixj.org/]. +==== -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*Message* |key value pair |Class +|Message |key value pair |Class |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.Message +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| keyValuePairSeparator | String | ✓ | a| Key value pair separator is used to split the values from their keys (mandatory). Can be '\u0001', '\u0009', '#', +or 'anything'. -|pairSeparator |string |mandatory - can be '=' or ';' or 'anything' +| pairSeparator | String | ✓ | | Pair separator used to split the key value pairs in tokens (mandatory). Can be '=', ';', or 'anything'. -|keyValuePairSeparair |string |mandatory - can be '\u0001', '\u0009', '#' or 'anything' +| crlf | String | | WINDOWS a| Character to be used to add a carriage return after each record (optional). Possible values = WINDOWS, UNIX, MAC, +or custom. If you specify a value other than the three listed before, the value you enter (custom) will be used +as the CRLF character(s). -|crlf |string |optional - possible values = WINDOWS,UNIX,MAC, or custom; default value -== WINDOWS - allow to define the carriage return character to use. If you -specify a value other than the three listed before, the value you enter -(custom) will be used as the CRLF character(s) +| isOrdered | boolean | | false a| Indicates if the message must be ordered in output. This annotation is associated to the message class of the +model and must be declared one time. -|type |string |optional - define the type of message (e.g. FIX, EMX, ...) +| name | String | | | Name describing the message (optional) -|version |string |optional - version of the message (e.g. 4.1) +| type | String | | FIX | type is used to define the type of the message (e.g. FIX, EMX, ...) (optional) + +| version | String | | 4.1 | version defines the version of the message (e.g. 4.1, ...) (optional) -|isOrdered |boolean |optional - default value = false - allow to change the order of the -fields when FIX message is generated. This annotation is associated to the message class of the model and must -be declared one time. |=== +// annotation options: END *case 1 : separator = 'u0001'* @@ -1232,7 +1257,7 @@ public class Order { } ---- - *Look at test cases* +*Look at test cases* 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 @@ -1247,34 +1272,38 @@ 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 -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*KeyValuePairField* |Key Value Pair - FIX |Property +|KeyValuePairField |Key Value Pair - FIX |Property |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.KeyValuePairField +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| tag | int | ✓ | | tag identifying the field in the message (mandatory) - must be unique + +| impliedDecimalSeparator | boolean | | false | <b>Camel 2.11:</b> Indicates if there is a decimal point implied at a specified location + +| name | String | | | name of the field (optional) -|tag |int |mandatory - digit number identifying the field in the message - must be -unique +| pattern | String | | | pattern that the formater will use to transform the data (optional) -|pattern |string |optional - default value = "" - will be used to format Decimal, Date, -... +| position | int | | 0 a| Position of the field in the message generated - must be used when the position of the key/tag in the FIX message +must be different -|precision |int |optional - digit number - represents the precision to be used when the -Decimal number will be formatted/parsed +| precision | int | | 0 | precision of the BigDecimal number to be created -|position |int |optional - must be used when the position of the key/tag in the FIX -message must be different +| required | boolean | | false | Indicates if the field is mandatory -|required |boolean |optional - default value = "false" +| timezone | String | | | Timezone to be used. -|impliedDecimalSeparator |boolean |*Camel 2.11:* optional - default value = "false" - Indicates if there is -a decimal point implied at a specified location |=== +// annotation options: END *case 1 : tag* @@ -1346,19 +1375,23 @@ section 2) and footer (= section 3) Only one attribute/parameter exists for this annotation. -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*Section* |FIX |Class +|Section |FIX |Class |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.Section +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| number | int | ✓ | | Number of the section -|number |int |digit number identifying the section position |=== +// annotation options: END *case 1 : Section* @@ -1424,7 +1457,7 @@ The purpose of the annotation @OneToMany is to allow to work with a `List<?>` field defined a POJO class or from a record containing repetitive groups. - *Restrictions OneToMany* +*Restrictions OneToMany* Be careful, the one to many of bindy does not allow to handle repetitions defined on several levels of the hierarchy @@ -1435,20 +1468,23 @@ The relation OneToMany ONLY WORKS in the following cases : tags/keys) * Generating a CSV with repetitive data -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*OneToMany* |all |property +|OneToMany |all |Property |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.OneToMany +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| mappedTo | String | | | Class name associated to the type of the List<Type of the Class> -|mappedTo |string |optional - string - class name associated to the type of the List<Type -of the Class> |=== +// annotation options: END *case 1 : Generating CSV with repetitive data* diff --git a/components/camel-bindy/src/main/docs/bindy-dataformat.adoc b/components/camel-bindy/src/main/docs/bindy-dataformat.adoc index 3a41560..dc98be7 100644 --- a/components/camel-bindy/src/main/docs/bindy-dataformat.adoc +++ b/components/camel-bindy/src/main/docs/bindy-dataformat.adoc @@ -106,46 +106,52 @@ to several children model classes. |CsvRecord |csv |Class |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.CsvRecord +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info -|separator |string |mandatory - can be ',' or ';' or 'anything'. The only whitespace character supported is tab (\t). No other whitespace characters (spaces) are not supported. 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 '\|' sign, than you have to mask -it, like '\|' +| separator | String | ✓ | a| Separator used to split a record in tokens (mandatory) - can be ',' or ';' or 'anything'. The only whitespace +character supported is tab (\t). No other whitespace characters (spaces) are not supported. 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 '\|' sign, than you have to mask it, like '\|' -|skipFirstLine |boolean |optional - default value = false - allow to skip the first line of the -CSV file +| allowEmptyStream | boolean | | false | The allowEmptyStream parameter will allow to prcoess the unavaiable stream for CSV file. -|crlf |string |optional - possible values = WINDOWS,UNIX,MAC, or custom; default value. -WINDOWS - allow to define the carriage return character to use. If you -specify a value other than the three listed before, the value you enter -(custom) will be used as the CRLF character(s) +| autospanLine | boolean | | false a| Last record spans rest of line (optional) - if enabled then the last column is auto spanned to end of line, for +example if its a comment, etc this allows the line to contain all characters, also the delimiter char. -|generateHeaderColumns |boolean |optional - default value = false - uses to generate the header columns -of the CSV generates +| crlf | String | | WINDOWS a| Character to be used to add a carriage return after each record (optional) - allow to define the carriage return +character to use. If you specify a value other than the three listed before, the value you enter (custom) will be +used as the CRLF character(s). Three values can be used : WINDOWS, UNIX, MAC, or custom. -|autospanLine |boolean |optional - default value = false - if enabled then -the last column is auto spanned to end of line, for example if its a -comment, etc this allows the line to contain all characters, also the -delimiter char. +| endWithLineBreak | boolean | | true | The endWithLineBreak parameter flags if the CSV file should end with a line break or not (optional) -|isOrdered |boolean |optional - default value = false - allow to change the order of the -fields when CSV is generated +| generateHeaderColumns | boolean | | false | The generateHeaderColumns parameter allow to add in the CSV generated the header containing names of the columns -|quote |String |optional - allow to specify a quote character of the -fields when CSV is generated. This annotation is associated to the root class of the model and must be -declared one time. +| isOrdered | boolean | | false | Indicates if the message must be ordered in output -|quoting |boolean |optional - default value = false - Indicate if the values (and headers) -must be quoted when marshaling when CSV is generated. +| name | String | | | Name describing the record (optional) -|endWithLineBreak |boolean |optional - default value = true - Indicate if the CSV generated file -should end with a line break. +| quote | String | | " a| Whether to marshal columns with the given quote character (optional) - allow to specify a quote character of the +fields when CSV is generated. This annotation is associated to the root class of the model and must be declared +one time. + +| quoting | boolean | | false | Indicate if the values (and headers) must be quoted when marshaling (optional) + +| quotingEscaped | boolean | | false | Indicate if the values must be escaped when quoting (optional) + +| removeQuotes | boolean | | true | The remove quotes parameter flags if unmarshalling should try to remove quotes for each field + +| skipField | boolean | | false a| The skipField parameter will allow to skip fields of a CSV file. If some fields are not necessary, they can be +skipped. + +| skipFirstLine | boolean | | false a| The skipFirstLine parameter will allow to skip or not the first line of a CSV file. This line often contains +columns definition -| |=== +// annotation options: END *case 1 : separator = ','* @@ -350,23 +356,25 @@ to generate the CSV The link annotation will allow to link objects together. -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*Link* |all |Class & Property +|Link |all |Class & Property |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.Link +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info -|linkType |LinkType |optional - by default the value is LinkType.oneToOne - so you are not -obliged to mention it +| linkType | LinkType | | OneToOne | Type of link identifying the relation between the classes |=== +// annotation options: END -Only one-to-one relation is allowed. +Only one-to-one relation is allowed as of the current version. e.g : If the model Class Client is linked to the Order class, then use annotation Link in the Order class like this : @@ -404,59 +412,72 @@ 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 -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*DataField* |all |Property +|DataField |all |Property |=== - -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.DataField +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| pos | int | ✓ | | Position of the data in the input record, must start from 1 (mandatory). See the position parameter. -|pos |int |mandatory - The *input* position of the field. digit number starting -from 1 to ... - See the position parameter. +| align | String | | R | Align the text to the right or left. Use values <tt>R</tt> or <tt>L</tt>. -|pattern |string |optional - default value = "" - will be used to format Decimal, Date, +| clip | boolean | | false | Indicates to clip data in the field if it exceeds the allowed length when using fixed length. -|length |int |optional - represents the length of the field (number of characters) for fixed length format +| columnName | String | | a| Name of the header column (optional). Uses the name of the property as default. Only applicable when `CsvRecord` +has `generateHeaderColumns = true` -|precision |int |optional - represents the precision to be used when the Decimal number -will be formatted/parsed +| decimalSeparator | String | | | Decimal Separator to be used with BigDecimal number -|pattern |string |optional - default value = "" - is used by the Java formatter -(SimpleDateFormat by example) to format/validate data. If using pattern, -then setting locale on bindy data format is recommended. Either set to a -known locale such as "us" or use "default" to use platform default -locale. +| defaultValue | String | | | Field's default value in case no value is set -|position |int |optional - must be used when the position of the field in the CSV -generated (output message) must be different compare to input position -(pos). See the pos parameter. +| delimiter | String | | | Optional delimiter to be used if the field has a variable length -|required |boolean |optional - default value = "false" +| groupingSeparator | String | | a| Grouping Separator to be used with BigDecimal number when we would like to format/parse to number with grouping +e.g. 123,456.789 -|trim |boolean |optional - default value = "false" +| impliedDecimalSeparator | boolean | | false | Indicates if there is a decimal point implied at a specified location -|defaultValue |string |optional - default value = "" - defines the field's -default value when the respective CSV field is empty/not available +| length | int | | 0 | Length of the data block (number of characters) if the record is set to a fixed length -|columnName |string |optional - default value = "" - defines the field's -header name; uses the name of the property as default. Only applicable when `CsvRecord` has `generateHeaderColumns = true` +| lengthPos | int | | 0 | Identifies a data field in the record that defines the expected fixed length for this field -|impliedDecimalSeparator |boolean |optional - default value = "false" - Indicates if there is -a decimal point implied at a specified location +| method | String | | a| Method name to call to apply such customization on DataField. This must be the method on the datafield itself or +you must provide static fully qualified name of the class's method e.g: see unit test +org.apache.camel.dataformat.bindy.csv.BindySimpleCsvFunctionWithExternalMethodTest.replaceToBar -|lengthPos |int |optional - can be used to identify a data field in a -fixed-length record that defines the fixed length for this field +| name | String | | | Name of the field (optional) -|align |string |optional - default value = "R" - Align the text to the right or left within a fixed-length field. -Use values 'R' or 'L' +| paddingChar | char | | | The char to pad with if the record is set to a fixed length + +| pattern | String | | a| Pattern that the Java formatter (SimpleDateFormat by example) will use to transform the data (optional). If using +pattern, then setting locale on bindy data format is recommended. Either set to a known locale such as "us" or +use "default" to use platform default locale. + +| position | int | | 0 a| Position of the field in the output message generated (should start from 1). Must be used when the position of +the field in the CSV generated (output message) must be different compare to input position (pos). See the pos +parameter. + +| precision | int | | 0 | precision of the {@link java.math.BigDecimal} number to be created + +| required | boolean | | false | Indicates if the field is mandatory + +| rounding | String | | CEILING a| Round mode to be used to round/scale a BigDecimal Values : UP, DOWN, CEILING, FLOOR, HALF_UP, +HALF_DOWN,HALF_EVEN, UNNECESSARY e.g : Number = 123456.789, Precision = 2, Rounding = CEILING Result : 123456.79 + +| timezone | String | | | @return String timezone ID + +| trim | boolean | | false | Indicates if the value should be trimmed -|delimiter |string |optional - can be used to demarcate the end of a variable-length field within a fixed-length record |=== +// annotation options: END *case 1 : pos* @@ -726,59 +747,55 @@ aligned to the right or to the left. + When the size of the data does not fill completely the length of the field, we can then add 'padd' characters. -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*FixedLengthRecord* |fixed |Class +|FixedLengthRecord |fixed |Class |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.FixedLengthRecord +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info -|crlf |string |optional - possible values = WINDOWS,UNIX,MAC, or custom; default value. -WINDOWS - allow to define the carriage return character to use. If you -specify a value other than the three listed before, the value you enter -(custom) will be used as the CRLF character(s). This option is used only during marshalling, -whereas unmarshalling uses system default JDK provided line delimiter unless eol is customized +| countGrapheme | boolean | | false | Indicates how chars are counted -|eol |string |optional - default="" which is empty string. Character to be used to process -considering end of line after each record while unmarshalling (optional - default = "" -which help default JDK provided line delimiter to be used unless any other line delimiter -provided). This option is used only during unmarshalling, where marshalling uses system default -provided line delimiter as "WINDOWS" unless any other value is provided +| crlf | String | | WINDOWS a| Character to be used to add a carriage return after each record (optional). Possible values: WINDOWS, UNIX, MAC, +or custom. This option is used only during marshalling, whereas unmarshalling uses system default JDK provided +line delimiter unless eol is customized. -|paddingChar |char |mandatory - default value = ' ' +| eol | String | | a| Character to be used to process considering end of line after each record while unmarshalling (optional - default += "" which help default JDK provided line delimiter to be used unless any other line delimiter provided) This +option is used only during unmarshalling, where marshalling uses system default provided line delimiter as +"WINDOWS" unless any other value is provided. -|length |int |mandatory = size of the fixed length record (number of characters) +| footer | Class | | void | Indicates that the record(s) of this type may be followed by a single footer record at the end of the file -|hasHeader |boolean |optional - Indicates that the record(s) of this type may -be preceded by a single header record at the beginning of the file / -stream +| header | Class | | void a| Indicates that the record(s) of this type may be preceded by a single header record at the beginning of in the +file -|hasFooter |boolean |optional - Indicates that the record(s) of this type may -be followed by a single footer record at the end of the file / stream +| ignoreMissingChars | boolean | | false | Indicates whether too short lines will be ignored -|skipHeader |boolean |optional - Configures the data format to skip marshalling -/ unmarshalling of the header record. Configure this parameter on the -primary record (e.g., not the header or footer). +| ignoreTrailingChars | boolean | | false a| Indicates that characters beyond the last mapped filed can be ignored when unmarshalling / parsing. This +annotation is associated to the root class of the model and must be declared one time. -|skipFooter |boolean |optional - Configures the data format to skip marshalling -/ unmarshalling of the footer record Configure this parameter on the -primary record (e.g., not the header or footer).. +| length | int | | 0 a| The fixed length of the record (number of characters). It means that the record will always be that long padded +with {#paddingChar()}'s -|isHeader |boolean |optional - Identifies this FixedLengthRecord as a header -record +| name | String | | | Name describing the record (optional) -|isFooter |boolean |optional - Identifies this FixedLengthRecords as a footer -record +| paddingChar | char | | | The char to pad with. -|ignoreTrailingChars |boolean |optional - Indicates that characters beyond the last -mapped filed can be ignored when unmarshalling / parsing. This annotation is associated to the root class of the model and must be -declared one time. -|=== +| skipFooter | boolean | | false a| Configures the data format to skip marshalling / unmarshalling of the footer record. Configure this parameter on +the primary record (e.g., not the header or footer). +| skipHeader | boolean | | false a| Configures the data format to skip marshalling / unmarshalling of the header record. Configure this parameter on +the primary record (e.g., not the header or footer). + +|=== +// annotation options: END The hasHeader/hasFooter parameters are mutually exclusive with isHeader/isFooter. A record may not be both a header/footer and a @@ -1127,7 +1144,7 @@ public class OrderFooter { } ---- -*case 7 : Skipping content when parsing a fixed length record. +*case 7 : Skipping content when parsing a fixed length record* It is common to integrate with systems that provide fixed-length records containing more information than needed for the target use case. It is @@ -1169,7 +1186,9 @@ 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) - *"FIX information"* +[NOTE] +==== +*FIX information* More information about FIX can be found on this web site : http://www.fixprotocol.org/[http://www.fixprotocol.org/]. To work with @@ -1178,35 +1197,41 @@ 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 http://www.quickfixj.org/[http://www.quickfixj.org/]. +==== -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*Message* |key value pair |Class +|Message |key value pair |Class |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.Message +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| keyValuePairSeparator | String | ✓ | a| Key value pair separator is used to split the values from their keys (mandatory). Can be '\u0001', '\u0009', '#', +or 'anything'. -|pairSeparator |string |mandatory - can be '=' or ';' or 'anything' +| pairSeparator | String | ✓ | | Pair separator used to split the key value pairs in tokens (mandatory). Can be '=', ';', or 'anything'. -|keyValuePairSeparair |string |mandatory - can be '\u0001', '\u0009', '#' or 'anything' +| crlf | String | | WINDOWS a| Character to be used to add a carriage return after each record (optional). Possible values = WINDOWS, UNIX, MAC, +or custom. If you specify a value other than the three listed before, the value you enter (custom) will be used +as the CRLF character(s). -|crlf |string |optional - possible values = WINDOWS,UNIX,MAC, or custom; default value -== WINDOWS - allow to define the carriage return character to use. If you -specify a value other than the three listed before, the value you enter -(custom) will be used as the CRLF character(s) +| isOrdered | boolean | | false a| Indicates if the message must be ordered in output. This annotation is associated to the message class of the +model and must be declared one time. -|type |string |optional - define the type of message (e.g. FIX, EMX, ...) +| name | String | | | Name describing the message (optional) -|version |string |optional - version of the message (e.g. 4.1) +| type | String | | FIX | type is used to define the type of the message (e.g. FIX, EMX, ...) (optional) + +| version | String | | 4.1 | version defines the version of the message (e.g. 4.1, ...) (optional) -|isOrdered |boolean |optional - default value = false - allow to change the order of the -fields when FIX message is generated. This annotation is associated to the message class of the model and must -be declared one time. |=== +// annotation options: END *case 1 : separator = 'u0001'* @@ -1232,7 +1257,7 @@ public class Order { } ---- - *Look at test cases* +*Look at test cases* 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 @@ -1247,34 +1272,38 @@ 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 -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*KeyValuePairField* |Key Value Pair - FIX |Property +|KeyValuePairField |Key Value Pair - FIX |Property |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.KeyValuePairField +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| tag | int | ✓ | | tag identifying the field in the message (mandatory) - must be unique + +| impliedDecimalSeparator | boolean | | false | <b>Camel 2.11:</b> Indicates if there is a decimal point implied at a specified location + +| name | String | | | name of the field (optional) -|tag |int |mandatory - digit number identifying the field in the message - must be -unique +| pattern | String | | | pattern that the formater will use to transform the data (optional) -|pattern |string |optional - default value = "" - will be used to format Decimal, Date, -... +| position | int | | 0 a| Position of the field in the message generated - must be used when the position of the key/tag in the FIX message +must be different -|precision |int |optional - digit number - represents the precision to be used when the -Decimal number will be formatted/parsed +| precision | int | | 0 | precision of the BigDecimal number to be created -|position |int |optional - must be used when the position of the key/tag in the FIX -message must be different +| required | boolean | | false | Indicates if the field is mandatory -|required |boolean |optional - default value = "false" +| timezone | String | | | Timezone to be used. -|impliedDecimalSeparator |boolean |*Camel 2.11:* optional - default value = "false" - Indicates if there is -a decimal point implied at a specified location |=== +// annotation options: END *case 1 : tag* @@ -1346,19 +1375,23 @@ section 2) and footer (= section 3) Only one attribute/parameter exists for this annotation. -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*Section* |FIX |Class +|Section |FIX |Class |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.Section +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| number | int | ✓ | | Number of the section -|number |int |digit number identifying the section position |=== +// annotation options: END *case 1 : Section* @@ -1424,7 +1457,7 @@ The purpose of the annotation @OneToMany is to allow to work with a `List<?>` field defined a POJO class or from a record containing repetitive groups. - *Restrictions OneToMany* +*Restrictions OneToMany* Be careful, the one to many of bindy does not allow to handle repetitions defined on several levels of the hierarchy @@ -1435,20 +1468,23 @@ The relation OneToMany ONLY WORKS in the following cases : tags/keys) * Generating a CSV with repetitive data -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*OneToMany* |all |property +|OneToMany |all |Property |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.OneToMany +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| mappedTo | String | | | Class name associated to the type of the List<Type of the Class> -|mappedTo |string |optional - string - class name associated to the type of the List<Type -of the Class> |=== +// annotation options: END *case 1 : Generating CSV with repetitive data* diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/CsvRecord.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/CsvRecord.java index f3c1fb7..35c6c356 100644 --- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/CsvRecord.java +++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/CsvRecord.java @@ -39,7 +39,10 @@ public @interface CsvRecord { String name() default ""; /** - * Separator used to split a record in tokens (mandatory) + * Separator used to split a record in tokens (mandatory) - can be ',' or ';' or 'anything'. The only whitespace + * character supported is tab (\t). No other whitespace characters (spaces) are not supported. 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 '\|' sign, than you have to mask it, like '\|' */ String separator(); @@ -56,8 +59,9 @@ public @interface CsvRecord { boolean skipField() default false; /** - * Character to be used to add a carriage return after each record (optional) Three values can be used : WINDOWS, - * UNIX or MAC. + * Character to be used to add a carriage return after each record (optional) - allow to define the carriage return + * character to use. If you specify a value other than the three listed before, the value you enter (custom) will be + * used as the CRLF character(s). Three values can be used : WINDOWS, UNIX, MAC, or custom. */ String crlf() default "WINDOWS"; @@ -72,7 +76,9 @@ public @interface CsvRecord { boolean isOrdered() default false; /** - * Whether to marshal columns with the given quote character (optional) + * Whether to marshal columns with the given quote character (optional) - allow to specify a quote character of the + * fields when CSV is generated. This annotation is associated to the root class of the model and must be declared + * one time. */ String quote() default "\""; @@ -87,7 +93,8 @@ public @interface CsvRecord { boolean quotingEscaped() default false; /** - * Last record spans rest of line (optional) + * Last record spans rest of line (optional) - if enabled then the last column is auto spanned to end of line, for + * example if its a comment, etc this allows the line to contain all characters, also the delimiter char. */ boolean autospanLine() default false; diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/DataField.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/DataField.java index d2ed5a0..e2e7561 100644 --- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/DataField.java +++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/DataField.java @@ -36,7 +36,7 @@ import java.lang.annotation.RetentionPolicy; public @interface DataField { /** - * Position of the data in the input record, must start from 1 (mandatory). + * Position of the data in the input record, must start from 1 (mandatory). See the position parameter. */ int pos(); @@ -46,12 +46,15 @@ public @interface DataField { String name() default ""; /** - * Name of the header column (optional) + * Name of the header column (optional). Uses the name of the property as default. Only applicable when `CsvRecord` + * has `generateHeaderColumns = true` */ String columnName() default ""; /** - * Pattern that the formatter will use to transform the data (optional) + * Pattern that the Java formatter (SimpleDateFormat by example) will use to transform the data (optional). If using + * pattern, then setting locale on bindy data format is recommended. Either set to a known locale such as "us" or + * use "default" to use platform default locale. */ String pattern() default ""; @@ -86,7 +89,9 @@ public @interface DataField { int precision() default 0; /** - * Position of the field in the output message generated (should start from 1) + * Position of the field in the output message generated (should start from 1). Must be used when the position of + * the field in the CSV generated (output message) must be different compare to input position (pos). See the pos + * parameter. * * @see #pos() */ diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/FixedLengthRecord.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/FixedLengthRecord.java index af10ba2..22e53f2 100644 --- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/FixedLengthRecord.java +++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/FixedLengthRecord.java @@ -36,9 +36,9 @@ public @interface FixedLengthRecord { String name() default ""; /** - * Character to be used to add a carriage return after each record (optional) Three values can be used : WINDOWS, - * UNIX or MAC This option is used only during marshalling, whereas unmarshalling uses system default JDK provided - * line delimiter unless eol is customized + * Character to be used to add a carriage return after each record (optional). Possible values: WINDOWS, UNIX, MAC, + * or custom. This option is used only during marshalling, whereas unmarshalling uses system default JDK provided + * line delimiter unless eol is customized. * * @return String */ @@ -48,7 +48,7 @@ public @interface FixedLengthRecord { * Character to be used to process considering end of line after each record while unmarshalling (optional - default * = "" which help default JDK provided line delimiter to be used unless any other line delimiter provided) This * option is used only during unmarshalling, where marshalling uses system default provided line delimiter as - * "WINDOWS" unless any other value is provided + * "WINDOWS" unless any other value is provided. * * @return String */ @@ -81,17 +81,20 @@ public @interface FixedLengthRecord { Class<?> footer() default void.class; /** - * Configures the data format to skip marshalling / unmarshalling of the header record + * Configures the data format to skip marshalling / unmarshalling of the header record. Configure this parameter on + * the primary record (e.g., not the header or footer). */ boolean skipHeader() default false; /** - * Configures the data format to skip marshalling / unmarshalling of the footer record + * Configures the data format to skip marshalling / unmarshalling of the footer record. Configure this parameter on + * the primary record (e.g., not the header or footer). */ boolean skipFooter() default false; /** - * Indicates whether trailing characters beyond the last mapped field may be ignored + * Indicates that characters beyond the last mapped filed can be ignored when unmarshalling / parsing. This + * annotation is associated to the root class of the model and must be declared one time. */ boolean ignoreTrailingChars() default false; diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/KeyValuePairField.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/KeyValuePairField.java index 7be0074..18a9688 100644 --- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/KeyValuePairField.java +++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/KeyValuePairField.java @@ -34,7 +34,7 @@ import java.lang.annotation.RetentionPolicy; public @interface KeyValuePairField { /** - * tag identifying the field in the message (mandatory) + * tag identifying the field in the message (mandatory) - must be unique * * @return int */ @@ -55,12 +55,15 @@ public @interface KeyValuePairField { String pattern() default ""; /** + * Timezone to be used. + * * @return String timezone ID */ String timezone() default ""; /** - * Position of the field in the message generated + * Position of the field in the message generated - must be used when the position of the key/tag in the FIX message + * must be different * * @return int */ @@ -79,7 +82,7 @@ public @interface KeyValuePairField { boolean required() default false; /** - * Indicates if there is a decimal point implied at a specified location + * <b>Camel 2.11:</b> Indicates if there is a decimal point implied at a specified location */ boolean impliedDecimalSeparator() default false; } diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/Link.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/Link.java index 1475fba..5ddd658 100644 --- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/Link.java +++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/Link.java @@ -21,7 +21,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** - * This annotation allows to link classes together in the model. This release version 1.0 only supports oneToone + * This annotation allows to link classes together in the model. This release version 1.0 only supports one-to-one * relation */ diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/Message.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/Message.java index 3973605..28b2839 100644 --- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/Message.java +++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/Message.java @@ -42,14 +42,15 @@ public @interface Message { String name() default ""; /** - * Pair separator used to split the key value pairs in tokens (mandatory) + * Pair separator used to split the key value pairs in tokens (mandatory). Can be '=', ';', or 'anything'. * * @return String */ String pairSeparator(); /** - * Key value pair separator is used to split the values from their keys (mandatory) + * Key value pair separator is used to split the values from their keys (mandatory). Can be '\u0001', '\u0009', '#', + * or 'anything'. * * @return String */ @@ -66,15 +67,17 @@ public @interface Message { String version() default "4.1"; /** - * Character to be used to add a carriage return after each record (optional) Three values can be used : WINDOWS, - * UNIX or MAC + * Character to be used to add a carriage return after each record (optional). Possible values = WINDOWS, UNIX, MAC, + * or custom. If you specify a value other than the three listed before, the value you enter (custom) will be used + * as the CRLF character(s). * * @return String */ String crlf() default "WINDOWS"; /** - * Indicates if the message must be ordered in output + * Indicates if the message must be ordered in output. This annotation is associated to the message class of the + * model and must be declared one time. * * @return boolean */ diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/OneToMany.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/OneToMany.java index 55141ac..6393382 100644 --- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/OneToMany.java +++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/OneToMany.java @@ -24,5 +24,8 @@ import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) public @interface OneToMany { + /** + * Class name associated to the type of the List<Type of the Class> + */ String mappedTo() default ""; } diff --git a/docs/components/modules/dataformats/pages/bindy-dataformat.adoc b/docs/components/modules/dataformats/pages/bindy-dataformat.adoc index 2ac40d4..7c6fd2b 100644 --- a/docs/components/modules/dataformats/pages/bindy-dataformat.adoc +++ b/docs/components/modules/dataformats/pages/bindy-dataformat.adoc @@ -108,46 +108,52 @@ to several children model classes. |CsvRecord |csv |Class |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.CsvRecord +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info -|separator |string |mandatory - can be ',' or ';' or 'anything'. The only whitespace character supported is tab (\t). No other whitespace characters (spaces) are not supported. 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 '\|' sign, than you have to mask -it, like '\|' +| separator | String | ✓ | a| Separator used to split a record in tokens (mandatory) - can be ',' or ';' or 'anything'. The only whitespace +character supported is tab (\t). No other whitespace characters (spaces) are not supported. 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 '\|' sign, than you have to mask it, like '\|' -|skipFirstLine |boolean |optional - default value = false - allow to skip the first line of the -CSV file +| allowEmptyStream | boolean | | false | The allowEmptyStream parameter will allow to prcoess the unavaiable stream for CSV file. -|crlf |string |optional - possible values = WINDOWS,UNIX,MAC, or custom; default value. -WINDOWS - allow to define the carriage return character to use. If you -specify a value other than the three listed before, the value you enter -(custom) will be used as the CRLF character(s) +| autospanLine | boolean | | false a| Last record spans rest of line (optional) - if enabled then the last column is auto spanned to end of line, for +example if its a comment, etc this allows the line to contain all characters, also the delimiter char. -|generateHeaderColumns |boolean |optional - default value = false - uses to generate the header columns -of the CSV generates +| crlf | String | | WINDOWS a| Character to be used to add a carriage return after each record (optional) - allow to define the carriage return +character to use. If you specify a value other than the three listed before, the value you enter (custom) will be +used as the CRLF character(s). Three values can be used : WINDOWS, UNIX, MAC, or custom. -|autospanLine |boolean |optional - default value = false - if enabled then -the last column is auto spanned to end of line, for example if its a -comment, etc this allows the line to contain all characters, also the -delimiter char. +| endWithLineBreak | boolean | | true | The endWithLineBreak parameter flags if the CSV file should end with a line break or not (optional) -|isOrdered |boolean |optional - default value = false - allow to change the order of the -fields when CSV is generated +| generateHeaderColumns | boolean | | false | The generateHeaderColumns parameter allow to add in the CSV generated the header containing names of the columns -|quote |String |optional - allow to specify a quote character of the -fields when CSV is generated. This annotation is associated to the root class of the model and must be -declared one time. +| isOrdered | boolean | | false | Indicates if the message must be ordered in output -|quoting |boolean |optional - default value = false - Indicate if the values (and headers) -must be quoted when marshaling when CSV is generated. +| name | String | | | Name describing the record (optional) -|endWithLineBreak |boolean |optional - default value = true - Indicate if the CSV generated file -should end with a line break. +| quote | String | | " a| Whether to marshal columns with the given quote character (optional) - allow to specify a quote character of the +fields when CSV is generated. This annotation is associated to the root class of the model and must be declared +one time. + +| quoting | boolean | | false | Indicate if the values (and headers) must be quoted when marshaling (optional) + +| quotingEscaped | boolean | | false | Indicate if the values must be escaped when quoting (optional) + +| removeQuotes | boolean | | true | The remove quotes parameter flags if unmarshalling should try to remove quotes for each field + +| skipField | boolean | | false a| The skipField parameter will allow to skip fields of a CSV file. If some fields are not necessary, they can be +skipped. + +| skipFirstLine | boolean | | false a| The skipFirstLine parameter will allow to skip or not the first line of a CSV file. This line often contains +columns definition -| |=== +// annotation options: END *case 1 : separator = ','* @@ -352,23 +358,25 @@ to generate the CSV The link annotation will allow to link objects together. -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*Link* |all |Class & Property +|Link |all |Class & Property |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.Link +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info -|linkType |LinkType |optional - by default the value is LinkType.oneToOne - so you are not -obliged to mention it +| linkType | LinkType | | OneToOne | Type of link identifying the relation between the classes |=== +// annotation options: END -Only one-to-one relation is allowed. +Only one-to-one relation is allowed as of the current version. e.g : If the model Class Client is linked to the Order class, then use annotation Link in the Order class like this : @@ -406,59 +414,72 @@ 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 -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*DataField* |all |Property +|DataField |all |Property |=== - -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.DataField +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| pos | int | ✓ | | Position of the data in the input record, must start from 1 (mandatory). See the position parameter. + +| align | String | | R | Align the text to the right or left. Use values <tt>R</tt> or <tt>L</tt>. -|pos |int |mandatory - The *input* position of the field. digit number starting -from 1 to ... - See the position parameter. +| clip | boolean | | false | Indicates to clip data in the field if it exceeds the allowed length when using fixed length. -|pattern |string |optional - default value = "" - will be used to format Decimal, Date, +| columnName | String | | a| Name of the header column (optional). Uses the name of the property as default. Only applicable when `CsvRecord` +has `generateHeaderColumns = true` -|length |int |optional - represents the length of the field (number of characters) for fixed length format +| decimalSeparator | String | | | Decimal Separator to be used with BigDecimal number -|precision |int |optional - represents the precision to be used when the Decimal number -will be formatted/parsed +| defaultValue | String | | | Field's default value in case no value is set -|pattern |string |optional - default value = "" - is used by the Java formatter -(SimpleDateFormat by example) to format/validate data. If using pattern, -then setting locale on bindy data format is recommended. Either set to a -known locale such as "us" or use "default" to use platform default -locale. +| delimiter | String | | | Optional delimiter to be used if the field has a variable length -|position |int |optional - must be used when the position of the field in the CSV -generated (output message) must be different compare to input position -(pos). See the pos parameter. +| groupingSeparator | String | | a| Grouping Separator to be used with BigDecimal number when we would like to format/parse to number with grouping +e.g. 123,456.789 -|required |boolean |optional - default value = "false" +| impliedDecimalSeparator | boolean | | false | Indicates if there is a decimal point implied at a specified location -|trim |boolean |optional - default value = "false" +| length | int | | 0 | Length of the data block (number of characters) if the record is set to a fixed length -|defaultValue |string |optional - default value = "" - defines the field's -default value when the respective CSV field is empty/not available +| lengthPos | int | | 0 | Identifies a data field in the record that defines the expected fixed length for this field -|columnName |string |optional - default value = "" - defines the field's -header name; uses the name of the property as default. Only applicable when `CsvRecord` has `generateHeaderColumns = true` +| method | String | | a| Method name to call to apply such customization on DataField. This must be the method on the datafield itself or +you must provide static fully qualified name of the class's method e.g: see unit test +org.apache.camel.dataformat.bindy.csv.BindySimpleCsvFunctionWithExternalMethodTest.replaceToBar -|impliedDecimalSeparator |boolean |optional - default value = "false" - Indicates if there is -a decimal point implied at a specified location +| name | String | | | Name of the field (optional) -|lengthPos |int |optional - can be used to identify a data field in a -fixed-length record that defines the fixed length for this field +| paddingChar | char | | | The char to pad with if the record is set to a fixed length -|align |string |optional - default value = "R" - Align the text to the right or left within a fixed-length field. -Use values 'R' or 'L' +| pattern | String | | a| Pattern that the Java formatter (SimpleDateFormat by example) will use to transform the data (optional). If using +pattern, then setting locale on bindy data format is recommended. Either set to a known locale such as "us" or +use "default" to use platform default locale. + +| position | int | | 0 a| Position of the field in the output message generated (should start from 1). Must be used when the position of +the field in the CSV generated (output message) must be different compare to input position (pos). See the pos +parameter. + +| precision | int | | 0 | precision of the {@link java.math.BigDecimal} number to be created + +| required | boolean | | false | Indicates if the field is mandatory + +| rounding | String | | CEILING a| Round mode to be used to round/scale a BigDecimal Values : UP, DOWN, CEILING, FLOOR, HALF_UP, +HALF_DOWN,HALF_EVEN, UNNECESSARY e.g : Number = 123456.789, Precision = 2, Rounding = CEILING Result : 123456.79 + +| timezone | String | | | @return String timezone ID + +| trim | boolean | | false | Indicates if the value should be trimmed -|delimiter |string |optional - can be used to demarcate the end of a variable-length field within a fixed-length record |=== +// annotation options: END *case 1 : pos* @@ -728,59 +749,57 @@ aligned to the right or to the left. + When the size of the data does not fill completely the length of the field, we can then add 'padd' characters. -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*FixedLengthRecord* |fixed |Class +|FixedLengthRecord |fixed |Class |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.FixedLengthRecord +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| countGrapheme | boolean | | false | Indicates how chars are counted + +| crlf | String | | WINDOWS a| Character to be used to add a carriage return after each record (optional). Possible values: WINDOWS, UNIX, MAC, +or custom. This option is used only during marshalling, whereas unmarshalling uses system default JDK provided +line delimiter unless eol is customized. -|crlf |string |optional - possible values = WINDOWS,UNIX,MAC, or custom; default value. -WINDOWS - allow to define the carriage return character to use. If you -specify a value other than the three listed before, the value you enter -(custom) will be used as the CRLF character(s). This option is used only during marshalling, -whereas unmarshalling uses system default JDK provided line delimiter unless eol is customized +| eol | String | | a| Character to be used to process considering end of line after each record while unmarshalling (optional - default += "" which help default JDK provided line delimiter to be used unless any other line delimiter provided) This +//THIS FILE IS COPIED: EDIT THE SOURCE FILE: +:page-source: components/camel-bindy/src/main/docs/bindy-dataformat.adoc +option is used only during unmarshalling, where marshalling uses system default provided line delimiter as +"WINDOWS" unless any other value is provided. -|eol |string |optional - default="" which is empty string. Character to be used to process -considering end of line after each record while unmarshalling (optional - default = "" -which help default JDK provided line delimiter to be used unless any other line delimiter -provided). This option is used only during unmarshalling, where marshalling uses system default -provided line delimiter as "WINDOWS" unless any other value is provided +| footer | Class | | void | Indicates that the record(s) of this type may be followed by a single footer record at the end of the file -|paddingChar |char |mandatory - default value = ' ' +| header | Class | | void a| Indicates that the record(s) of this type may be preceded by a single header record at the beginning of in the +file -|length |int |mandatory = size of the fixed length record (number of characters) +| ignoreMissingChars | boolean | | false | Indicates whether too short lines will be ignored -|hasHeader |boolean |optional - Indicates that the record(s) of this type may -be preceded by a single header record at the beginning of the file / -stream +| ignoreTrailingChars | boolean | | false a| Indicates that characters beyond the last mapped filed can be ignored when unmarshalling / parsing. This +annotation is associated to the root class of the model and must be declared one time. -|hasFooter |boolean |optional - Indicates that the record(s) of this type may -be followed by a single footer record at the end of the file / stream +| length | int | | 0 a| The fixed length of the record (number of characters). It means that the record will always be that long padded +with {#paddingChar()}'s -|skipHeader |boolean |optional - Configures the data format to skip marshalling -/ unmarshalling of the header record. Configure this parameter on the -primary record (e.g., not the header or footer). +| name | String | | | Name describing the record (optional) -|skipFooter |boolean |optional - Configures the data format to skip marshalling -/ unmarshalling of the footer record Configure this parameter on the -primary record (e.g., not the header or footer).. +| paddingChar | char | | | The char to pad with. -|isHeader |boolean |optional - Identifies this FixedLengthRecord as a header -record +| skipFooter | boolean | | false a| Configures the data format to skip marshalling / unmarshalling of the footer record. Configure this parameter on +the primary record (e.g., not the header or footer). -|isFooter |boolean |optional - Identifies this FixedLengthRecords as a footer -record +| skipHeader | boolean | | false a| Configures the data format to skip marshalling / unmarshalling of the header record. Configure this parameter on +the primary record (e.g., not the header or footer). -|ignoreTrailingChars |boolean |optional - Indicates that characters beyond the last -mapped filed can be ignored when unmarshalling / parsing. This annotation is associated to the root class of the model and must be -declared one time. |=== - +// annotation options: END The hasHeader/hasFooter parameters are mutually exclusive with isHeader/isFooter. A record may not be both a header/footer and a @@ -1129,7 +1148,7 @@ public class OrderFooter { } ---- -*case 7 : Skipping content when parsing a fixed length record. +*case 7 : Skipping content when parsing a fixed length record* It is common to integrate with systems that provide fixed-length records containing more information than needed for the target use case. It is @@ -1171,7 +1190,9 @@ 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) - *"FIX information"* +[NOTE] +==== +*FIX information* More information about FIX can be found on this web site : http://www.fixprotocol.org/[http://www.fixprotocol.org/]. To work with @@ -1180,35 +1201,41 @@ 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 http://www.quickfixj.org/[http://www.quickfixj.org/]. +==== -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*Message* |key value pair |Class +|Message |key value pair |Class |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.Message +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| keyValuePairSeparator | String | ✓ | a| Key value pair separator is used to split the values from their keys (mandatory). Can be '\u0001', '\u0009', '#', +or 'anything'. -|pairSeparator |string |mandatory - can be '=' or ';' or 'anything' +| pairSeparator | String | ✓ | | Pair separator used to split the key value pairs in tokens (mandatory). Can be '=', ';', or 'anything'. -|keyValuePairSeparair |string |mandatory - can be '\u0001', '\u0009', '#' or 'anything' +| crlf | String | | WINDOWS a| Character to be used to add a carriage return after each record (optional). Possible values = WINDOWS, UNIX, MAC, +or custom. If you specify a value other than the three listed before, the value you enter (custom) will be used +as the CRLF character(s). -|crlf |string |optional - possible values = WINDOWS,UNIX,MAC, or custom; default value -== WINDOWS - allow to define the carriage return character to use. If you -specify a value other than the three listed before, the value you enter -(custom) will be used as the CRLF character(s) +| isOrdered | boolean | | false a| Indicates if the message must be ordered in output. This annotation is associated to the message class of the +model and must be declared one time. -|type |string |optional - define the type of message (e.g. FIX, EMX, ...) +| name | String | | | Name describing the message (optional) -|version |string |optional - version of the message (e.g. 4.1) +| type | String | | FIX | type is used to define the type of the message (e.g. FIX, EMX, ...) (optional) + +| version | String | | 4.1 | version defines the version of the message (e.g. 4.1, ...) (optional) -|isOrdered |boolean |optional - default value = false - allow to change the order of the -fields when FIX message is generated. This annotation is associated to the message class of the model and must -be declared one time. |=== +// annotation options: END *case 1 : separator = 'u0001'* @@ -1234,7 +1261,7 @@ public class Order { } ---- - *Look at test cases* +*Look at test cases* 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 @@ -1249,34 +1276,38 @@ 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 -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*KeyValuePairField* |Key Value Pair - FIX |Property +|KeyValuePairField |Key Value Pair - FIX |Property |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.KeyValuePairField +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| tag | int | ✓ | | tag identifying the field in the message (mandatory) - must be unique + +| impliedDecimalSeparator | boolean | | false | <b>Camel 2.11:</b> Indicates if there is a decimal point implied at a specified location + +| name | String | | | name of the field (optional) -|tag |int |mandatory - digit number identifying the field in the message - must be -unique +| pattern | String | | | pattern that the formater will use to transform the data (optional) -|pattern |string |optional - default value = "" - will be used to format Decimal, Date, -... +| position | int | | 0 a| Position of the field in the message generated - must be used when the position of the key/tag in the FIX message +must be different -|precision |int |optional - digit number - represents the precision to be used when the -Decimal number will be formatted/parsed +| precision | int | | 0 | precision of the BigDecimal number to be created -|position |int |optional - must be used when the position of the key/tag in the FIX -message must be different +| required | boolean | | false | Indicates if the field is mandatory -|required |boolean |optional - default value = "false" +| timezone | String | | | Timezone to be used. -|impliedDecimalSeparator |boolean |*Camel 2.11:* optional - default value = "false" - Indicates if there is -a decimal point implied at a specified location |=== +// annotation options: END *case 1 : tag* @@ -1348,19 +1379,23 @@ section 2) and footer (= section 3) Only one attribute/parameter exists for this annotation. -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*Section* |FIX |Class +|Section |FIX |Class |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.Section +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| number | int | ✓ | | Number of the section -|number |int |digit number identifying the section position |=== +// annotation options: END *case 1 : Section* @@ -1426,7 +1461,7 @@ The purpose of the annotation @OneToMany is to allow to work with a `List<?>` field defined a POJO class or from a record containing repetitive groups. - *Restrictions OneToMany* +*Restrictions OneToMany* Be careful, the one to many of bindy does not allow to handle repetitions defined on several levels of the hierarchy @@ -1437,20 +1472,23 @@ The relation OneToMany ONLY WORKS in the following cases : tags/keys) * Generating a CSV with repetitive data -[width="100%",cols="10%,10%,80%",options="header",] +[width="100%",cols="10%s,10%,80%",options="header",] |=== |Annotation name |Record type |Level -|*OneToMany* |all |property +|OneToMany |all |Property |=== -[width="100%",cols="10%,10%,80%",options="header",] +// annotation interface: org.apache.camel.dataformat.bindy.annotation.OneToMany +// annotation options: START +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] |=== -|Parameter name |type |Info +| Parameter name | Type | Required | Default value | Info + +| mappedTo | String | | | Class name associated to the type of the List<Type of the Class> -|mappedTo |string |optional - string - class name associated to the type of the List<Type -of the Class> |=== +// annotation options: END *case 1 : Generating CSV with repetitive data* diff --git a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/AnnotationModel.java b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/AnnotationModel.java new file mode 100644 index 0000000..07bf1e3 --- /dev/null +++ b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/AnnotationModel.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.tooling.model; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@SuppressWarnings("unused") +public class AnnotationModel { + + protected String className; + protected List<AnnotationOptionModel> options = new ArrayList<>(); + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + public List<AnnotationOptionModel> getOptions() { + return options; + } + + public void addOption(AnnotationOptionModel option) { + options.add(option); + } + + public List<AnnotationOptionModel> getSortedOptions() { + return options.stream().sorted((o1, o2) -> { + if (o1.isOptional() == o2.isOptional()) { + return o1.getName().compareTo(o2.getName()); + } else { + return Boolean.compare(o1.isOptional(), o2.isOptional()); + } + }).collect(Collectors.toList()); + } + + public static class AnnotationOptionModel { + + protected String name; + protected String type; + protected String description; + protected String defaultValue; + protected boolean optional; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + + public boolean isOptional() { + return optional; + } + + public void setOptional(boolean optional) { + this.optional = optional; + } + } +} diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateReadmeMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateReadmeMojo.java index bc3da7e..580a1c5 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateReadmeMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateReadmeMojo.java @@ -17,8 +17,11 @@ package org.apache.camel.maven.packaging; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Method; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; @@ -32,8 +35,10 @@ import java.util.Set; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import java.util.stream.Stream; +import org.apache.camel.tooling.model.AnnotationModel; import org.apache.camel.tooling.model.ArtifactModel; import org.apache.camel.tooling.model.BaseModel; import org.apache.camel.tooling.model.BaseOptionModel; @@ -52,6 +57,12 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; +import org.jboss.forge.roaster.Roaster; +import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.ASTNode; +import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration; +import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.Javadoc; +import org.jboss.forge.roaster.model.source.AnnotationElementSource; +import org.jboss.forge.roaster.model.source.JavaAnnotationSource; import org.mvel2.templates.TemplateRuntime; import org.sonatype.plexus.build.incremental.BuildContext; @@ -110,6 +121,8 @@ public class UpdateReadmeMojo extends AbstractGeneratorMojo { @Parameter protected Boolean failFast; + protected List<Path> sourceRoots; + @Override public void execute(MavenProject project, MavenProjectHelper projectHelper, BuildContext buildContext) throws MojoFailureException, MojoExecutionException { @@ -236,7 +249,7 @@ public class UpdateReadmeMojo extends AbstractGeneratorMojo { // only if there is components we should update the documentation files if (!jsonFiles.isEmpty()) { - getLog().debug("Found " + jsonFiles.size() + "miscellaneous components"); + getLog().debug("Found " + jsonFiles.size() + " miscellaneous components"); for (File jsonFile : jsonFiles) { final String kind = "other"; String json = loadJsonFrom(jsonFile, kind); @@ -330,6 +343,12 @@ public class UpdateReadmeMojo extends AbstractGeneratorMojo { String options = evaluateTemplate("dataformat-options.mvel", model); updated |= updateOptionsIn(file, kind, options); + // optional annotation processings + // for now it's only applied to bindy but can be unlocked for other dataformats if needed + if ("bindy".equals(dataFormatName)) { + updated |= updateAnnotationsIn(file); + } + if (updated) { getLog().info("Updated doc file: " + file); } else if (exists) { @@ -800,6 +819,59 @@ public class UpdateReadmeMojo extends AbstractGeneratorMojo { } } + private boolean updateAnnotationsIn(final File file) throws MojoExecutionException { + if (!file.exists()) { + return false; + } + + try { + String text = PackageHelper.loadText(file); + String updated = updateAnnotationRecursivelyIn(text); + if (text.equals(updated)) { + return false; + } + PackageHelper.writeText(file, updated); + return true; + } catch (IOException e) { + throw new MojoExecutionException("Error reading file " + file + " Reason: " + e, e); + } + } + + private String updateAnnotationRecursivelyIn(String text) throws MojoExecutionException { + String annotationInterface = Strings.between(text, "// annotation interface:", "// annotation options: START"); + if (annotationInterface == null) { + return text; + } + annotationInterface = annotationInterface.trim(); + + Class<?> annotation = loadClass(annotationInterface); + if (!annotation.isAnnotation()) { + throw new MojoExecutionException("Interface " + annotationInterface + " is not an annotation"); + } + getLog().debug("Processing annotation " + annotationInterface); + AnnotationModel model = generateAnnotationModel(annotation); + String options = evaluateTemplate("annotation-options.mvel", model); + String updated = options.trim(); + + String existing = Strings.between(text, "// annotation options: START", "// annotation options: END"); + if (existing == null) { + return text; + } + // remove leading line breaks etc + existing = existing.trim(); + + String after = Strings.after(text, "// annotation options: END"); + // process subsequent annotations + String afterUpdated = updateAnnotationRecursivelyIn(after); + + if (existing.equals(updated) && Objects.equals(after, afterUpdated)) { + return text; + } + + String before = Strings.before(text, "// annotation options: START"); + return before + "// annotation options: START\n" + updated + "\n// annotation options: END" + afterUpdated; + } + private static String loadJsonFrom(Set<File> jsonFiles, String kind, String name) { for (File file : jsonFiles) { if (file.getName().equals(name + PackageHelper.JSON_SUFIX)) { @@ -917,6 +989,92 @@ public class UpdateReadmeMojo extends AbstractGeneratorMojo { return model; } + private AnnotationModel generateAnnotationModel(Class<?> annotation) { + String source = loadJavaSource(annotation.getName()); + JavaAnnotationSource annotationSource = parseAnnotationSource(source); + + AnnotationModel model = new AnnotationModel(); + for (Method method : annotation.getDeclaredMethods()) { + AnnotationModel.AnnotationOptionModel option = new AnnotationModel.AnnotationOptionModel(); + option.setName(method.getName()); + option.setType(method.getReturnType().getSimpleName()); + if (method.getDefaultValue() != null) { + option.setOptional(true); + option.setDefaultValue(method.getDefaultValue().toString()); + } + + String javadoc = findJavaDoc(source, annotationSource, method); + if (!Strings.isNullOrEmpty(javadoc)) { + option.setDescription(javadoc.trim()); + } + + model.addOption(option); + } + return model; + } + + private String loadJavaSource(String className) { + try { + Path file = getSourceRoots().stream() + .map(d -> d.resolve(className.replace('.', '/') + ".java")) + .filter(Files::isRegularFile) + .findFirst() + .orElse(null); + + if (file == null) { + throw new FileNotFoundException("Unable to find source for " + className); + } + return PackageHelper.loadText(file); + } catch (IOException e) { + String classpath; + try { + classpath = project.getCompileClasspathElements().toString(); + } catch (Exception e2) { + classpath = e2.toString(); + } + throw new RuntimeException( + "Unable to load source for class " + className + " in folders " + getSourceRoots() + + " (classpath: " + classpath + ")"); + } + } + + private JavaAnnotationSource parseAnnotationSource(String source) { + return Roaster.parse(JavaAnnotationSource.class, source); + } + + private List<Path> getSourceRoots() { + if (sourceRoots == null) { + sourceRoots = project.getCompileSourceRoots().stream() + .map(Paths::get) + .collect(Collectors.toList()); + } + return sourceRoots; + } + + private String findJavaDoc(String source, JavaAnnotationSource annotationSource, Method method) { + AnnotationElementSource element = annotationSource.getAnnotationElement(method.getName()); + if (element == null) { + return null; + } + return getJavaDocText(source, element); + } + + static String getJavaDocText(String source, AnnotationElementSource member) { + if (member == null) { + return null; + } + AnnotationTypeMemberDeclaration decl = (AnnotationTypeMemberDeclaration) member.getInternal(); + Javadoc jd = decl.getJavadoc(); + if (source == null || jd.tags().isEmpty()) { + return null; + } + ASTNode n = (ASTNode) jd.tags().get(0); + String txt = source.substring(n.getStartPosition(), n.getStartPosition() + n.getLength()); + return txt + .replaceAll(" *\n *\\* *\n", "\n\n") + .replaceAll(" *\n *\\* +", "\n"); + } + private static String evaluateTemplate(final String templateName, final Object model) throws MojoExecutionException { try (InputStream templateStream = UpdateReadmeMojo.class.getClassLoader().getResourceAsStream(templateName)) { String template = PackageHelper.loadText(templateStream); diff --git a/tooling/maven/camel-package-maven-plugin/src/main/resources/annotation-options.mvel b/tooling/maven/camel-package-maven-plugin/src/main/resources/annotation-options.mvel new file mode 100644 index 0000000..96fdf53 --- /dev/null +++ b/tooling/maven/camel-package-maven-plugin/src/main/resources/annotation-options.mvel @@ -0,0 +1,9 @@ +@if{!options.isEmpty()} +[width="100%",cols="10%,10%,10%,10%,60%",options="header",] +|=== +| Parameter name | Type | Required | Default value | Info +@foreach{row : sortedOptions} +| @{row.name} | @{row.type} | @if{!row.optional}✓@end{} | @if{row.defaultValue != null}${row.defaultValue}@end{} @{row.description.?contains("\n") ? "a" : ""}| @{util.escape(row.description)} +@end{} +|=== +@end{}