This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit f2a92b6a6732cdc8c988939e1ad838cd19405c95
Author: Jan Bednář <m...@janbednar.eu>
AuthorDate: Fri Jul 5 11:46:22 2019 +0200

    CAMEL-13628: add date to FileEvent
---
 .../src/main/docs/file-watch-component.adoc        | 880 +--------------------
 .../component/file/watch/FileWatchConsumer.java    |  41 +-
 .../component/file/watch/constants/FileEvent.java  |  14 +-
 3 files changed, 40 insertions(+), 895 deletions(-)

diff --git 
a/components/camel-file-watch/src/main/docs/file-watch-component.adoc 
b/components/camel-file-watch/src/main/docs/file-watch-component.adoc
index 62d590c..5117873 100644
--- a/components/camel-file-watch/src/main/docs/file-watch-component.adoc
+++ b/components/camel-file-watch/src/main/docs/file-watch-component.adoc
@@ -90,130 +90,18 @@ The component supports 3 options, which are listed below.
 |===
 // spring-boot-auto-configure options: END
 
-=== Move and Delete operations
-
-Any move or delete operations is executed after (post command) the
-routing has completed; so during processing of the `Exchange` the file
-is still located in the inbox folder.
-
-Lets illustrate this with an example:
+=== TODO
 
 [source,java]
 ----
-from("file://inbox?move=.done").to("bean:handleOrder");
-----
-
-When a file is dropped in the `inbox` folder, the file consumer notices
-this and creates a new `FileExchange` that is routed to the
-`handleOrder` bean. The bean then processes the `File` object. At this
-point in time the file is still located in the `inbox` folder. After the
-bean completes, and thus the route is completed, the file consumer will
-perform the move operation and move the file to the `.done` sub-folder.
-
-The *move* and the *preMove* options are considered as a directory name
-(though if you use an expression such as <<file-language,File Language>>, or 
<<simple-language,Simple>> then the result of the expression
-evaluation is the file name to be used - eg if you set
-
-[source]
-----
-move=../backup/copy-of-${file:name}
+TODO
 ----
 
-then that's using the <<file-language,File Language>> which we
-use return the file name to be used), which can be either relative or
-absolute. If relative, the directory is created as a sub-folder from
-within the folder where the file was consumed.
-
-By default, Camel will move consumed files to the `.camel` sub-folder
-relative to the directory where the file was consumed.
-
-If you want to delete the file after processing, the route should be:
-
-[source,java]
-----
-from("file://inobox?delete=true").to("bean:handleOrder");
-----
-
-We have introduced a *pre* move operation to move files *before* they
-are processed. This allows you to mark which files have been scanned as
-they are moved to this sub folder before being processed.
-
-[source,java]
-----
-from("file://inbox?preMove=inprogress").to("bean:handleOrder");
-----
-
-You can combine the *pre* move and the regular move:
-
-[source,java]
-----
-from("file://inbox?preMove=inprogress&move=.done").to("bean:handleOrder");
-----
-
-So in this situation, the file is in the `inprogress` folder when being
-processed and after it's processed, it's moved to the `.done` folder.
-
-=== Fine grained control over Move and PreMove option
-
-The *move* and *preMove* options
-are Expression-based, so we have the full power of
-the <<file-language,File Language>> to do advanced configuration
-of the directory and name pattern. +
- Camel will, in fact, internally convert the directory name you enter
-into a <<file-language,File Language>> expression. So when we
-enter `move=.done` Camel will convert this into:
-`${``file:parent``}/.done/${``file:onlyname`}. This is only done if
-Camel detects that you have not provided a $\{ } in the option value
-yourself. So when you enter a $\{ } Camel will *not* convert it and thus
-you have the full power.
-
-So if we want to move the file into a backup folder with today's date as
-the pattern, we can do:
-
-[source]
-----
-move=backup/${date:now:yyyyMMdd}/${file:name}
-----
-
-=== About moveFailed
-
-The `moveFailed` option allows you to move files that *could not* be
-processed succesfully to another location such as a error folder of your
-choice. For example to move the files in an error folder with a
-timestamp you can use
-`moveFailed=/error/${``file:name.noext``}-${date:now:yyyyMMddHHmmssSSS}.${``file:ext`}.
-
-See more examples at <<file-language,File Language>>
-
 === Message Headers
 
 The following headers are supported by this component:
 
-==== File producer only
-
-[width="100%",cols="10%,90%",options="header",]
-|===
-|Header |Description
-
-|`CamelFileName` |Specifies the name of the file to write (relative to the 
endpoint
-directory). This name can be a `String`; a `String` with a
-<<file-language,File Language>> or <<simple-language,Simple>>
-expression; or an Expression object. If it's
-`null` then Camel will auto-generate a filename based on the message
-unique ID.
-
-|`CamelFileNameProduced` |The actual absolute filepath (path + name) for the 
output file that was
-written. This header is set by Camel and its purpose is providing
-end-users with the name of the file that was written.
-
-|`CamelOverruleFileName` |*Camel 2.11:* Is used for overruling `CamelFileName` 
header and use the
-value instead (but only once, as the producer will remove this header
-after writing the file). The value can be only be a String. Notice that
-if the option `fileName` has been configured, then this is still being
-evaluated.
-|===
-
-==== File consumer only
+==== File Watch consumer only
 
 [width="100%",cols="10%,90%",options="header",]
 |===
@@ -246,603 +134,8 @@ relative filename. For absolute files this is the 
absolute path.
 *Camel 2.10.3 and older* the type is `Date`.
 |===
 
-=== Batch Consumer
-
-This component implements the Batch Consumer.
-
-=== Exchange Properties, file consumer only
-
-As the file consumer implements the `BatchConsumer` it supports batching
-the files it polls. By batching we mean that Camel will add the
-following additional properties to the Exchange, so
-you know the number of files polled, the current index, and whether the
-batch is already completed.
-
-[width="100%",cols="10%,90%",options="header",]
-|===
-|Property |Description
-
-|`CamelBatchSize` |The total number of files that was polled in this batch.
-
-|`CamelBatchIndex` |The current index of the batch. Starts from 0.
-
-|`CamelBatchComplete` |A `boolean` value indicating the last Exchange in
-the batch. Is only `true` for the last entry.
-|===
-
-This allows you for instance to know how many files exist in this batch
-and for instance let the Aggregator2 aggregate
-this number of files.
-
-=== Using charset
-
-*Available as of Camel 2.9.3* +
- The charset option allows for configuring an encoding of the files on
-both the consumer and producer endpoints. For example if you read utf-8
-files, and want to convert the files to iso-8859-1, you can do:
-
-[source,java]
-----
-from("file:inbox?charset=utf-8")
-  .to("file:outbox?charset=iso-8859-1")
-----
-
-You can also use the `convertBodyTo` in the route. In the example below
-we have still input files in utf-8 format, but we want to convert the
-file content to a byte array in iso-8859-1 format. And then let a bean
-process the data. Before writing the content to the outbox folder using
-the current charset.
-
-[source,java]
-----
-from("file:inbox?charset=utf-8")
-  .convertBodyTo(byte[].class, "iso-8859-1")
-  .to("bean:myBean")
-  .to("file:outbox");
-----
-
-If you omit the charset on the consumer endpoint, then Camel does not
-know the charset of the file, and would by default use "UTF-8". However
-you can configure a JVM system property to override and use a different
-default encoding with the key `org.apache.camel.default.charset`.
-
-In the example below this could be a problem if the files is not in
-UTF-8 encoding, which would be the default encoding for read the
-files. +
- In this example when writing the files, the content has already been
-converted to a byte array, and thus would write the content directly as
-is (without any further encodings).
-
-[source,java]
-----
-from("file:inbox")
-  .convertBodyTo(byte[].class, "iso-8859-1")
-  .to("bean:myBean")
-  .to("file:outbox");
-----
-
-You can also override and control the encoding dynamic when writing
-files, by setting a property on the exchange with the key
-`Exchange.CHARSET_NAME`. For example in the route below we set the
-property with a value from a message header.
-
-[source,java]
-----
-from("file:inbox")
-  .convertBodyTo(byte[].class, "iso-8859-1")
-  .to("bean:myBean")
-  .setProperty(Exchange.CHARSET_NAME, header("someCharsetHeader"))
-  .to("file:outbox");
-----
-
-We suggest to keep things simpler, so if you pickup files with the same
-encoding, and want to write the files in a specific encoding, then favor
-to use the `charset` option on the endpoints.
-
-Notice that if you have explicit configured a `charset` option on the
-endpoint, then that configuration is used, regardless of the
-`Exchange.CHARSET_NAME` property.
-
-If you have some issues then you can enable DEBUG logging on
-`org.apache.camel.component.file`, and Camel logs when it reads/write a
-file using a specific charset. +
- For example the route below will log the following:
-
-[source,java]
-----
-from("file:inbox?charset=utf-8")
-  .to("file:outbox?charset=iso-8859-1")
-----
-
-And the logs:
-
-[source]
-----------------------------------------------------------------------------------------------------------------------------------------------
-DEBUG GenericFileConverter           - Read file 
/Users/davsclaus/workspace/camel/camel-core/target/charset/input/input.txt with 
charset utf-8
-DEBUG FileOperations                 - Using Reader to write file: 
target/charset/output.txt with charset: iso-8859-1
-----------------------------------------------------------------------------------------------------------------------------------------------
-
-=== Common gotchas with folder and filenames
-
-When Camel is producing files (writing files) there are a few gotchas
-affecting how to set a filename of your choice. By default, Camel will
-use the message ID as the filename, and since the message ID is normally
-a unique generated ID, you will end up with filenames such as:
-`ID-MACHINENAME-2443-1211718892437-1-0`. If such a filename is not
-desired, then you must provide a filename in the `CamelFileName` message
-header. The constant, `Exchange.FILE_NAME`, can also be used.
-
-The sample code below produces files using the message ID as the
-filename:
-
-[source,java]
-----
-from("direct:report").to("file:target/reports");
-----
-
-To use `report.txt` as the filename you have to do:
-
-[source,java]
-----
-from("direct:report").setHeader(Exchange.FILE_NAME, 
constant("report.txt")).to( "file:target/reports");
-----
-
-... the same as above, but with `CamelFileName`:
-
-[source,java]
-----
-from("direct:report").setHeader("CamelFileName", constant("report.txt")).to( 
"file:target/reports");
-----
-
-And a syntax where we set the filename on the endpoint with the
-*fileName* URI option.
-
-[source,java]
-----
-from("direct:report").to("file:target/reports/?fileName=report.txt");
-----
-
-=== Filename Expression
-
-Filename can be set either using the *expression* option or as a
-string-based <<file-language,File Language>> expression in the
-`CamelFileName` header. See the <<file-language,File Language>>
-for syntax and samples.
-
-[[File2-Consumingfilesfromfolderswhereothersdropfilesdirectly]]
-=== Consuming files from folders where others drop files directly
-
-Beware if you consume files from a folder where other applications write
-files to directly. Take a look at the different readLock options to see
-what suits your use cases. The best approach is however to write to
-another folder and after the write move the file in the drop folder.
-However if you write files directly to the drop folder then the option
-changed could better detect whether a file is currently being
-written/copied as it uses a file changed algorithm to see whether the
-file size / modification changes over a period of time. The other
-readLock options rely on Java File API that sadly is not always very
-good at detecting this. You may also want to look at the doneFileName
-option, which uses a marker file (done file) to signal when a file is
-done and ready to be consumed.
-
-=== Using done files
-
-*Available as of Camel 2.6*
-
-See also section _writing done files_ below.
-
-If you want only to consume files when a done file exists, then you can
-use the `doneFileName` option on the endpoint.
-
-[source,java]
-----
-from("file:bar?doneFileName=done");
-----
-
-Will only consume files from the bar folder, if a done _file_ exists in
-the same directory as the target files. Camel will automatically delete
-the _done file_ when it's done consuming the files. From Camel *2.9.3*
-onwards Camel will not automatically delete the _done file_ if
-`noop=true` is configured.
-
-However it is more common to have one _done file_ per target file. This
-means there is a 1:1 correlation. To do this you must use dynamic
-placeholders in the `doneFileName` option. Currently Camel supports the
-following two dynamic tokens: `file:name` and `file:name.noext` which
-must be enclosed in $\{ }. The consumer only supports the static part of
-the _done file_ name as either prefix or suffix (not both).
-
-[source,java]
-----
-from("file:bar?doneFileName=${file:name}.done");
-----
-
-In this example only files will be polled if there exists a done file
-with the name _file name_.done. For example
-
-* `hello.txt` - is the file to be consumed
-* `hello.txt.done` - is the associated done file
-
-You can also use a prefix for the done file, such as:
-
-[source,java]
-----
-from("file:bar?doneFileName=ready-${file:name}");
-----
-
-* `hello.txt` - is the file to be consumed
-* `ready-hello.txt` - is the associated done file
-
-=== Writing done files
-
-*Available as of Camel 2.6*
-
-After you have written a file you may want to write an additional _done_
-_file_ as a kind of marker, to indicate to others that the file is
-finished and has been written. To do that you can use the `doneFileName`
-option on the file producer endpoint.
-
-[source,java]
-----
-.to("file:bar?doneFileName=done");
-----
-
-Will simply create a file named `done` in the same directory as the
-target file.
-
-However it is more common to have one done file per target file. This
-means there is a 1:1 correlation. To do this you must use dynamic
-placeholders in the `doneFileName` option. Currently Camel supports the
-following two dynamic tokens: `file:name` and `file:name.noext` which
-must be enclosed in $\{ }.
-
-[source,java]
-----
-.to("file:bar?doneFileName=done-${file:name}");
-----
-
-Will for example create a file named `done-foo.txt` if the target file
-was `foo.txt` in the same directory as the target file.
-
-[source,java]
-----
-.to("file:bar?doneFileName=${file:name}.done");
-----
-
-Will for example create a file named `foo.txt.done` if the target file
-was `foo.txt` in the same directory as the target file.
-
-[source,java]
-----
-.to("file:bar?doneFileName=${file:name.noext}.done");
-----
-
-Will for example create a file named `foo.done` if the target file was
-`foo.txt` in the same directory as the target file.
-
-=== Samples
-
-#=== Read from a directory and write to another directory
-
-[source,java]
-----
-from("file://inputdir/?delete=true").to("file://outputdir")
-----
-
-==== Read from a directory and write to another directory using a overrule 
dynamic name
-
-[source,java]
-----
-from("file://inputdir/?delete=true").to("file://outputdir?overruleFile=copy-of-${file:name}")
-----
-
-Listen on a directory and create a message for each file dropped there.
-Copy the contents to the `outputdir` and delete the file in the
-`inputdir`.
-
-==== Reading recursively from a directory and writing to another
-
-[source,java]
-----
-from("file://inputdir/?recursive=true&delete=true").to("file://outputdir")
-----
-
-Listen on a directory and create a message for each file dropped there.
-Copy the contents to the `outputdir` and delete the file in the
-`inputdir`. Will scan recursively into sub-directories. Will lay out the
-files in the same directory structure in the `outputdir` as the
-`inputdir`, including any sub-directories.
-
-[source]
-----
-inputdir/foo.txt
-inputdir/sub/bar.txt
-----
-
-Will result in the following output layout:
-
-[source]
-----
-outputdir/foo.txt
-outputdir/sub/bar.txt
-----
-
-[[File2-Usingflatten]]
-=== Using flatten
-
-If you want to store the files in the outputdir directory in the same
-directory, disregarding the source directory layout (e.g. to flatten out
-the path), you just add the `flatten=true` option on the file producer
-side:
-
-[source,java]
-----
-from("file://inputdir/?recursive=true&delete=true").to("file://outputdir?flatten=true")
-----
-
-Will result in the following output layout:
-
-[source]
-----
-outputdir/foo.txt
-outputdir/bar.txt
-----
-
-=== Reading from a directory and the default move operation
-
-Camel will by default move any processed file into a `.camel`
-subdirectory in the directory the file was consumed from.
-
-[source,java]
-----
-from("file://inputdir/?recursive=true&delete=true").to("file://outputdir")
-----
-
-Affects the layout as follows: +
- *before*
-
-[source]
-----
-inputdir/foo.txt
-inputdir/sub/bar.txt
-----
-
-*after*
-
-[source]
-----
-inputdir/.camel/foo.txt
-inputdir/sub/.camel/bar.txt
-outputdir/foo.txt
-outputdir/sub/bar.txt
-----
-
-=== Read from a directory and process the message in java
-
-[source,java]
-----
-from("file://inputdir/").process(new Processor() {
-  public void process(Exchange exchange) throws Exception {
-    Object body = exchange.getIn().getBody();
-    // do some business logic with the input body
-  }
-});
-----
-
-The body will be a `File` object that points to the file that was just
-dropped into the `inputdir` directory.
-
-=== Writing to files
-
-Camel is of course also able to write files, i.e. produce files. In the
-sample below we receive some reports on the SEDA queue that we process
-before they are being written to a directory.
-
-==== Write to subdirectory using `Exchange.FILE_NAME`
-
-Using a single route, it is possible to write a file to any number of
-subdirectories. If you have a route setup as such:
-
-[source,xml]
-----
-<route>
-  <from uri="bean:myBean"/>
-  <to uri="file:/rootDirectory"/>
-</route>
-----
-
-You can have `myBean` set the header `Exchange.FILE_NAME` to values such
-as:
-
-[source]
-----
-Exchange.FILE_NAME = hello.txt => /rootDirectory/hello.txt
-Exchange.FILE_NAME = foo/bye.txt => /rootDirectory/foo/bye.txt
-----
-
-This allows you to have a single route to write files to multiple
-destinations.
-
-==== Writing file through the temporary directory relative to the final 
destination
-
-Sometime you need to temporarily write the files to some directory
-relative to the destination directory. Such situation usually happens
-when some external process with limited filtering capabilities is
-reading from the directory you are writing to. In the example below
-files will be written to the  `/var/myapp/filesInProgress` directory and
-after data transfer is done, they will be atomically moved to
-the` /var/myapp/finalDirectory `directory.
-
-[source,java]
-----
-from("direct:start").
-  to("file:///var/myapp/finalDirectory?tempPrefix=/../filesInProgress/");
-----
-
-=== Using expression for filenames
-
-In this sample we want to move consumed files to a backup folder using
-today's date as a sub-folder name:
-
-[source,java]
-----
-from("file://inbox?move=backup/${date:now:yyyyMMdd}/${file:name}").to("...");
-----
-
-See <<file-language,File Language>> for more samples.
-
-=== Avoiding reading the same file more than once (idempotent consumer)
-
-Camel supports Idempotent Consumer
-directly within the component so it will skip already processed files.
-This feature can be enabled by setting the `idempotent=true` option.
-
-[source,java]
-----
-from("file://inbox?idempotent=true").to("...");
-----
-
-Camel uses the absolute file name as the idempotent key, to detect
-duplicate files. From *Camel 2.11* onwards you can customize this key by
-using an expression in the idempotentKey option. For example to use both
-the name and the file size as the key
-
-[source,xml]
-----
-<route>
-  <from 
uri="file://inbox?idempotent=true&amp;idempotentKey=${file:name}-${file:size}"/>
-  <to uri="bean:processInbox"/>
-</route>
-----
-
-By default Camel uses a in memory based store for keeping track of
-consumed files, it uses a least recently used cache holding up to 1000
-entries. You can plugin your own implementation of this store by using
-the `idempotentRepository` option using the `#` sign in the value to
-indicate it's a referring to a bean in the Registry
-with the specified `id`.
-
-[source,xml]
-----
- <!-- define our store as a plain spring bean -->
- <bean id="myStore" class="com.mycompany.MyIdempotentStore"/>
-
-<route>
-  <from uri="file://inbox?idempotent=true&amp;idempotentRepository=#myStore"/>
-  <to uri="bean:processInbox"/>
-</route>
-----
-
-Camel will log at `DEBUG` level if it skips a file because it has been
-consumed before:
-
-[source]
-----
-DEBUG FileConsumer is idempotent and the file has been consumed before. Will 
skip this file: target\idempotent\report.txt
-----
-
-=== Using a file based idempotent repository
-
-In this section we will use the file based idempotent repository
-`org.apache.camel.processor.idempotent.FileIdempotentRepository` instead
-of the in-memory based that is used as default. +
- This repository uses a 1st level cache to avoid reading the file
-repository. It will only use the file repository to store the content of
-the 1st level cache. Thereby the repository can survive server restarts.
-It will load the content of the file into the 1st level cache upon
-startup. The file structure is very simple as it stores the key in
-separate lines in the file. By default, the file store has a size limit
-of 1mb. When the file grows larger Camel will truncate the file store,
-rebuilding the content by flushing the 1st level cache into a fresh
-empty file.
-
-We configure our repository using Spring XML creating our file
-idempotent repository and define our file consumer to use our repository
-with the `idempotentRepository` using `#` sign to indicate
-Registry lookup:
-
-=== Using a JPA based idempotent repository
-
-In this section we will use the JPA based idempotent repository instead
-of the in-memory based that is used as default.
-
-First we need a persistence-unit in `META-INF/persistence.xml` where we
-need to use the class
-`org.apache.camel.processor.idempotent.jpa.MessageProcessed` as model.
-
-[source,xml]
-----
-<persistence-unit name="idempotentDb" transaction-type="RESOURCE_LOCAL">
-  <class>org.apache.camel.processor.idempotent.jpa.MessageProcessed</class>
-
-  <properties>
-    <property name="openjpa.ConnectionURL" 
value="jdbc:derby:target/idempotentTest;create=true"/>
-    <property name="openjpa.ConnectionDriverName" 
value="org.apache.derby.jdbc.EmbeddedDriver"/>
-    <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/>
-    <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO"/>
-    <property name="openjpa.Multithreaded" value="true"/>
-  </properties>
-</persistence-unit>
-----
-
-Next, we can create our JPA idempotent repository in the spring
-XML file as well:
-
-[source,xml]
-----
-<!-- we define our jpa based idempotent repository we want to use in the file 
consumer -->
-<bean id="jpaStore" 
class="org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository">
-    <!-- Here we refer to the entityManagerFactory -->
-    <constructor-arg index="0" ref="entityManagerFactory"/>
-    <!-- This 2nd parameter is the name  (= a category name).
-         You can have different repositories with different names -->
-    <constructor-arg index="1" value="FileConsumer"/>
-</bean>
-----
-
-And yes then we just need to refer to the *jpaStore* bean in the file
-consumer endpoint using the `idempotentRepository` using the `#` syntax
-option:
-
-[source,xml]
-----
-<route>
-  <from uri="file://inbox?idempotent=true&amp;idempotentRepository=#jpaStore"/>
-  <to uri="bean:processInbox"/>
-</route>
-----
-
-=== Filter using org.apache.camel.component.file.GenericFileFilter
-
-Camel supports pluggable filtering strategies. You can then configure
-the endpoint with such a filter to skip certain files being processed.
-
-In the sample we have built our own filter that skips files starting
-with `skip` in the filename:
-
-And then we can configure our route using the *filter* attribute to
-reference our filter (using `#` notation) that we have defined in the
-spring XML file:
-
-[source,xml]
-----
-<!-- define our filter as a plain spring bean -->
-<bean id="myFilter" class="com.mycompany.MyFileFilter"/>
-
-<route>
-  <from uri="file://inbox?filter=#myFilter"/>
-  <to uri="bean:processInbox"/>
-</route>
-----
-
 === Filtering using ANT path matcher
 
-The ANT path matcher is shipped out-of-the-box in the *camel-spring*
-jar. So you need to depend on *camel-spring* if you are using Maven. +
- The reasons is that we leverage Spring's
-http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/util/AntPathMatcher.html[AntPathMatcher]
-to do the actual matching.
-
 The file paths is matched with the following rules:
 
 * `?` matches one character
@@ -856,162 +149,8 @@ See the URI options above for more information.
 
 The sample below demonstrates how to use it:
 
-==== Sorting using Comparator
-
-Camel supports pluggable sorting strategies. This strategy it to use the
-build in `java.util.Comparator` in Java. You can then configure the
-endpoint with such a comparator and have Camel sort the files before
-being processed.
-
-In the sample we have built our own comparator that just sorts by file
-name:
-
-And then we can configure our route using the *sorter* option to
-reference to our sorter (`mySorter`) we have defined in the spring XML
-file:
-
-[source,xml]
-----
- <!-- define our sorter as a plain spring bean -->
- <bean id="mySorter" class="com.mycompany.MyFileSorter"/>
-
-<route>
-  <from uri="file://inbox?sorter=#mySorter"/>
-  <to uri="bean:processInbox"/>
-</route>
-----
-
-TIP: *URI options can reference beans using the # syntax*
-In the Spring DSL route above notice that we can refer to beans in the
-Registry by prefixing the id with `#`. So writing
-`sorter=#mySorter`, will instruct Camel to go look in the
-Registry for a bean with the ID, `mySorter`.
-
-==== Sorting using sortBy
-
-Camel supports pluggable sorting strategies. This strategy it to use the
-<<file-language,File Language>> to configure the sorting. The
-`sortBy` option is configured as follows:
-
-[source]
-----
-sortBy=group 1;group 2;group 3;...
-----
-
-Where each group is separated with semi colon. In the simple situations
-you just use one group, so a simple example could be:
-
-[source]
-----
-sortBy=file:name
-----
-
-This will sort by file name, you can reverse the order by prefixing
-`reverse:` to the group, so the sorting is now Z..A:
-
-[source]
-----
-sortBy=reverse:file:name
-----
-
-As we have the full power of <<file-language,File Language>> we
-can use some of the other parameters, so if we want to sort by file size
-we do:
-
-[source]
-----
-sortBy=file:length
-----
-
-You can configure to ignore the case, using `ignoreCase:` for string
-comparison, so if you want to use file name sorting but to ignore the
-case then we do:
-
-[source]
-----
-sortBy=ignoreCase:file:name
-----
-
-You can combine ignore case and reverse, however reverse must be
-specified first:
-
-[source]
-----
-sortBy=reverse:ignoreCase:file:name
-----
-
-In the sample below we want to sort by last modified file, so we do:
-
-[source]
-----
-sortBy=file:modified
-----
-
-And then we want to group by name as a 2nd option so files with same
-modifcation is sorted by name:
-
-[source]
-----
-sortBy=file:modified;file:name
-----
-
-Now there is an issue here, can you spot it? Well the modified timestamp
-of the file is too fine as it will be in milliseconds, but what if we
-want to sort by date only and then subgroup by name? +
- Well as we have the true power of <<file-language,File Language>> we can use 
its date command that supports patterns. So this
-can be solved as:
-
-[source]
-----
-sortBy=date:file:yyyyMMdd;file:name
-----
-
-Yeah, that is pretty powerful, oh by the way you can also use reverse
-per group, so we could reverse the file names:
-
-[source]
-----
-sortBy=date:file:yyyyMMdd;reverse:file:name
-----
-
-=== Using GenericFileProcessStrategy
-
-The option `processStrategy` can be used to use a custom
-`GenericFileProcessStrategy` that allows you to implement your own
-_begin_, _commit_ and _rollback_ logic. +
- For instance lets assume a system writes a file in a folder you should
-consume. But you should not start consuming the file before another
-_ready_ file has been written as well.
-
-So by implementing our own `GenericFileProcessStrategy` we can implement
-this as:
-
-* In the `begin()` method we can test whether the special _ready_ file
-exists. The begin method returns a `boolean` to indicate if we can
-consume the file or not.
-* In the `abort()` method (Camel 2.10) special logic can be executed in
-case the `begin` operation returned `false`, for example to cleanup
-resources etc.
-* in the `commit()` method we can move the actual file and also delete
-the _ready_ file.
-
-=== Using filter
-
-The `filter` option allows you to implement a custom filter in Java code
-by implementing the `org.apache.camel.component.file.GenericFileFilter`
-interface. This interface has an `accept` method that returns a boolean.
-Return `true` to include the file, and `false` to skip the file. From
-Camel 2.10 onwards, there is a `isDirectory` method on `GenericFile`
-whether the file is a directory. This allows you to filter unwanted
-directories, to avoid traversing down unwanted directories.
-
-For example to skip any directories which starts with `"skip"` in the
-name, can be implemented as follows:
-
 === Using consumer.bridgeErrorHandler
 
-*Available as of Camel 2.10*
-
 If you want to use the Camel Error Handler to
 deal with any exception occurring in the file consumer, then you can
 enable the `consumer.bridgeErrorHandler` option as shown below:
@@ -1027,7 +166,7 @@ onException(IOException.class)
 
 // this is the file route that pickup files, notice how we bridge the consumer 
to use the Camel routing error handler
 // the exclusiveReadLockStrategy is only configured because this is from an 
unit test, so we use that to simulate exceptions
-from("file:target/nospace?consumer.bridgeErrorHandler=true")
+from("file-watch:target/nospace?consumer.bridgeErrorHandler=true")
     .convertBodyTo(String.class)
     .to("mock:result");
 ----
@@ -1041,14 +180,3 @@ interceptors, OnCompletions
 does *not* apply. The Exchange is processed directly
 by the Camel Error Handler, and does not allow
 prior actions such as interceptors, onCompletion to take action.
-
-=== Debug logging
-
-This component has log level *TRACE* that can be helpful if you have
-problems.
-
-=== See Also
-
-* <<file-language,File Language>>
-* FTP
-* Polling Consumer
diff --git 
a/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchConsumer.java
 
b/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchConsumer.java
index 34bf7ac..f30706b 100644
--- 
a/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchConsumer.java
+++ 
b/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchConsumer.java
@@ -17,6 +17,7 @@
 package org.apache.camel.component.file.watch;
 
 import java.io.File;
+import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -78,9 +79,9 @@ public class FileWatchConsumer extends DefaultConsumer {
         }
 
         DirectoryWatcher.Builder watcherBuilder = DirectoryWatcher.builder()
-        .path(this.baseDirectory)
-        .logger(log)
-        .listener(new FileWatchDirectoryChangeListener());
+            .path(this.baseDirectory)
+            .logger(log)
+            .listener(new FileWatchDirectoryChangeListener());
 
         if (!System.getProperty("os.name").toLowerCase().contains("mac")) {
             // If not macOS, use FileSystem WatchService. io.methvin.watcher 
uses by default WatchService associated to default FileSystem.
@@ -97,9 +98,9 @@ public class FileWatchConsumer extends DefaultConsumer {
         this.watcher = watcherBuilder.build();
 
         watchDirExecutorService = 
getEndpoint().getCamelContext().getExecutorServiceManager()
-        .newFixedThreadPool(this, "CamelFileWatchService", 
getEndpoint().getPollThreads());
+            .newFixedThreadPool(this, "CamelFileWatchService", 
getEndpoint().getPollThreads());
         pollExecutorService = 
getEndpoint().getCamelContext().getExecutorServiceManager()
-        .newFixedThreadPool(this, "CamelFileWatchPoll", 
getEndpoint().getConcurrentConsumers());
+            .newFixedThreadPool(this, "CamelFileWatchPoll", 
getEndpoint().getConcurrentConsumers());
 
         for (int i = 0; i < getEndpoint().getPollThreads(); i++) {
             this.watcher.watchAsync(watchDirExecutorService);
@@ -129,17 +130,24 @@ public class FileWatchConsumer extends DefaultConsumer {
 
     private Exchange prepareExchange(FileEvent event) {
         Exchange exchange = getEndpoint().createExchange();
-        exchange.setFromEndpoint(getEndpoint());
         File file = event.getEventPath().toFile();
         Message message = exchange.getIn();
         message.setBody(file);
         message.setHeader(FileWatchComponent.EVENT_TYPE_HEADER, 
event.getEventType());
-        message.setHeader(Exchange.FILE_NAME, 
PathUtils.normalizeToString(baseDirectory.relativize(event.getEventPath())));
-        message.setHeader("CamelFileRelativePath", 
message.getHeader(Exchange.FILE_NAME));
-        message.setHeader("CamelFileAbsolutePath", 
PathUtils.normalizeToString(event.getEventPath().toAbsolutePath()));
+        message.setHeader(Exchange.FILE_NAME_ONLY, 
event.getEventPath().getFileName().toString());
         message.setHeader("CamelFileAbsolute", true);
+
+        final String absolutePath = 
PathUtils.normalizeToString(event.getEventPath().toAbsolutePath());
+        message.setHeader("CamelFileAbsolutePath", absolutePath);
+        message.setHeader(Exchange.FILE_PATH, absolutePath);
+
+        final String relativePath = 
PathUtils.normalizeToString(baseDirectory.relativize(event.getEventPath()));
+        message.setHeader(Exchange.FILE_NAME, relativePath);
+        message.setHeader("CamelFileRelativePath", relativePath);
+        message.setHeader(Exchange.FILE_NAME_CONSUMED, relativePath);
+
         message.setHeader(Exchange.FILE_PARENT, 
PathUtils.normalizeToString(event.getEventPath().getParent().toAbsolutePath()));
-        message.setHeader(Exchange.FILE_NAME_ONLY, 
event.getEventPath().getFileName().toString());
+        message.setHeader(Exchange.FILE_LAST_MODIFIED, event.getEventDate());
 
         return exchange;
     }
@@ -149,10 +157,17 @@ public class FileWatchConsumer extends DefaultConsumer {
             return false;
         }
 
-        if (!getEndpoint().isRecursive() && 
!Objects.equals(fileEvent.getEventPath().getParent(), this.baseDirectory)) {
-            // On some platforms (macOS) is WatchService always recursive,
+        if (!getEndpoint().isRecursive()) {
+            // On some platforms (eg macOS) is WatchService always recursive,
             // so we need to filter this out to make this component platform 
independent
-            return false;
+            try {
+                if (!Files.isSameFile(fileEvent.getEventPath().getParent(), 
this.baseDirectory)){
+                    return false;
+                }
+            } catch (IOException e) {
+                log.warn(String.format("Exception occurred during executing 
filter. Filtering file %s out.", fileEvent.getEventPath()), e);
+                return false;
+            }
         }
 
         String pattern = getEndpoint().getAntInclude();
diff --git 
a/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/constants/FileEvent.java
 
b/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/constants/FileEvent.java
index 3712087..ed263ec 100644
--- 
a/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/constants/FileEvent.java
+++ 
b/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/constants/FileEvent.java
@@ -17,12 +17,18 @@
 package org.apache.camel.component.file.watch.constants;
 
 import java.nio.file.Path;
+import java.util.Date;
 
 import io.methvin.watcher.DirectoryChangeEvent;
 
 public class FileEvent {
     private FileEventEnum eventType;
     private Path eventPath;
+    private Date eventDate;
+
+    private FileEvent() {
+        this.eventDate = new Date();
+    }
 
     public FileEvent(FileEventEnum eventType, Path eventPath) {
         this.eventType = eventType;
@@ -38,15 +44,11 @@ public class FileEvent {
         return eventType;
     }
 
-    public void setEventType(FileEventEnum eventType) {
-        this.eventType = eventType;
-    }
-
     public Path getEventPath() {
         return eventPath;
     }
 
-    public void setEventPath(Path eventPath) {
-        this.eventPath = eventPath;
+    public Date getEventDate() {
+        return this.eventDate;
     }
 }

Reply via email to