001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.model.dataformat; 018 019import java.util.List; 020import javax.xml.bind.annotation.XmlAccessType; 021import javax.xml.bind.annotation.XmlAccessorType; 022import javax.xml.bind.annotation.XmlAttribute; 023import javax.xml.bind.annotation.XmlElement; 024import javax.xml.bind.annotation.XmlRootElement; 025 026import org.apache.camel.CamelContext; 027import org.apache.camel.model.DataFormatDefinition; 028import org.apache.camel.spi.DataFormat; 029import org.apache.camel.spi.Metadata; 030import org.apache.camel.util.CamelContextHelper; 031import org.apache.camel.util.ObjectHelper; 032 033/** 034 * CSV data format 035 */ 036@Metadata(label = "dataformat,transformation", title = "CSV") 037@XmlRootElement(name = "csv") 038@XmlAccessorType(XmlAccessType.FIELD) 039public class CsvDataFormat extends DataFormatDefinition { 040 // Format options 041 @XmlAttribute 042 private String formatRef; 043 @XmlAttribute 044 private String formatName; 045 @XmlAttribute 046 private Boolean commentMarkerDisabled; 047 @XmlAttribute 048 private String commentMarker; 049 @XmlAttribute 050 private String delimiter; 051 @XmlAttribute 052 private Boolean escapeDisabled; 053 @XmlAttribute 054 private String escape; 055 @XmlAttribute 056 private Boolean headerDisabled; 057 @XmlElement 058 private List<String> header; 059 @XmlAttribute 060 private Boolean allowMissingColumnNames; 061 @XmlAttribute 062 private Boolean ignoreEmptyLines; 063 @XmlAttribute 064 private Boolean ignoreSurroundingSpaces; 065 @XmlAttribute 066 private Boolean nullStringDisabled; 067 @XmlAttribute 068 private String nullString; 069 @XmlAttribute 070 private Boolean quoteDisabled; 071 @XmlAttribute 072 private String quote; 073 @XmlAttribute 074 private String recordSeparatorDisabled; 075 @XmlAttribute 076 private String recordSeparator; 077 @XmlAttribute 078 private Boolean skipHeaderRecord; 079 080 // Unmarshall options 081 @XmlAttribute 082 private Boolean lazyLoad; 083 @XmlAttribute 084 private Boolean useMaps; 085 @XmlAttribute 086 private String recordConverterRef; 087 088 public CsvDataFormat() { 089 super("csv"); 090 } 091 092 public CsvDataFormat(String delimiter) { 093 this(); 094 setDelimiter(delimiter); 095 } 096 097 public CsvDataFormat(boolean lazyLoad) { 098 this(); 099 setLazyLoad(lazyLoad); 100 } 101 102 @Override 103 protected void configureDataFormat(DataFormat dataFormat, CamelContext camelContext) { 104 // Format options 105 if (ObjectHelper.isNotEmpty(formatRef)) { 106 Object format = CamelContextHelper.mandatoryLookup(camelContext, formatRef); 107 setProperty(camelContext, dataFormat, "format", format); 108 } else if (ObjectHelper.isNotEmpty(formatName)) { 109 setProperty(camelContext, dataFormat, "formatName", formatName); 110 } 111 if (commentMarkerDisabled != null) { 112 setProperty(camelContext, dataFormat, "commentMarkerDisabled", commentMarkerDisabled); 113 } 114 if (commentMarker != null) { 115 setProperty(camelContext, dataFormat, "commentMarker", singleChar(commentMarker, "commentMarker")); 116 } 117 if (delimiter != null) { 118 setProperty(camelContext, dataFormat, "delimiter", singleChar(delimiter, "delimiter")); 119 } 120 if (escapeDisabled != null) { 121 setProperty(camelContext, dataFormat, "escapeDisabled", escapeDisabled); 122 } 123 if (escape != null) { 124 setProperty(camelContext, dataFormat, "escape", singleChar(escape, "escape")); 125 } 126 if (headerDisabled != null) { 127 setProperty(camelContext, dataFormat, "headerDisabled", headerDisabled); 128 } 129 if (header != null && !header.isEmpty()) { 130 setProperty(camelContext, dataFormat, "header", header.toArray(new String[header.size()])); 131 } 132 if (allowMissingColumnNames != null) { 133 setProperty(camelContext, dataFormat, "allowMissingColumnNames", allowMissingColumnNames); 134 } 135 if (ignoreEmptyLines != null) { 136 setProperty(camelContext, dataFormat, "ignoreEmptyLines", ignoreEmptyLines); 137 } 138 if (ignoreSurroundingSpaces != null) { 139 setProperty(camelContext, dataFormat, "ignoreSurroundingSpaces", ignoreSurroundingSpaces); 140 } 141 if (nullStringDisabled != null) { 142 setProperty(camelContext, dataFormat, "nullStringDisabled", nullStringDisabled); 143 } 144 if (nullString != null) { 145 setProperty(camelContext, dataFormat, "nullString", nullString); 146 } 147 if (quoteDisabled != null) { 148 setProperty(camelContext, dataFormat, "quoteDisabled", quoteDisabled); 149 } 150 if (quote != null) { 151 setProperty(camelContext, dataFormat, "quote", singleChar(quote, "quote")); 152 } 153 if (recordSeparatorDisabled != null) { 154 setProperty(camelContext, dataFormat, "recordSeparatorDisabled", recordSeparatorDisabled); 155 } 156 if (recordSeparator != null) { 157 setProperty(camelContext, dataFormat, "recordSeparator", recordSeparator); 158 } 159 if (skipHeaderRecord != null) { 160 setProperty(camelContext, dataFormat, "skipHeaderRecord", skipHeaderRecord); 161 } 162 163 // Unmarshall options 164 if (lazyLoad != null) { 165 setProperty(camelContext, dataFormat, "lazyLoad", lazyLoad); 166 } 167 if (useMaps != null) { 168 setProperty(camelContext, dataFormat, "useMaps", useMaps); 169 } 170 if (ObjectHelper.isNotEmpty(recordConverterRef)) { 171 Object recordConverter = CamelContextHelper.mandatoryLookup(camelContext, recordConverterRef); 172 setProperty(camelContext, dataFormat, "recordConverter", recordConverter); 173 } 174 } 175 176 private static Character singleChar(String value, String attributeName) { 177 if (value.length() != 1) { 178 throw new IllegalArgumentException(String.format("The '%s' attribute must be exactly one character long.", attributeName)); 179 } 180 return value.charAt(0); 181 } 182 183 public String getFormatRef() { 184 return formatRef; 185 } 186 187 /** 188 * The reference format to use, it will be updated with the other format options, the default value is CSVFormat.DEFAULT 189 */ 190 public void setFormatRef(String formatRef) { 191 this.formatRef = formatRef; 192 } 193 194 public String getFormatName() { 195 return formatName; 196 } 197 198 /** 199 * The name of the format to use, the default value is CSVFormat.DEFAULT 200 */ 201 public void setFormatName(String formatName) { 202 this.formatName = formatName; 203 } 204 205 public Boolean getCommentMarkerDisabled() { 206 return commentMarkerDisabled; 207 } 208 209 /** 210 * Disables the comment marker of the reference format. 211 */ 212 public void setCommentMarkerDisabled(Boolean commentMarkerDisabled) { 213 this.commentMarkerDisabled = commentMarkerDisabled; 214 } 215 216 public String getCommentMarker() { 217 return commentMarker; 218 } 219 220 /** 221 * Sets the comment marker of the reference format. 222 */ 223 public void setCommentMarker(String commentMarker) { 224 this.commentMarker = commentMarker; 225 } 226 227 public String getDelimiter() { 228 return delimiter; 229 } 230 231 /** 232 * Sets the delimiter to use. 233 * <p/> 234 * The default value is , (comma) 235 */ 236 public void setDelimiter(String delimiter) { 237 this.delimiter = delimiter; 238 } 239 240 public Boolean getEscapeDisabled() { 241 return escapeDisabled; 242 } 243 244 /** 245 * Use for disabling using escape character 246 */ 247 public void setEscapeDisabled(Boolean escapeDisabled) { 248 this.escapeDisabled = escapeDisabled; 249 } 250 251 public String getEscape() { 252 return escape; 253 } 254 255 /** 256 * Sets the escape character to use 257 */ 258 public void setEscape(String escape) { 259 this.escape = escape; 260 } 261 262 /** 263 * Use for disabling headers 264 */ 265 public Boolean getHeaderDisabled() { 266 return headerDisabled; 267 } 268 269 public void setHeaderDisabled(Boolean headerDisabled) { 270 this.headerDisabled = headerDisabled; 271 } 272 273 public List<String> getHeader() { 274 return header; 275 } 276 277 /** 278 * To configure the CSV headers 279 */ 280 public void setHeader(List<String> header) { 281 this.header = header; 282 } 283 284 public Boolean getAllowMissingColumnNames() { 285 return allowMissingColumnNames; 286 } 287 288 /** 289 * Whether to allow missing column names. 290 */ 291 public void setAllowMissingColumnNames(Boolean allowMissingColumnNames) { 292 this.allowMissingColumnNames = allowMissingColumnNames; 293 } 294 295 public Boolean getIgnoreEmptyLines() { 296 return ignoreEmptyLines; 297 } 298 299 /** 300 * Whether to ignore empty lines. 301 */ 302 public void setIgnoreEmptyLines(Boolean ignoreEmptyLines) { 303 this.ignoreEmptyLines = ignoreEmptyLines; 304 } 305 306 public Boolean getIgnoreSurroundingSpaces() { 307 return ignoreSurroundingSpaces; 308 } 309 310 /** 311 * Whether to ignore surrounding spaces 312 */ 313 public void setIgnoreSurroundingSpaces(Boolean ignoreSurroundingSpaces) { 314 this.ignoreSurroundingSpaces = ignoreSurroundingSpaces; 315 } 316 317 public Boolean getNullStringDisabled() { 318 return nullStringDisabled; 319 } 320 321 /** 322 * Used to disable null strings 323 */ 324 public void setNullStringDisabled(Boolean nullStringDisabled) { 325 this.nullStringDisabled = nullStringDisabled; 326 } 327 328 public String getNullString() { 329 return nullString; 330 } 331 332 /** 333 * Sets the null string 334 */ 335 public void setNullString(String nullString) { 336 this.nullString = nullString; 337 } 338 339 public Boolean getQuoteDisabled() { 340 return quoteDisabled; 341 } 342 343 /** 344 * Used to disable quotes 345 */ 346 public void setQuoteDisabled(Boolean quoteDisabled) { 347 this.quoteDisabled = quoteDisabled; 348 } 349 350 public String getQuote() { 351 return quote; 352 } 353 354 /** 355 * Sets the quote which by default is " 356 */ 357 public void setQuote(String quote) { 358 this.quote = quote; 359 } 360 361 public String getRecordSeparatorDisabled() { 362 return recordSeparatorDisabled; 363 } 364 365 /** 366 * Used for disabling record separator 367 */ 368 public void setRecordSeparatorDisabled(String recordSeparatorDisabled) { 369 this.recordSeparatorDisabled = recordSeparatorDisabled; 370 } 371 372 public String getRecordSeparator() { 373 return recordSeparator; 374 } 375 376 /** 377 * Sets the record separator (aka new line) which by default is \r\n (CRLF) 378 */ 379 public void setRecordSeparator(String recordSeparator) { 380 this.recordSeparator = recordSeparator; 381 } 382 383 public Boolean getSkipHeaderRecord() { 384 return skipHeaderRecord; 385 } 386 387 /** 388 * Whether to skip the header record in the output 389 */ 390 public void setSkipHeaderRecord(Boolean skipHeaderRecord) { 391 this.skipHeaderRecord = skipHeaderRecord; 392 } 393 394 public Boolean getLazyLoad() { 395 return lazyLoad; 396 } 397 398 /** 399 * Whether the unmarshalling should produce an iterator that reads the lines on the fly or if all the lines must be read at one. 400 */ 401 public void setLazyLoad(Boolean lazyLoad) { 402 this.lazyLoad = lazyLoad; 403 } 404 405 public Boolean getUseMaps() { 406 return useMaps; 407 } 408 409 /** 410 * Whether the unmarshalling should produce maps for the lines values instead of lists. It requires to have header (either defined or collected). 411 */ 412 public void setUseMaps(Boolean useMaps) { 413 this.useMaps = useMaps; 414 } 415 416 public String getRecordConverterRef() { 417 return recordConverterRef; 418 } 419 420 /** 421 * Refers to a custom <tt>CsvRecordConverter</tt> to lookup from the registry to use. 422 */ 423 public void setRecordConverterRef(String recordConverterRef) { 424 this.recordConverterRef = recordConverterRef; 425 } 426 427}