fix #197 - mention triava as JCache implementation

Signed-off-by: Sebastian Hoß <1d6e1cf70ec6f9ab28d3ea4b27a49a77654d370e@shoss.de>

= memoization.java image:https://img.shields.io/badge/email-%40metio-brightgreen.svg?style=social&label=mail["Discuss on Google Groups", link="https://groups.google.com/forum/#!forum/metio"] image:https://img.shields.io/badge/irc-%23metio.wtf-brightgreen.svg?style=social&label=IRC["Chat on IRC", link="http://webchat.freenode.net/?channels=metio.wtf"]
Sebastian Hoß <http://seb.xn--ho-hia.de/[@sebhoss]>
:github-org: sebhoss
:project-name: memoization.java
:project-group: de.xn--ho-hia.memoization
:coverity-project: 8732
:codacy-project: 0ed810b7f2514f0ea1c8e86e97c803c4
:jdk-api: https://docs.oracle.com/javase/8/docs/api
:issue: https://github.com/sebhoss/memoization.java/issues
:toc:
:toc-placement: preamble

image:https://img.shields.io/badge/license-cc%20zero-000000.svg?style=flat-square["CC Zero", link="http://creativecommons.org/publicdomain/zero/1.0/"]
pass:[]
image:https://reposs.herokuapp.com/?path={github-org}/{project-name}&style=flat-square["Repository size"]
image:https://www.openhub.net/p/memoization-java/widgets/project_thin_badge?format=gif["Open Hub statistics", link="https://www.openhub.net/p/memoization-java"]

image:https://img.shields.io/travis/{github-org}/{project-name}/master.svg?style=flat-square["Build Status", link="https://travis-ci.org/{github-org}/{project-name}"]
image:https://img.shields.io/coveralls/{github-org}/{project-name}/master.svg?style=flat-square["Code Coverage", link="https://coveralls.io/github/{github-org}/{project-name}"]
image:https://img.shields.io/coverity/scan/{coverity-project}.svg?style=flat-square["Coverity Scan Result", link="https://scan.coverity.com/projects/{github-org}-memoization-java"]
image:https://img.shields.io/codacy/grade/{codacy-project}.svg?style=flat-square["Codacy Code Quality", link="https://www.codacy.com/app/mail_7/memoization-java"]
image:https://img.shields.io/badge/forkable-yes-brightgreen.svg?style=flat-square["Can this project be forked?", link="https://basicallydan.github.io/forkability/?u={github-org}&r={project-name}"]
image:https://img.shields.io/maintenance/yes/2017.svg?style=flat-square["Is this thing still maintained?"]
image:https://img.shields.io/bountysource/team/metio/activity.svg?style=flat-square["Bounties on open tickets", link="https://www.bountysource.com/teams/metio"]

_Java link:https://en.wikipedia.org/wiki/Memoization[memoization] library - trade space for time_

== Features

* Memoize calls to `Consumer`, `Function`, `Predicate`, `Supplier` and other functional interfaces in `java.util.function`
* Cache values using link:https://github.com/ben-manes/caffeine[Caffeine], link:https://github.com/google/guava/wiki/CachesExplained[Guava], link:https://jcp.org/en/jsr/detail?id=107[JCache] or any link:{jdk-api}/java/util/concurrent/ConcurrentMap.html[`ConcurrentMap`]
* Customize cache key calculation

.Coverage of `java.util.function`
|===
| | Caffeine | Guava | JCache | ConcurrentMap

| link:{jdk-api}/java/util/function/BiConsumer.html[BiConsumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/BiFunction.html[BiFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/BiPredicate.html[BiPredicate]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/BooleanSupplier.html[BooleanSupplier]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/Consumer.html[Consumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoubleBinaryOperator.html[DoubleBinaryOperator]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoubleConsumer.html[DoubleConsumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoubleFunction.html[DoubleFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoublePredicate.html[DoublePredicate]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoubleSupplier.html[DoubleSupplier]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoubleToIntFunction.html[DoubleToIntFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoubleToLongFunction.html[DoubleToLongFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoubleUnaryOperator.html[DoubleUnaryOperator]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/Function.html[Function]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntBinaryOperator.html[IntBinaryOperator]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntConsumer.html[IntConsumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntFunction.html[IntFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntPredicate.html[IntPredicate]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntSupplier.html[IntSupplier]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntToDoubleFunction.html[IntToDoubleFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntToLongFunction.html[IntToLongFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntUnaryOperator.html[IntUnaryOperator]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongBinaryOperator.html[LongBinaryOperator]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongConsumer.html[LongConsumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongFunction.html[LongFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongPredicate.html[LongPredicate]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongSupplier.html[LongSupplier]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongToDoubleFunction.html[LongToDoubleFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongToIntFunction.html[LongToIntFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongUnaryOperator.html[LongUnaryOperator]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ObjDoubleConsumer.html[ObjDoubleConsumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ObjIntConsumer.html[ObjIntConsumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ObjLongConsumer.html[ObjLongConsumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/Predicate.html[Predicate]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/Supplier.html[Supplier]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ToDoubleBiFunction.html[ToDoubleBiFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ToDoubleFunction.html[ToDoubleFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ToIntBiFunction.html[ToIntBiFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ToIntFunction.html[ToIntFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ToLongBiFunction.html[ToLongBiFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ToLongFunction.html[ToLongFunction]
| ✓
| ✓
| ✓
| ✓
|===

== Development Status

The Caffeine, Guava, JCache and `ConcurrentMap` based implementations cover all functional interfaces from `java.util.function`. Take a look at the link:https://github.com/sebhoss/memoization.java/issues[open tickets] for future ideas & ways to help out.

== Usage

Memoize any of the supported types by using the static factory methods supplied by:

* pass:[] `CaffeineMemoize` if you want to use link:https://github.com/ben-manes/caffeine[Caffeine] caches.
* pass:[] `GuavaMemoize` if you want to use link:https://github.com/google/guava/wiki/CachesExplained[Guava] caches.
* pass:[] `JCacheMemoize` if you want to use link:https://jcp.org/en/jsr/detail?id=107[JCache] (JSR107) caches.
* pass:[] `MapMemoize` if you want to use any link:{jdk-api}/java/util/concurrent/ConcurrentMap.html[`ConcurrentMap`] as cache.

=== Default cache w/ default cache keys

[source, java]
----
// memoize in Caffeine cache
Consumer<INPUT> consumer                 = ...;
Consumer<INPUT> memoizedConsumer         = CaffeineMemoize.consumer(consumer);

// memoize in Guava cache
Function<INPUT, OUTPUT> function         = ...;
Function<INPUT, OUTPUT> memoizedFunction = GuavaMemoize.function(function);

// memoize in JCache cache
Predicate<INPUT> predicate               = ...;
Predicate<INPUT> memoizedPredicate       = JCacheMemoize.predicate(predicate);

// memoize in ConcurrentMap
Supplier<OUTPUT> supplier                = ...;
Supplier<OUTPUT> memoizedSupplier        = MapMemoize.supplier(supplier);
----

=== Default cache w/ custom cache keys

[source, java]
----
// memoize in Caffeine cache
Consumer<INPUT> consumer                 = ...;
Function<INPUT, KEY> keyFunction         = ...;
Consumer<INPUT> memoizedConsumer         = CaffeineMemoize.consumer(consumer, keyFunction);

// memoize in Guava cache
Function<INPUT, OUTPUT> function         = ...;
Function<INPUT, KEY> keyFunction         = ...;
Function<INPUT, OUTPUT> memoizedFunction = GuavaMemoize.function(function, keyFunction);

// memoize in JCache cache
Predicate<INPUT> predicate               = ...;
Function<INPUT, KEY> keyFunction         = ...;
Predicate<INPUT> memoizedPredicate       = JCacheMemoize.predicate(predicate, keyFunction);

// memoize in ConcurrentMap
Supplier<OUTPUT> supplier                = ...;
Supplier<KEY> keySupplier                = ...;
Supplier<OUTPUT> memoizedSupplier        = MapMemoize.supplier(supplier, keySupplier);
----

=== Custom cache w/ default cache keys

[source, java]
----
// memoize in Caffeine cache
Consumer<INPUT> consumer                 = ...;
Cache<INPUT, INPUT> cache                = ...; // com.github.benmanes.caffeine.cache.Cache
Consumer<INPUT> memoizedConsumer         = CaffeineMemoize.consumer(consumer, cache);

// memoize in Guava cache
Function<INPUT, OUTPUT> function         = ...;
Cache<INPUT, OUTPUT> cache               = ...; // com.google.common.cache.Cache
Function<INPUT, OUTPUT> memoizedFunction = GuavaMemoize.function(function, cache);

// memoize in JCache cache
Predicate<INPUT> predicate               = ...;
Cache<INPUT, Boolean> cache              = ...; // javax.cache.Cache
Predicate<INPUT> memoizedPredicate       = JCacheMemoize.predicate(predicate, cache);

// memoize in ConcurrentMap
Supplier<OUTPUT> supplier                = ...;
Map<String, OUTPUT> cache                = ...;
Supplier<OUTPUT> memoizedSupplier        = MapMemoize.supplier(supplier, cache);
----

=== Custom cache w/ custom cache keys

[source, java]
----
// memoize in Caffeine cache
Consumer<INPUT> consumer                 = ...;
Function<INPUT, KEY> keyFunction         = ...;
Cache<KEY, INPUT> cache                  = ...; // com.github.benmanes.caffeine.cache.Cache
Consumer<INPUT> memoizedConsumer         = CaffeineMemoize.consumer(consumer, keyFunction, cache);

// memoize in Guava cache
Function<INPUT, OUTPUT> function         = ...;
Function<INPUT, KEY> keyFunction         = ...;
Cache<KEY, OUTPUT> cache                 = ...; // com.google.common.cache.Cache
Function<INPUT, OUTPUT> memoizedFunction = GuavaMemoize.function(function, keyFunction, cache);

// memoize in JCache cache
Predicate<INPUT> predicate               = ...;
Function<INPUT, KEY> keyFunction         = ...;
Cache<KEY, Boolean> cache                = ...; // javax.cache.Cache
Predicate<INPUT> memoizedPredicate       = JCacheMemoize.predicate(predicate, keyFunction, cache);

// memoize in ConcurrentMap
Supplier<OUTPUT> supplier                = ...;
Supplier<KEY> keySupplier                = ...;
Map<KEY, OUTPUT> cache                   = ...;
Supplier<OUTPUT> memoizedSupplier        = MapMemoize.supplier(supplier, keySupplier, cache);
----

Note that `MapMemoize` does accept any `Map`, however copies the entries in the map to a new `ConcurrentHashMap` in case the provided `Map` is not a `ConcurrentMap` as well. This is done in order to ensure atomic `computeIfAbsent` behavior.

=== Integration

In order to use this project, declare the following inside your POM:

[source, xml, subs="attributes,verbatim"]
----
<dependencies>
  <dependency>
    <groupId>{project-group}</groupId>
    <artifactId>memoization-core</artifactId>
    <version>${version.memoization}</version>
  </dependency>

  <dependency>
    <groupId>{project-group}</groupId>
    <artifactId>memoization-caffeine</artifactId>
    <version>${version.memoization}</version>
  </dependency>
  <dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>${version.caffeine}</version>
  </dependency>

  <dependency>
    <groupId>{project-group}</groupId>
    <artifactId>memoization-guava</artifactId>
    <version>${version.memoization}</version>
  </dependency>
  <dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>${version.guava}</version>
  </dependency>

  <dependency>
    <groupId>{project-group}</groupId>
    <artifactId>memoization-jcache</artifactId>
    <version>${version.memoization}</version>
  </dependency>
  <dependency>
    <groupId>javax.cache</groupId>
    <artifactId>cache-api</artifactId>
    <version>${version.jcache}</version>
  </dependency>

  <dependency>
    <groupId>...</groupId>
    <artifactId>...</artifactId>
    <version>...</version>
  </dependency>

</dependencies>
----

Replace `${version.memoization}` with the pass:[latest release]. This project follows the link:http://semver.org/[semantic versioning guidelines].
Popular JCache implementations are link:http://www.ehcache.org/[Ehcache], link:http://commons.apache.org/proper/commons-jcs/[Commons JCS], link:https://hazelcast.org/[Hazelcast], link:http://infinispan.org/[Infinispan], link:https://ignite.apache.org/[Apache Ignite], link:http://www.alachisoft.com/tayzgrid/[TayzGrid] and link:https://github.com/trivago/triava[triava].
Use link:https://github.com/jhalterman/expiringmap[ExpiringMap], link:https://github.com/ben-manes/concurrentlinkedhashmap[ConcurrentLinkedHashMap], link:https://github.com/OpenHFT/Chronicle-Map[Chronicle-Map], link:http://www.cacheonix.org/[Cacheonix] or other `ConcurrentMap` implementations as alternatives to the default `ConcurrentHashMap` used in the `MapMemoize` factory. Caches like link:http://cache2k.org/[cache2k] can be used together with both `JCacheMemoize` as a JSR-107 cache and `MapMemoize` by calling `cache.asMap()`.

=== Compatibility

This project is compatible with the following Java versions:

.Java compatibility
|===
| | 1.X.Y | 2.X.Y

| Java 8
| ✓
| ✓
|===

== Alternatives

* link:http://www.tek271.com/software/java/memoizer[Tek271 Memoizer]
* link:https://github.com/kelvinguu/gitmemoizer[GitMemoizer]
* link:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html#cache-annotations-cacheable[Spring's `@Cacheable`]
* link:https://github.com/marmelo/chili#memoize[Chili's `@Memoize`]
* link:https://clojuredocs.org/clojure.core/memoize[Clojure's `(memoize f)`]
* link:http://docs.groovy-lang.org/latest/html/gapi/groovy/transform/Memoized.html[Groovy's `@Memoized`]
* link:https://github.com/cb372/scalacache#memoization-of-method-results[ScalaCache's `memoize`]
* link:https://github.com/aol/cyclops/tree/master/cyclops-javaslang#memoization-with-a-guava-cache[Cyclops' `Memoize`]
* link:https://github.com/pakoito/RxMemoization[RxMemoization]
* link:https://github.com/jmorwick/memoized[memoized]
* link:https://github.com/ggrandes/memoizer[memoizer]
* link:http://aspects.jcabi.com/annotation-cacheable.html[jcabi's `@Cacheable`]
* link:https://github.com/strongh/crache#memoization-client[crache]

== License

To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.

You should have received a copy of the CC0 Public Domain Dedication along
with this software. If not, see http://creativecommons.org/publicdomain/zero/1.0/.

== Mirrors

* https://github.com/sebhoss/memoization.java
* https://bitbucket.org/sebhoss/memoization.java
* https://gitlab.com/sebastian.hoss/memoization.java
* http://v2.pikacode.com/sebhoss/memoization.java
* http://repo.or.cz/memoization.java.git

= memoization.java image:https://img.shields.io/badge/email-%40metio-brightgreen.svg?style=social&label=mail["Discuss on Google Groups", link="https://groups.google.com/forum/#!forum/metio"] image:https://img.shields.io/badge/irc-%23metio.wtf-brightgreen.svg?style=social&label=IRC["Chat on IRC", link="http://webchat.freenode.net/?channels=metio.wtf"]
Sebastian Hoß <http://seb.xn--ho-hia.de/[@sebhoss]>
:github-org: sebhoss
:project-name: memoization.java
:project-group: de.xn--ho-hia.memoization
:coverity-project: 8732
:codacy-project: 0ed810b7f2514f0ea1c8e86e97c803c4
:jdk-api: https://docs.oracle.com/javase/8/docs/api
:issue: https://github.com/sebhoss/memoization.java/issues
:toc:
:toc-placement: preamble

image:https://img.shields.io/badge/license-cc%20zero-000000.svg?style=flat-square["CC Zero", link="http://creativecommons.org/publicdomain/zero/1.0/"]
pass:[]
image:https://reposs.herokuapp.com/?path={github-org}/{project-name}&style=flat-square["Repository size"]
image:https://www.openhub.net/p/memoization-java/widgets/project_thin_badge?format=gif["Open Hub statistics", link="https://www.openhub.net/p/memoization-java"]

image:https://img.shields.io/travis/{github-org}/{project-name}/master.svg?style=flat-square["Build Status", link="https://travis-ci.org/{github-org}/{project-name}"]
image:https://img.shields.io/coveralls/{github-org}/{project-name}/master.svg?style=flat-square["Code Coverage", link="https://coveralls.io/github/{github-org}/{project-name}"]
image:https://img.shields.io/coverity/scan/{coverity-project}.svg?style=flat-square["Coverity Scan Result", link="https://scan.coverity.com/projects/{github-org}-memoization-java"]
image:https://img.shields.io/codacy/grade/{codacy-project}.svg?style=flat-square["Codacy Code Quality", link="https://www.codacy.com/app/mail_7/memoization-java"]
image:https://img.shields.io/badge/forkable-yes-brightgreen.svg?style=flat-square["Can this project be forked?", link="https://basicallydan.github.io/forkability/?u={github-org}&r={project-name}"]
image:https://img.shields.io/maintenance/yes/2017.svg?style=flat-square["Is this thing still maintained?"]
image:https://img.shields.io/bountysource/team/metio/activity.svg?style=flat-square["Bounties on open tickets", link="https://www.bountysource.com/teams/metio"]

_Java link:https://en.wikipedia.org/wiki/Memoization[memoization] library - trade space for time_

== Features

* Memoize calls to `Consumer`, `Function`, `Predicate`, `Supplier` and other functional interfaces in `java.util.function`
* Cache values using link:https://github.com/ben-manes/caffeine[Caffeine], link:https://github.com/google/guava/wiki/CachesExplained[Guava], link:https://jcp.org/en/jsr/detail?id=107[JCache] or any link:{jdk-api}/java/util/concurrent/ConcurrentMap.html[`ConcurrentMap`]
* Customize cache key calculation

.Coverage of `java.util.function`
|===
| | Caffeine | Guava | JCache | ConcurrentMap

| link:{jdk-api}/java/util/function/BiConsumer.html[BiConsumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/BiFunction.html[BiFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/BiPredicate.html[BiPredicate]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/BooleanSupplier.html[BooleanSupplier]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/Consumer.html[Consumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoubleBinaryOperator.html[DoubleBinaryOperator]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoubleConsumer.html[DoubleConsumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoubleFunction.html[DoubleFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoublePredicate.html[DoublePredicate]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoubleSupplier.html[DoubleSupplier]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoubleToIntFunction.html[DoubleToIntFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoubleToLongFunction.html[DoubleToLongFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/DoubleUnaryOperator.html[DoubleUnaryOperator]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/Function.html[Function]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntBinaryOperator.html[IntBinaryOperator]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntConsumer.html[IntConsumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntFunction.html[IntFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntPredicate.html[IntPredicate]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntSupplier.html[IntSupplier]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntToDoubleFunction.html[IntToDoubleFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntToLongFunction.html[IntToLongFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/IntUnaryOperator.html[IntUnaryOperator]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongBinaryOperator.html[LongBinaryOperator]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongConsumer.html[LongConsumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongFunction.html[LongFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongPredicate.html[LongPredicate]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongSupplier.html[LongSupplier]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongToDoubleFunction.html[LongToDoubleFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongToIntFunction.html[LongToIntFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/LongUnaryOperator.html[LongUnaryOperator]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ObjDoubleConsumer.html[ObjDoubleConsumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ObjIntConsumer.html[ObjIntConsumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ObjLongConsumer.html[ObjLongConsumer]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/Predicate.html[Predicate]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/Supplier.html[Supplier]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ToDoubleBiFunction.html[ToDoubleBiFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ToDoubleFunction.html[ToDoubleFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ToIntBiFunction.html[ToIntBiFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ToIntFunction.html[ToIntFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ToLongBiFunction.html[ToLongBiFunction]
| ✓
| ✓
| ✓
| ✓

| link:{jdk-api}/java/util/function/ToLongFunction.html[ToLongFunction]
| ✓
| ✓
| ✓
| ✓
|===

== Development Status

The Caffeine, Guava, JCache and `ConcurrentMap` based implementations cover all functional interfaces from `java.util.function`. Take a look at the link:https://github.com/sebhoss/memoization.java/issues[open tickets] for future ideas & ways to help out.

== Usage

Memoize any of the supported types by using the static factory methods supplied by:

* pass:[] `CaffeineMemoize` if you want to use link:https://github.com/ben-manes/caffeine[Caffeine] caches.
* pass:[] `GuavaMemoize` if you want to use link:https://github.com/google/guava/wiki/CachesExplained[Guava] caches.
* pass:[] `JCacheMemoize` if you want to use link:https://jcp.org/en/jsr/detail?id=107[JCache] (JSR107) caches.
* pass:[] `MapMemoize` if you want to use any link:{jdk-api}/java/util/concurrent/ConcurrentMap.html[`ConcurrentMap`] as cache.

=== Default cache w/ default cache keys

[source, java]
----
// memoize in Caffeine cache
Consumer<INPUT> consumer                 = ...;
Consumer<INPUT> memoizedConsumer         = CaffeineMemoize.consumer(consumer);

// memoize in Guava cache
Function<INPUT, OUTPUT> function         = ...;
Function<INPUT, OUTPUT> memoizedFunction = GuavaMemoize.function(function);

// memoize in JCache cache
Predicate<INPUT> predicate               = ...;
Predicate<INPUT> memoizedPredicate       = JCacheMemoize.predicate(predicate);

// memoize in ConcurrentMap
Supplier<OUTPUT> supplier                = ...;
Supplier<OUTPUT> memoizedSupplier        = MapMemoize.supplier(supplier);
----

=== Default cache w/ custom cache keys

[source, java]
----
// memoize in Caffeine cache
Consumer<INPUT> consumer                 = ...;
Function<INPUT, KEY> keyFunction         = ...;
Consumer<INPUT> memoizedConsumer         = CaffeineMemoize.consumer(consumer, keyFunction);

// memoize in Guava cache
Function<INPUT, OUTPUT> function         = ...;
Function<INPUT, KEY> keyFunction         = ...;
Function<INPUT, OUTPUT> memoizedFunction = GuavaMemoize.function(function, keyFunction);

// memoize in JCache cache
Predicate<INPUT> predicate               = ...;
Function<INPUT, KEY> keyFunction         = ...;
Predicate<INPUT> memoizedPredicate       = JCacheMemoize.predicate(predicate, keyFunction);

// memoize in ConcurrentMap
Supplier<OUTPUT> supplier                = ...;
Supplier<KEY> keySupplier                = ...;
Supplier<OUTPUT> memoizedSupplier        = MapMemoize.supplier(supplier, keySupplier);
----

=== Custom cache w/ default cache keys

[source, java]
----
// memoize in Caffeine cache
Consumer<INPUT> consumer                 = ...;
Cache<INPUT, INPUT> cache                = ...; // com.github.benmanes.caffeine.cache.Cache
Consumer<INPUT> memoizedConsumer         = CaffeineMemoize.consumer(consumer, cache);

// memoize in Guava cache
Function<INPUT, OUTPUT> function         = ...;
Cache<INPUT, OUTPUT> cache               = ...; // com.google.common.cache.Cache
Function<INPUT, OUTPUT> memoizedFunction = GuavaMemoize.function(function, cache);

// memoize in JCache cache
Predicate<INPUT> predicate               = ...;
Cache<INPUT, Boolean> cache              = ...; // javax.cache.Cache
Predicate<INPUT> memoizedPredicate       = JCacheMemoize.predicate(predicate, cache);

// memoize in ConcurrentMap
Supplier<OUTPUT> supplier                = ...;
Map<String, OUTPUT> cache                = ...;
Supplier<OUTPUT> memoizedSupplier        = MapMemoize.supplier(supplier, cache);
----

=== Custom cache w/ custom cache keys

[source, java]
----
// memoize in Caffeine cache
Consumer<INPUT> consumer                 = ...;
Function<INPUT, KEY> keyFunction         = ...;
Cache<KEY, INPUT> cache                  = ...; // com.github.benmanes.caffeine.cache.Cache
Consumer<INPUT> memoizedConsumer         = CaffeineMemoize.consumer(consumer, keyFunction, cache);

// memoize in Guava cache
Function<INPUT, OUTPUT> function         = ...;
Function<INPUT, KEY> keyFunction         = ...;
Cache<KEY, OUTPUT> cache                 = ...; // com.google.common.cache.Cache
Function<INPUT, OUTPUT> memoizedFunction = GuavaMemoize.function(function, keyFunction, cache);

// memoize in JCache cache
Predicate<INPUT> predicate               = ...;
Function<INPUT, KEY> keyFunction         = ...;
Cache<KEY, Boolean> cache                = ...; // javax.cache.Cache
Predicate<INPUT> memoizedPredicate       = JCacheMemoize.predicate(predicate, keyFunction, cache);

// memoize in ConcurrentMap
Supplier<OUTPUT> supplier                = ...;
Supplier<KEY> keySupplier                = ...;
Map<KEY, OUTPUT> cache                   = ...;
Supplier<OUTPUT> memoizedSupplier        = MapMemoize.supplier(supplier, keySupplier, cache);
----

Note that `MapMemoize` does accept any `Map`, however copies the entries in the map to a new `ConcurrentHashMap` in case the provided `Map` is not a `ConcurrentMap` as well. This is done in order to ensure atomic `computeIfAbsent` behavior.

=== Integration

In order to use this project, declare the following inside your POM:

[source, xml, subs="attributes,verbatim"]
----
<dependencies>
  <dependency>
    <groupId>{project-group}</groupId>
    <artifactId>memoization-core</artifactId>
    <version>${version.memoization}</version>
  </dependency>

  <dependency>
    <groupId>{project-group}</groupId>
    <artifactId>memoization-caffeine</artifactId>
    <version>${version.memoization}</version>
  </dependency>
  <dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>${version.caffeine}</version>
  </dependency>

  <dependency>
    <groupId>{project-group}</groupId>
    <artifactId>memoization-guava</artifactId>
    <version>${version.memoization}</version>
  </dependency>
  <dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>${version.guava}</version>
  </dependency>

  <dependency>
    <groupId>{project-group}</groupId>
    <artifactId>memoization-jcache</artifactId>
    <version>${version.memoization}</version>
  </dependency>
  <dependency>
    <groupId>javax.cache</groupId>
    <artifactId>cache-api</artifactId>
    <version>${version.jcache}</version>
  </dependency>

  <dependency>
    <groupId>...</groupId>
    <artifactId>...</artifactId>
    <version>...</version>
  </dependency>

</dependencies>
----

Replace `${version.memoization}` with the pass:[latest release]. This project follows the link:http://semver.org/[semantic versioning guidelines].
Popular JCache implementations are link:http://www.ehcache.org/[Ehcache], link:http://commons.apache.org/proper/commons-jcs/[Commons JCS], link:https://hazelcast.org/[Hazelcast], link:http://infinispan.org/[Infinispan], link:https://ignite.apache.org/[Apache Ignite] and link:http://www.alachisoft.com/tayzgrid/[TayzGrid].
Use link:https://github.com/jhalterman/expiringmap[ExpiringMap], link:https://github.com/ben-manes/concurrentlinkedhashmap[ConcurrentLinkedHashMap], link:https://github.com/OpenHFT/Chronicle-Map[Chronicle-Map], link:http://www.cacheonix.org/[Cacheonix] or other `ConcurrentMap` implementations as alternatives to the default `ConcurrentHashMap` used in the `MapMemoize` factory. Caches like link:http://cache2k.org/[cache2k] can be used together with both `JCacheMemoize` as a JSR-107 cache and `MapMemoize` by calling `cache.asMap()`.

=== Compatibility

This project is compatible with the following Java versions:

.Java compatibility
|===
| | 1.X.Y | 2.X.Y

| Java 8
| ✓
| ✓
|===

== Alternatives

* link:http://www.tek271.com/software/java/memoizer[Tek271 Memoizer]
* link:https://github.com/kelvinguu/gitmemoizer[GitMemoizer]
* link:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html#cache-annotations-cacheable[Spring's `@Cacheable`]
* link:https://github.com/marmelo/chili#memoize[Chili's `@Memoize`]
* link:https://clojuredocs.org/clojure.core/memoize[Clojure's `(memoize f)`]
* link:http://docs.groovy-lang.org/latest/html/gapi/groovy/transform/Memoized.html[Groovy's `@Memoized`]
* link:https://github.com/cb372/scalacache#memoization-of-method-results[ScalaCache's `memoize`]
* link:https://github.com/aol/cyclops/tree/master/cyclops-javaslang#memoization-with-a-guava-cache[Cyclops' `Memoize`]
* link:https://github.com/pakoito/RxMemoization[RxMemoization]
* link:https://github.com/jmorwick/memoized[memoized]
* link:https://github.com/ggrandes/memoizer[memoizer]
* link:http://aspects.jcabi.com/annotation-cacheable.html[jcabi's `@Cacheable`]
* link:https://github.com/strongh/crache#memoization-client[crache]

== License

To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.

You should have received a copy of the CC0 Public Domain Dedication along
with this software. If not, see http://creativecommons.org/publicdomain/zero/1.0/.

== Mirrors

* https://github.com/sebhoss/memoization.java
* https://bitbucket.org/sebhoss/memoization.java
* https://gitlab.com/sebastian.hoss/memoization.java
* http://v2.pikacode.com/sebhoss/memoization.java
* http://repo.or.cz/memoization.java.git


Updating README.asciidoc.

Updating README.asciidoc.

= 6+1+2+0 = nine

Nine is an XMPP 6120 library. It contains the components necessary to build an XMPP server or client.
The library is broken into several packages, each of which handles a specific piece
of the 6120 specification's functionality. These include:

Stream:: The stream package is responsible for separating the underlying transport layers
(TCP implemented here, BOSH implemented in link:http://github.com/skriptble/gabble[gabble])
from the XMPP application logic (stanza handling).
SASL:: Handles the SASL related functionality.
Namespace:: Maps constants to XMPP namespaces. This helps in avoiding mistyping a namespace.
JID:: Handles JID creation and validation.
Element:: Handles element parsing, marshalling, and manipulation.
Element/Stanza:: Handles stanza specific transformation and manipulation.
Bind:: Handles stream negotiation binding.

== Prototype
Under the cmd/prototype directory is a prototype implementation of an RFC 6120
XMPP server. It only handles stream negotiation, however it can be expanded to handle
other types of XMPP logic. The prototype requires a signed certificate and key to startup properly. A self signed key works for this purpose.


Update readme.

Update readme.

CocoaLibSpotify
===============

CocoaLibSpotify is an Objective-C wrapper around our libspotify library. It provides easy access to libspotify's features in a friendly, KVC/O compliant Objective-C wrapper.

*IMPORTANT:* When checking out CocoaLibSpotify, please run a +git submodule update --init+ before trying to build the sample projects.

Building -  Mac OS X
====================

The Xcode project was built in Xcode 4.0, but should also work fine in Xcode 3.2.x.

CocoaLibSpotify requires libspotify.framework, which isn't included in the repository. The Xcode project includes a build step to download and unpack it from developer.spotify.com automatically. If this fails for some reason, download it manually from developer.spotify.com and unpack it into the project folder.

The built CocoaLibSpotify.framework contains libspotify.framework as a child framework. Sometimes, Xcode gives build errors complaining it can't find <libspotify/api.h>. If you get this, manually add the directory libspotify.framework is in to your project's "Framework Search Paths" build setting. For example, if you're building the CocoaLibSpotify.framework project with your application then copying it into your bundle, you'd have this:

`$CONFIGURATION_BUILD_DIR/CocoaLibSpotify.framework/Versions/Frameworks`

Otherwise, you'd point to the downloaded libspotify.framework manually, something like this:

`../../libspotify-9.1.32-Darwin-universal`

Building - iOS
==============

At the moment, the easiest way to build CocoaLibSpotify on iOS is to include all of the files in the "common" directory directory in your project. When you need to use CocoaLibSpotify, include the following header file and you'll have everything you need imported:

#import "CocoaLibSpotify.h"

Of course, you need to include libspotify in your project too. Simply download the archives from http://developer.spotify.com/ and include the library and api.h file in your project.

Documentation
=============

The headers of CocoaLibSpotify are well documented, and we've provided an Xcode DocSet to provide documentation right in Xcode. With these and the sample projects, you should have everything you need to dive right in!

Contact
=======

If you have any problems or find any bugs, see our GitHub page for known issues and discussion. Otherwise, we may be available in irc://irc.freenode.net/spotify.

CocoaLibSpotify
===============

CocoaLibSpotify is an Objective-C wrapper around our libspotify library. It provides easy access to libspotify's features in a friendly, KVC/O compliant Objective-C wrapper.

*IMPORTANT:* When checking out CocoaLibSpotify, please run a +git submodule update --init+ before trying to build the sample projects.

Building -  Mac OS X
====================

The Xcode project was built in Xcode 4.0, but should also work fine in Xcode 3.2.x.

CocoaLibSpotify requires libspotify.framework, which isn't included in the repository. The Xcode project includes a build step to download and unpack it from developer.spotify.com automatically. If this fails for some reason, download it manually from developer.spotify.com and unpack it into the project folder.

The built CocoaLibSpotify.framework contains libspotify.framework as a child framework. Sometimes, Xcode gives build errors complaining it can't find <libspotify/api.h>. If you get this, manually add the directory CocoaLibSpotify.framework is in to your project's "Framework Search Paths" build setting.

Building - iOS
==============

At the moment, the easiest way to build CocoaLibSpotify on iOS is to include all of the files in the "common" directory directory in your project. When you need to use CocoaLibSpotify, include the following header file and you'll have everything you need imported:

#import "CocoaLibSpotify.h"

Of course, you need to include libspotify in your project too. Simply download the archives from http://developer.spotify.com/ and include the library and api.h file in your project.

Documentation
=============

The headers of CocoaLibSpotify are well documented, and we've provided an Xcode DocSet to provide documentation right in Xcode. With these and the sample projects, you should have everything you need to dive right in!

Contact
=======

If you have any problems or find any bugs, see our GitHub page for known issues and discussion. Otherwise, we may be available in irc://irc.freenode.net/spotify.


center test

center test

= jME3 Special Effects Overview
:revnumber: 2.1
:revdate: 2020/07/22
:keywords: documentation, effect, light, water
:uri-jmonkeyengine: https://github.com/jMonkeyEngine/jmonkeyengine/tree/master/
:img-jmonkeyengine: https://github.com/jMonkeyEngine/jmonkeyengine/raw/master/
:uri-forum: https://hub.jmonkeyengine.org/

jME3 supports several types of special effects: Post-Processor Filters, SceneProcessors, and Particle Emitters (also known as particle systems). This list contains screenshots and links to sample code that demonstrates how to add the effect to a scene.

== Sample Code

*  There is one `com.jme3.effect.ParticleEmitter` class for all Particle Systems.
*  There is one `com.jme3.post.FilterPostProcessor` class and several `com.jme3.post.filters.` (all Filters have `Filter` in their names).
*  There are several `SceneProcessor` classes in various packages, including e.g. `com.jme3.shadow.` and `com.jme3.water.` (SceneProcessor have `Processor` or `Renderer` in their names).

=== Particle Emitter

[source,java]
----

public class MyGame extends SimpleApplication {
  public void simpleInitApp() {
    ParticleEmitter pm = new ParticleEmitter("my particle effect", Type.Triangle, 60);
    Material pmMat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
    pmMat.setTexture("Texture", assetManager.loadTexture("Effects/spark.png"));
    pm.setMaterial(pmMat);
    pm.setImagesX(1);
    pm.setImagesY(1);
    rootNode.attachChild(pm); // attach one or more emitters to any node
  }
}

----

=== Scene Processor

[source,java]
----

public class MyGame extends SimpleApplication {
    private BasicShadowRenderer bsr;

    public void simpleInitApp() {
        bsr = new BasicShadowRenderer(assetManager, 1024);
        bsr.setDirection(new Vector3f(.3f, -0.5f, -0.5f));
        viewPort.addProcessor(bsr); // add one or more sceneprocessor to viewport
    }
...
}
----

=== Post-Processor Filter

[source,java]
----

public class MyGame extends SimpleApplication {
    private FilterPostProcessor fpp; // one FilterPostProcessor per app
    private SomeFilter sf;           // one or more Filters per app

    public void simpleInitApp() {
        fpp = new FilterPostProcessor(assetManager);
        viewPort.addProcessor(fpp); // add one FilterPostProcessor to viewPort

        sf = new SomeFilter();
        fpp.addFilter(sf);  // add one or more Filters to FilterPostProcessor
    }
...
}
----

== Water

[.float-group]
--
[.center]
image:effect/water-post.png[water-post.png,width="150",height="100"]
image:effect/water.png[water.png,width="150",height="100"]
image:effect/water-reflection-muddy.png[water-reflection-muddy.png,width="150",height="100"]
image:effect/underwater2.jpg[underwater2.jpg,width="150",height="100"]
--
The jMonkeyEngine xref:jme3/advanced/water.adoc["`SeaMonkey WaterFilter`"] simulates ocean waves, foam, including cool underwater caustics. +
Use the SimpleWaterProcessor (SceneProcessor) for small, limited bodies of water, such as puddles, drinking troughs, pools, fountains.

See also:

*  link:{uri-forum}t/monkeys-at-the-beach/15000[Rendering Water as Post-Process Effect] announcement with video.
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/water/TestSceneWater.java[TestSceneWater.java] – SimpleWaterProcessor. (SceneProcessor)
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/water/TestSimpleWater.java[TestSimpleWater.java] – SimpleWaterProcessor. (SceneProcessor)
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/water/TestPostWater.java[TestPostWater.java] – WaterFilter.
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/water/TestPostWaterLake.java[TestPostWaterLake.java] – WaterFilter.

== Environment Effects

=== Depth of Field Blur

image:effect/dof-blur.png[dof-blur.png,width="150",height="100"]
image:effect/light-scattering-filter.png[light-scattering-filter.png,width="150",height="100"]

*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestDepthOfField.java[TestDepthOfField.java] – DepthOfFieldFilter.

=== Fog

*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestFog.java[TestFog.java] – FogFilter.

=== Light Scattering

*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestLightScattering.java[TestLightScattering.java] – LightScatteringFilter.

=== Vegetation

*  Contribution: xref:jme3/contributions/vegetationsystem/grass.adoc[Grass System]
*  Contribution: {uri-forum}t/generating-vegetation-paged-geometry-style/18928[Trees (WIP)]

== Light and Shadows

=== Bloom and Glow

image:effect/tanlglow1.png[tanlglow1.png,width="150",height="100"]
image:effect/shadow-sponza-ssao.png[shadow-sponza-ssao.png,width="150",height="100"]

*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestBloom.java[TestBloom.java]
*  More details: xref:jme3/advanced/bloom_and_glow.adoc[Bloom and Glow] – BloomFilter.

=== Light

*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/light/TestSimpleLighting.java[TestSimpleLighting.java] – DirectionalLight, PointLight.
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/light/TestLightRadius.java[TestLightRadius.java] – DirectionalLight, PointLight.
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/light/TestManyLights.java[TestManyLights.java] – .j3o scene.
*  More details: xref:jme3/advanced/light_and_shadow.adoc[Light and Shadow]

=== Shadow

image:effect/shadow.png[shadow.png,width="150",height="100"]
image:light/light-sources.png[light-sources.png,width="150",height="100"]

//*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/light/TestShadow.java[TestShadow.java] – BasicShadowRenderer. (SceneProcessor)
//*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/light/TestPssmShadow.java[TestPssmShadow.java] – PssmShadowRenderer (SceneProcessor), also known as Parallel-Split Shadow Mapping (PSSM).
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestSSAO.java[TestSSAO.java], link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestSSAO2.java[TestSSAO2.java] – SSAOFilter, also known as Screen-Space Ambient Occlusion shadows (SSOA).
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestTransparentSSAO.java[TestTransparentSSAO.java] – SSAOFilter, also known as Screen-Space Ambient Occlusion shadows (SSOA), plus transparancy.
*  More details: xref:jme3/advanced/light_and_shadow.adoc[Light and Shadow]

== Special: Glass, Metal, Dissolve, Toon

=== Toon Effect

image:effect/toon-dino.png[toon-dino.png,width="150",height="100"]

*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestCartoonEdge.java[TestCartoonEdge.java] – CartoonEdgeFilter.
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestTransparentCartoonEdge.java[TestTransparentCartoonEdge.java] – CartoonEdgeFilter.

=== Fade in / Fade out

*  xref:jme3/advanced/fade.adoc[Fade] – FadeFilter

=== User Contributed

image:effect/shaderblow_light1.jpg[shaderblow_light1.jpg,width="78",height="150"]
image:effect/shaderblow_glass.jpg[shaderblow_glass.jpg,width="80",height="150"]
image:sdk:plugin/shaderblow_matcap.jpg[shaderblow_matcap.jpg,width="150",height="150"]
image:effect/shaderblow_light2.jpg[shaderblow_light2.jpg,width="66",height="150"]

xref:sdk:plugin/shaderblow.adoc[ShaderBlow - GLSL Shader Library]

*  LightBlow Shader – blend material texture maps.
*  FakeParticleBlow Shader – jet, fire effect.
*  ToonBlow Shader – Toon Shading, toon edges.
*  Dissolve Shader – Scifi teleportation/dissolve effect.
*  MatCap Shader – Gold, metals, glass, toons…!
*  Glass Shader – Glass.
*  Force Shield Shader – Scifi impact-on-force-field effect.
*  SimpleSprite Shader – Animated textures.
*  SimpleSpriteParticle Shader – Sprite library.
*  MovingTexture Shader – Animated cloud/mist texture.
*  SoftParticles Shader – Fire, clouds, smoke etc.
*  Displace Shader – Deformation effect: Ripple, wave, pulse, swell!

Thanks for your awesome contributions! Keep them coming!

== Particle Emitters: Explosions, Fire, Smoke

image:effect/explosion-5.png[explosion-5.png,width="150",height="100"]
image:effect/particle.png[particle.png,width="150",height="100"]

xref:jme3/advanced/particle_emitters.adoc[Particle emitter effects] are highly configurable and can have any texture. They can simulate smoke, dust, leaves, meteors, snowflakes, mosquitos, fire, explosions, clusters, embers, sparks…

*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/effect/TestExplosionEffect.java[TestExplosionEffect.java] – debris, flame, flash, shockwave, smoke, sparks.
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/effect/TestPointSprite.java[TestPointSprite.java] – cluster of points.
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/effect/TestMovingParticle.java[TestMovingParticle.java] – dust, smoke.

=== Creating your own Filters

Here is an extract taken from @nehon in the forum thread (link:{uri-forum}t/how-exactly-do-filters-work/26871[http://hub.jmonkeyengine.org/forum/topic/how-exactly-do-filters-work/])

The methods are called in this order (pretty much the same flow as processors):
- initFilter() is called once when the FilterPostPorcessor is initialized or when the filter is added to the processor and this one as already been initialized.

for each frame the methods are called in that sequence :
- preFrame() occurs before anything happens
- postQueue() occcurs once the queues have been populated (there is one queue per bucket and 2 additional queues for the shadows, casters and recievers). Note that geometries in the queues are the one in the view frustum.
- postFrame occurs once the main frame has been rendered (the back buffer)

Those methods are optional in a filter, they are only there if you want to hook in the rendering process.

The material variable is here for convenience. You have a getMaterial method that returns the material that’s gonna be used to render the full screen quad. It just happened that in every implementation I had a material attribute in all my sub-classes, so I just put it back in the abstract class. Most of the time getMaterial returns this attribute.

Forced-technique can be any technique really, they are more related with the material system than to the filters but anyway. When you use a forced technique the renderer tries to select it on the material of each geometry, if the technique does not exists for the material the geometry is not rendered.
You assume well about the SSAO filer, the normal of the scene are rendered to a texture in a pre pass.

Passes : these are filters in filters in a way. First they are a convenient way to initialize a FrameBuffer and the associated textures it needs, then you can use them for what ever you want.
For example, a Pass can be (as in the SSAO filter) an extra render of the scene with a forced technique, and you have to handle the render yourself in the postQueue method.
It can be a post pass to do after the main filter has been rendered to screen (for example an additional blur pass used in SSAO again). You have a list of passes called postRenderPass in the Filter abstract class. If you add a pass to this list, it’ll be automatically rendered by the FilterPostProcessor during the filter chain.

The bloom Filter does an intensive use of passes.

Filters in a nutshell.

See also:

*  xref:jme3/advanced/particle_emitters.adoc[Particle Emitters]
*  xref:jme3/advanced/bloom_and_glow.adoc[Bloom and Glow]
*  link:http://www.smashingmagazine.com/2008/08/07/50-photoshop-tutorials-for-sky-and-space-effects/[Photoshop Tutorial for Sky and space effects (article)]

= jME3 Special Effects Overview
:revnumber: 2.1
:revdate: 2020/07/22
:keywords: documentation, effect, light, water
:uri-jmonkeyengine: https://github.com/jMonkeyEngine/jmonkeyengine/tree/master/
:img-jmonkeyengine: https://github.com/jMonkeyEngine/jmonkeyengine/raw/master/
:uri-forum: https://hub.jmonkeyengine.org/

jME3 supports several types of special effects: Post-Processor Filters, SceneProcessors, and Particle Emitters (also known as particle systems). This list contains screenshots and links to sample code that demonstrates how to add the effect to a scene.

== Sample Code

*  There is one `com.jme3.effect.ParticleEmitter` class for all Particle Systems.
*  There is one `com.jme3.post.FilterPostProcessor` class and several `com.jme3.post.filters.` (all Filters have `Filter` in their names).
*  There are several `SceneProcessor` classes in various packages, including e.g. `com.jme3.shadow.` and `com.jme3.water.` (SceneProcessor have `Processor` or `Renderer` in their names).

=== Particle Emitter

[source,java]
----

public class MyGame extends SimpleApplication {
  public void simpleInitApp() {
    ParticleEmitter pm = new ParticleEmitter("my particle effect", Type.Triangle, 60);
    Material pmMat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
    pmMat.setTexture("Texture", assetManager.loadTexture("Effects/spark.png"));
    pm.setMaterial(pmMat);
    pm.setImagesX(1);
    pm.setImagesY(1);
    rootNode.attachChild(pm); // attach one or more emitters to any node
  }
}

----

=== Scene Processor

[source,java]
----

public class MyGame extends SimpleApplication {
    private BasicShadowRenderer bsr;

    public void simpleInitApp() {
        bsr = new BasicShadowRenderer(assetManager, 1024);
        bsr.setDirection(new Vector3f(.3f, -0.5f, -0.5f));
        viewPort.addProcessor(bsr); // add one or more sceneprocessor to viewport
    }
...
}
----

=== Post-Processor Filter

[source,java]
----

public class MyGame extends SimpleApplication {
    private FilterPostProcessor fpp; // one FilterPostProcessor per app
    private SomeFilter sf;           // one or more Filters per app

    public void simpleInitApp() {
        fpp = new FilterPostProcessor(assetManager);
        viewPort.addProcessor(fpp); // add one FilterPostProcessor to viewPort

        sf = new SomeFilter();
        fpp.addFilter(sf);  // add one or more Filters to FilterPostProcessor
    }
...
}
----

== Water

[.center]
image:effect/water-post.png[water-post.png,width="150",height="100",align="center"]
image:effect/water.png[water.png,width="150",height="100",align="center"]
image:effect/water-reflection-muddy.png[water-reflection-muddy.png,width="150",height="100",align="center"]
image:effect/underwater2.jpg[underwater2.jpg,width="150",height="100",align="center"]

The jMonkeyEngine xref:jme3/advanced/water.adoc["`SeaMonkey WaterFilter`"] simulates ocean waves, foam, including cool underwater caustics. +
Use the SimpleWaterProcessor (SceneProcessor) for small, limited bodies of water, such as puddles, drinking troughs, pools, fountains.

See also:

*  link:{uri-forum}t/monkeys-at-the-beach/15000[Rendering Water as Post-Process Effect] announcement with video.
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/water/TestSceneWater.java[TestSceneWater.java] – SimpleWaterProcessor. (SceneProcessor)
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/water/TestSimpleWater.java[TestSimpleWater.java] – SimpleWaterProcessor. (SceneProcessor)
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/water/TestPostWater.java[TestPostWater.java] – WaterFilter.
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/water/TestPostWaterLake.java[TestPostWaterLake.java] – WaterFilter.

== Environment Effects

=== Depth of Field Blur

image:effect/dof-blur.png[dof-blur.png,width="150",height="100"]
image:effect/light-scattering-filter.png[light-scattering-filter.png,width="150",height="100"]

*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestDepthOfField.java[TestDepthOfField.java] – DepthOfFieldFilter.

=== Fog

*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestFog.java[TestFog.java] – FogFilter.

=== Light Scattering

*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestLightScattering.java[TestLightScattering.java] – LightScatteringFilter.

=== Vegetation

*  Contribution: xref:jme3/contributions/vegetationsystem/grass.adoc[Grass System]
*  Contribution: {uri-forum}t/generating-vegetation-paged-geometry-style/18928[Trees (WIP)]

== Light and Shadows

=== Bloom and Glow

image:effect/tanlglow1.png[tanlglow1.png,width="150",height="100"]
image:effect/shadow-sponza-ssao.png[shadow-sponza-ssao.png,width="150",height="100"]

*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestBloom.java[TestBloom.java]
*  More details: xref:jme3/advanced/bloom_and_glow.adoc[Bloom and Glow] – BloomFilter.

=== Light

*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/light/TestSimpleLighting.java[TestSimpleLighting.java] – DirectionalLight, PointLight.
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/light/TestLightRadius.java[TestLightRadius.java] – DirectionalLight, PointLight.
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/light/TestManyLights.java[TestManyLights.java] – .j3o scene.
*  More details: xref:jme3/advanced/light_and_shadow.adoc[Light and Shadow]

=== Shadow

image:effect/shadow.png[shadow.png,width="150",height="100"]
image:light/light-sources.png[light-sources.png,width="150",height="100"]

//*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/light/TestShadow.java[TestShadow.java] – BasicShadowRenderer. (SceneProcessor)
//*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/light/TestPssmShadow.java[TestPssmShadow.java] – PssmShadowRenderer (SceneProcessor), also known as Parallel-Split Shadow Mapping (PSSM).
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestSSAO.java[TestSSAO.java], link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestSSAO2.java[TestSSAO2.java] – SSAOFilter, also known as Screen-Space Ambient Occlusion shadows (SSOA).
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestTransparentSSAO.java[TestTransparentSSAO.java] – SSAOFilter, also known as Screen-Space Ambient Occlusion shadows (SSOA), plus transparancy.
*  More details: xref:jme3/advanced/light_and_shadow.adoc[Light and Shadow]

== Special: Glass, Metal, Dissolve, Toon

=== Toon Effect

image:effect/toon-dino.png[toon-dino.png,width="150",height="100"]

*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestCartoonEdge.java[TestCartoonEdge.java] – CartoonEdgeFilter.
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/post/TestTransparentCartoonEdge.java[TestTransparentCartoonEdge.java] – CartoonEdgeFilter.

=== Fade in / Fade out

*  xref:jme3/advanced/fade.adoc[Fade] – FadeFilter

=== User Contributed

image:effect/shaderblow_light1.jpg[shaderblow_light1.jpg,width="78",height="150"]
image:effect/shaderblow_glass.jpg[shaderblow_glass.jpg,width="80",height="150"]
image:sdk:plugin/shaderblow_matcap.jpg[shaderblow_matcap.jpg,width="150",height="150"]
image:effect/shaderblow_light2.jpg[shaderblow_light2.jpg,width="66",height="150"]

xref:sdk:plugin/shaderblow.adoc[ShaderBlow - GLSL Shader Library]

*  LightBlow Shader – blend material texture maps.
*  FakeParticleBlow Shader – jet, fire effect.
*  ToonBlow Shader – Toon Shading, toon edges.
*  Dissolve Shader – Scifi teleportation/dissolve effect.
*  MatCap Shader – Gold, metals, glass, toons…!
*  Glass Shader – Glass.
*  Force Shield Shader – Scifi impact-on-force-field effect.
*  SimpleSprite Shader – Animated textures.
*  SimpleSpriteParticle Shader – Sprite library.
*  MovingTexture Shader – Animated cloud/mist texture.
*  SoftParticles Shader – Fire, clouds, smoke etc.
*  Displace Shader – Deformation effect: Ripple, wave, pulse, swell!

Thanks for your awesome contributions! Keep them coming!

== Particle Emitters: Explosions, Fire, Smoke

image:effect/explosion-5.png[explosion-5.png,width="150",height="100"]
image:effect/particle.png[particle.png,width="150",height="100"]

xref:jme3/advanced/particle_emitters.adoc[Particle emitter effects] are highly configurable and can have any texture. They can simulate smoke, dust, leaves, meteors, snowflakes, mosquitos, fire, explosions, clusters, embers, sparks…

*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/effect/TestExplosionEffect.java[TestExplosionEffect.java] – debris, flame, flash, shockwave, smoke, sparks.
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/effect/TestPointSprite.java[TestPointSprite.java] – cluster of points.
*  link:{uri-jmonkeyengine}jme3-examples/src/main/java/jme3test/effect/TestMovingParticle.java[TestMovingParticle.java] – dust, smoke.

=== Creating your own Filters

Here is an extract taken from @nehon in the forum thread (link:{uri-forum}t/how-exactly-do-filters-work/26871[http://hub.jmonkeyengine.org/forum/topic/how-exactly-do-filters-work/])

The methods are called in this order (pretty much the same flow as processors):
- initFilter() is called once when the FilterPostPorcessor is initialized or when the filter is added to the processor and this one as already been initialized.

for each frame the methods are called in that sequence :
- preFrame() occurs before anything happens
- postQueue() occcurs once the queues have been populated (there is one queue per bucket and 2 additional queues for the shadows, casters and recievers). Note that geometries in the queues are the one in the view frustum.
- postFrame occurs once the main frame has been rendered (the back buffer)

Those methods are optional in a filter, they are only there if you want to hook in the rendering process.

The material variable is here for convenience. You have a getMaterial method that returns the material that’s gonna be used to render the full screen quad. It just happened that in every implementation I had a material attribute in all my sub-classes, so I just put it back in the abstract class. Most of the time getMaterial returns this attribute.

Forced-technique can be any technique really, they are more related with the material system than to the filters but anyway. When you use a forced technique the renderer tries to select it on the material of each geometry, if the technique does not exists for the material the geometry is not rendered.
You assume well about the SSAO filer, the normal of the scene are rendered to a texture in a pre pass.

Passes : these are filters in filters in a way. First they are a convenient way to initialize a FrameBuffer and the associated textures it needs, then you can use them for what ever you want.
For example, a Pass can be (as in the SSAO filter) an extra render of the scene with a forced technique, and you have to handle the render yourself in the postQueue method.
It can be a post pass to do after the main filter has been rendered to screen (for example an additional blur pass used in SSAO again). You have a list of passes called postRenderPass in the Filter abstract class. If you add a pass to this list, it’ll be automatically rendered by the FilterPostProcessor during the filter chain.

The bloom Filter does an intensive use of passes.

Filters in a nutshell.

See also:

*  xref:jme3/advanced/particle_emitters.adoc[Particle Emitters]
*  xref:jme3/advanced/bloom_and_glow.adoc[Bloom and Glow]
*  link:http://www.smashingmagazine.com/2008/08/07/50-photoshop-tutorials-for-sky-and-space-effects/[Photoshop Tutorial for Sky and space effects (article)]


Minor edit

Minor edit

[[breaking_60_search_changes]]
=== Search and Query DSL changes

==== Changes to queries

* The `collect_payloads` parameter of the `span_near` query has been removed. Payloads will be
  loaded when needed.

* Queries on boolean fields now strictly parse boolean-like values. This means
  only the strings `"true"` and `"false"` will be parsed into their boolean
  counterparts. Other strings will cause an error to be thrown.

* The `in` query (a synonym for the `terms` query) has been removed

* The `geo_bbox` query (a synonym for the `geo_bounding_box` query) has been removed

* The `mlt` query (a synonym for the `more_like_this` query) has been removed.

* The deprecated `like_text`, `ids` and `docs` parameters (all synonyms for `like`) of the `more_like_this` query have
been removed. Also the deprecated `min_word_len` (a synonym for `min_word_length`) and `max_word_len`
(a synonym for `max_word_length`) have been removed.

* The `fuzzy_match` and `match_fuzzy` query (synonyma for the `match` query) have been removed

* The `terms` query now always returns scores equal to `1` and is not subject to
  `indices.query.bool.max_clause_count` anymore.

* The deprecated `indices` query has been removed.

* Support for empty query objects (`{ }`) has been removed from the query DSL.
  An error is thrown whenever an empty query object is provided.

* The deprecated `minimum_number_should_match` parameter in the `bool` query has
  been removed, use `minimum_should_match` instead.

* The `query_string` query now correctly parses the maximum number of
  states allowed when
  "https://en.wikipedia.org/wiki/Powerset_construction#Complexity[determinizing]"
  a regex as `max_determinized_states` instead of the typo
  `max_determined_states`.

* The `query_string` query no longer accepts `enable_position_increment`, use
  `enable_position_increments` instead.

* For `geo_distance` queries, sorting, and aggregations the `sloppy_arc` option
  has been removed from the `distance_type` parameter.

* The `geo_distance_range` query, which was deprecated in 5.0, has been removed.

* The `optimize_bbox` parameter has been removed from `geo_distance` queries.

* The `ignore_malformed` and `coerce` parameters have been removed from
  `geo_bounding_box`, `geo_polygon`, and `geo_distance` queries.

* The `disable_coord` parameter of the `bool` and `common_terms` queries has
  been removed. If provided, it will be ignored and issue a deprecation warning.

* The `template` query has been removed. This query was deprecated since 5.0

* The `percolate` query's `document_type` has been deprecated. From 6.0 and later
  it is no longer required to specify the `document_type` parameter.

* The `split_on_whitespace` parameter for the `query_string` query has been removed.
  If provided, it will be ignored and issue a deprecation warning.
  The `query_string` query now splits on operator only.

* The `use_dis_max` parameter for the `query_string` query has been removed.
  If provided, it will be ignored and issue a deprecation warning.
  The `tie_breaker` parameter must be used instead.

* The `auto_generate_phrase_queries` parameter for the `query_string` query has been removed,
  use an explicit quoted query instead.
  If provided, it will be ignored and issue a deprecation warning.

* The `all_fields` parameter for the `query_string` has been removed.
  Set `default_field` to *` instead.
  If provided, `default_field` will be automatically set to `*`

* The `index` parameter in the terms filter, used to look up terms in a dedicated index is
  now mandatory. Previously, the index defaulted to the index the query was executed on. Now this index
  must be explicitly set in the request.

* The deprecated `type` and `slop` parameter for the `match` query have been removed. Instead of
setting the `type`, the `match_phrase` or `match_phrase_prefix` should be used. The `slop` removed from
the `match` query but is supported for `match_phrase` and `match_phrase_prefix`.

* The deprecated `phrase_slop` parameter (a synonym for the `slop` parameter) of the `match_phrase` query has been removed.

* The deprecated `query` parameter (a synonym for the `filter` parameter) of the `constant_score` query has been removed.

* The deprecated `phrase_slop` parameter (a synonym for the `slop` parameter) of the `multi_match` query has been removed.

* The deprecated `prefix` parameter (a synonym for the `value` parameter) of the `prefix` query has been removed.

* The deprecated `le` (a synonym for `lte`) and `ge` (a synonym for `gte`) parameter of the `range` query have been removed.

* The deprecated multi term rewrite parameters `constant_score_auto`, `constant_score_filter` (synonyms for `constant_score`)
have been removed.

==== Search shards API

The search shards API no longer accepts the `type` url parameter, which didn't
have any effect in previous versions.

==== Changes to the Profile API

The `"time"` field showing human readable timing output has been replaced by the `"time_in_nanos"`
field which displays the elapsed time in nanoseconds. The `"time"` field can be turned on by adding
`"?human=true"` to the request url. It will display a rounded, human readable time value.

==== Scoring changes

===== Query normalization

Query normalization has been removed. This means that the TF-IDF similarity no
longer tries to make scores comparable across queries and that boosts are now
integrated into scores as simple multiplicative factors.

Other similarities are not affected as they did not normalize scores and
already integrated boosts into scores as multiplicative factors.

See https://issues.apache.org/jira/browse/LUCENE-7347[`LUCENE-7347`] for more
information.

===== Coordination factors

Coordination factors have been removed from the scoring formula. This means that
boolean queries no longer score based on the number of matching clauses.
Instead, they always return the sum of the scores of the matching clauses.

As a consequence, use of the TF-IDF similarity is now discouraged as this was
an important component of the quality of the scores that this similarity
produces. BM25 is recommended instead.

See https://issues.apache.org/jira/browse/LUCENE-7347[`LUCENE-7347`] for more
information.

==== Fielddata on `_uid`

Fielddata on `_uid` is deprecated. It is possible to switch to `_id` instead
but the only reason why it has not been deprecated too is because it is used
for the `random_score` function. If you really need access to the id of
documents for sorting, aggregations or search scripts, the recommendation is
to duplicate the id as a field in the document.

==== Highlighters

The `unified` highlighter is the new default choice for highlighter.
The offset strategy for each field is picked internally by this highlighter depending on the
type of the field (`index_options`).
It is still possible to force the highlighter to `fvh` or `plain` types.

The `postings` highlighter has been removed from Lucene and Elasticsearch.
The `unified` highlighter outputs the same highlighting when `index_options` is set
 to `offsets`.

==== `fielddata_fields`

The deprecated `fielddata_fields` have now been removed. `docvalue_fields` should be used instead.

==== `docvalue_fields`

`docvalue_fields` now have a default upper limit of 100 fields that can be requested.
This limit can be overridden by using the `index.max_docvalue_fields_search` index setting.

==== `script_fields`

`script_fields` now have a default upper limit of 32 script fields that can be requested.
This limit can be overridden by using the `index.max_script_fields` index setting.

==== Inner hits

The source inside a hit of inner hits keeps its full path with respect to the entire source.
In prior versions the source field names were relative to the inner hit.

==== Scroll

The `from` parameter can no longer be used in the search request body when initiating a scroll.
The parameter was already ignored in these situations, now in addition an error is thrown.

==== Limit on from/size in top hits and inner hits

The maximum number of results (`from` + `size`) that is allowed to be retrieved
via inner hits and top hits has been limited to 100. The limit can be controlled
via the `index.max_inner_result_window` index setting.

==== Scroll queries that use the request_cache are deprecated

Setting `request_cache:true` on a query that creates a scroll ('scroll=1m`)
 is deprecated and the request will not use the cache internally.
In future versions we will return a `400 - Bad request` instead of just ignoring
the hint.
Scroll queries are not meant to be cached.

[[breaking_60_search_changes]]
=== Search and Query DSL changes

==== Changes to queries

* The `collect_payloads` parameter of the `span_near` query has been removed. Payloads will be
  loaded when needed.

* Queries on boolean fields now strictly parse boolean-like values. This means
  only the strings `"true"` and `"false"` will be parsed into their boolean
  counterparts. Other strings will cause an error to be thrown.

* The `in` query (a synonym for the `terms` query) has been removed

* The `geo_bbox` query (a synonym for the `geo_bounding_box` query) has been removed

* The `mlt` query (a synonym for the `more_like_this` query) has been removed.

* The deprecated `like_text`, `ids` and `docs` parameters (all synonyms for `like`) of the `more_like_this` query have
been removed. Also the deprecated `min_word_len` (a synonym for `min_word_length`) and `max_word_len`
(a synonym for `max_word_length`) have been removed.

* The `fuzzy_match` and `match_fuzzy` query (synonyma for the `match` query) have been removed

* The `terms` query now always returns scores equal to `1` and is not subject to
  `indices.query.bool.max_clause_count` anymore.

* The deprecated `indices` query has been removed.

* Support for empty query objects (`{ }`) has been removed from the query DSL.
  An error is thrown whenever an empty query object is provided.

* The deprecated `minimum_number_should_match` parameter in the `bool` query has
  been removed, use `minimum_should_match` instead.

* The `query_string` query now correctly parses the maximum number of
  states allowed when
  "https://en.wikipedia.org/wiki/Powerset_construction#Complexity[determinizing]"
  a regex as `max_determinized_states` instead of the typo
  `max_determined_states`.

* The `query_string` query no longer accepts `enable_position_increment`, use
  `enable_position_increments` instead.

* For `geo_distance` queries, sorting, and aggregations the `sloppy_arc` option
  has been removed from the `distance_type` parameter.

* The `geo_distance_range` query, which was deprecated in 5.0, has been removed.

* The `optimize_bbox` parameter has been removed from `geo_distance` queries.

* The `ignore_malformed` and `coerce` parameters have been removed from
  `geo_bounding_box`, `geo_polygon`, and `geo_distance` queries.

* The `disable_coord` parameter of the `bool` and `common_terms` queries has
  been removed. If provided, it will be ignored and issue a deprecation warning.

* The `template` query has been removed. This query was deprecated since 5.0

* The `percolate` query's `document_type` has been deprecated. From 6.0 and later
  it is no longer required to specify the `document_type` parameter.

* The `split_on_whitespace` parameter for the `query_string` query has been removed.
  If provided, it will be ignored and issue a deprecation warning.
  The `query_string` query now splits on operator only.

* The `use_dismax` parameter for the `query_string` query has been removed.
  If provided, it will be ignored and issue a deprecation warning.
  The `tie_breaker` parameter must be used instead.

* The `auto_generate_phrase_queries` parameter for the `query_string` query has been removed,
  use an explicit quoted query instead.
  If provided, it will be ignored and issue a deprecation warning.

* The `all_fields` parameter for the `query_string` has been removed.
  Set `default_field` to *` instead.
  If provided, `default_field` will be automatically set to `*`

* The `index` parameter in the terms filter, used to look up terms in a dedicated index is
  now mandatory. Previously, the index defaulted to the index the query was executed on. Now this index
  must be explicitly set in the request.

* The deprecated `type` and `slop` parameter for the `match` query have been removed. Instead of
setting the `type`, the `match_phrase` or `match_phrase_prefix` should be used. The `slop` removed from
the `match` query but is supported for `match_phrase` and `match_phrase_prefix`.

* The deprecated `phrase_slop` parameter (a synonym for the `slop` parameter) of the `match_phrase` query has been removed.

* The deprecated `query` parameter (a synonym for the `filter` parameter) of the `constant_score` query has been removed.

* The deprecated `phrase_slop` parameter (a synonym for the `slop` parameter) of the `multi_match` query has been removed.

* The deprecated `prefix` parameter (a synonym for the `value` parameter) of the `prefix` query has been removed.

* The deprecated `le` (a synonym for `lte`) and `ge` (a synonym for `gte`) parameter of the `range` query have been removed.

* The deprecated multi term rewrite parameters `constant_score_auto`, `constant_score_filter` (synonyms for `constant_score`)
have been removed.

==== Search shards API

The search shards API no longer accepts the `type` url parameter, which didn't
have any effect in previous versions.

==== Changes to the Profile API

The `"time"` field showing human readable timing output has been replaced by the `"time_in_nanos"`
field which displays the elapsed time in nanoseconds. The `"time"` field can be turned on by adding
`"?human=true"` to the request url. It will display a rounded, human readable time value.

==== Scoring changes

===== Query normalization

Query normalization has been removed. This means that the TF-IDF similarity no
longer tries to make scores comparable across queries and that boosts are now
integrated into scores as simple multiplicative factors.

Other similarities are not affected as they did not normalize scores and
already integrated boosts into scores as multiplicative factors.

See https://issues.apache.org/jira/browse/LUCENE-7347[`LUCENE-7347`] for more
information.

===== Coordination factors

Coordination factors have been removed from the scoring formula. This means that
boolean queries no longer score based on the number of matching clauses.
Instead, they always return the sum of the scores of the matching clauses.

As a consequence, use of the TF-IDF similarity is now discouraged as this was
an important component of the quality of the scores that this similarity
produces. BM25 is recommended instead.

See https://issues.apache.org/jira/browse/LUCENE-7347[`LUCENE-7347`] for more
information.

==== Fielddata on `_uid`

Fielddata on `_uid` is deprecated. It is possible to switch to `_id` instead
but the only reason why it has not been deprecated too is because it is used
for the `random_score` function. If you really need access to the id of
documents for sorting, aggregations or search scripts, the recommendation is
to duplicate the id as a field in the document.

==== Highlighters

The `unified` highlighter is the new default choice for highlighter.
The offset strategy for each field is picked internally by this highlighter depending on the
type of the field (`index_options`).
It is still possible to force the highlighter to `fvh` or `plain` types.

The `postings` highlighter has been removed from Lucene and Elasticsearch.
The `unified` highlighter outputs the same highlighting when `index_options` is set
 to `offsets`.

==== `fielddata_fields`

The deprecated `fielddata_fields` have now been removed. `docvalue_fields` should be used instead.

==== `docvalue_fields`

`docvalue_fields` now have a default upper limit of 100 fields that can be requested.
This limit can be overridden by using the `index.max_docvalue_fields_search` index setting.

==== `script_fields`

`script_fields` now have a default upper limit of 32 script fields that can be requested.
This limit can be overridden by using the `index.max_script_fields` index setting.

==== Inner hits

The source inside a hit of inner hits keeps its full path with respect to the entire source.
In prior versions the source field names were relative to the inner hit.

==== Scroll

The `from` parameter can no longer be used in the search request body when initiating a scroll.
The parameter was already ignored in these situations, now in addition an error is thrown.

==== Limit on from/size in top hits and inner hits

The maximum number of results (`from` + `size`) that is allowed to be retrieved
via inner hits and top hits has been limited to 100. The limit can be controlled
via the `index.max_inner_result_window` index setting.

==== Scroll queries that use the request_cache are deprecated

Setting `request_cache:true` on a query that creates a scroll ('scroll=1m`)
 is deprecated and the request will not use the cache internally.
In future versions we will return a `400 - Bad request` instead of just ignoring
the hint.
Scroll queries are not meant to be cached.


Update Executable-Test-Case-Development-Rules.adoc

== Executable Test Case Development Rules

These rules were discussed between nations on 18 October 2016.

=== RTI compatibility
The ETC must be developed and tested with both Pitch and MÄK RTI, last versions if possible.
Some specific libraries (RTI adapters) will be developed in integrated in IVCT. ETC development must be done upon those RTI adapters.

=== Overall ETC structure

==== GitHub project name / Java package project name / Class names
GitHub Repository name: TC_[ETC name]
Ex.: `TC_CS_Verification`

Example:
----
TC_CS_Verification
----

Java main package name: nato.ivct.etc.tc_[ETC name], e.g.:
----
nato.ivct.etc.tc_cs_verification
nato.ivct.etc.fr.tc_hla_declaration_management
----

Main class names: TC_XXXX_[meaningful name].java.
N.B. : [meaningful name] is meaningful in the context of ETC, and is different of [ETC name] to avoid redundancy.

Example for ETC HLA Declaration Management:
----
TC_0001_Object_Publication.java
TC_0002_Interaction_Subscription.java
----

Java model and parameters package name: nato.ivct.etc.tc_**lib_**[ETC name], e.g.:
----
nato.ivct.etc.tc_lib_cs_verification
nato.ivct.etc.fr.tc_lib_hla_declaration_management
----

ETC model and parameters classes names: TC_[ETC name]__BaseModel.java and TC_[ETC name]_TcParam.java, e.g.:
----
TC_CS_Verification_BaseModel.java
TC_CS_Verification_TcParam.java
----

NOTE: **Warning:** The full name of a class may be very long, e.g.: `nato.ivct.etc.tc_hla_declaration_management.TC_0001_Object_Publication`

==== 3rd Party Libraries
Because one of the main problem with Java development is the management of dependencies (i.e. librairies), _**all new development (new ETC) must use already existing libraries**_. It will avoid some inconsistency and incompatibility between codes developed by different developers that may use different versions of the same library.
All 3rd party libraries must be declared in ETC Gradle files, as it is done in HelloWorld example.

**Question:** Where do new 3rd party libraries must be dropped off? It seems that Gradle manages some cache.

**Question:** How to have access to the libraries list that are already used by developed ETC? Who is responsible for the management of that list?

=== Development Best Practices
==== Test Case Parameters
It is mandatory to use JSON file to define parameter values.
3 steps in the initialization of Test Case Parameters (file `TC_[ETC name]_TcParam.java`) :

. Declaration with a NULL value
. Assignation to the value read using JSON parser
. Systematic check to detect invalid value

==== Test Case Variables
It is mandatory to manage Test Case Variables in the model source code (file `TC_[ETC name]_BaseModel.java`).

==== Logging

It is mandatory to use of the logger implementation (lockback) delivered by the framework.
Lockback configuration file: `[ETC name]/src/main/resources/logback.xml`.
There is 2 appenders: FILE and STDOUT.
There is currently a technical limitation that does not allow to place the output of a test case into a test case specific file. So, in order to facilitate the reading of the log file :

* At the beginning of each text case, the following specific message is logged: `Start of tc_[ETC name].TC_XXXX_[meaningful name]`
Example:   `Start of tc_hla_declaration_management.TC_0001_Object_Publication`

* At the beginning of each text case, the following specific message is logged:
`End of tc_[ETC name].TC_XXXX_[meaningful name]`
Ex.: `End of tc_hla_declaration_management.TC_0001_Object_Publication`

==== GUI
No GUI in the ETC, only parameters.

==== Results
The result of an ETC must be the following:

* INCONCLUSIVE: Corresponds to an error during initialisation (preambleAction method) or termination (postambleAction method) of the test.
* FAILED: An error / a problem occurred during the execution of the ETC that leads to a failure
* PASSED: No error / problem occurred during the execution of the ETC, the test is passed

== Executable Test Case Development Rules

These rules were discussed between nations on 18 October 2016.

=== RTI compatibility
The ETC must be developed and tested with both Pitch and MÄK RTI, last versions if possible.
Some specific libraries (RTI adapters) will be developed in integrated in IVCT. ETC development must be done upon those RTI adapters.

=== Overall ETC structure

==== GitHub project name / Java package project name / Class names
GitHub Repository name: TC_[ETC name]
Ex.: `TC_CS_Verification`

Example:
----
TC_CS_Verification
----

Java main package name: nato.ivct.etc.tc_[ETC name].
Example:
----
nato.ivct.etc.tc_cs_verification
nato.ivct.etc.fr.tc_hla_declaration_management
----

Main class names: TC_XXXX_[meaningful name].java.
N.B. : [meaningful name] is meaningful in the context of ETC, and is different of [ETC name] to avoid redundancy.
Example for ETC HLA Declaration Management:
----
TC_0001_Object_Publication.java
TC_0002_Interaction_Subscription.java
----

Java model and parameters package name: nato.ivct.etc.tc_**lib_**[ETC name].
Example:
----
nato.ivct.etc.tc_lib_cs_verification
nato.ivct.etc.fr.tc_lib_hla_declaration_management
----

ETC model and parameters classes names: TC_[ETC name]__BaseModel.java and TC_[ETC name]_TcParam.java.
Example:
----
TC_CS_Verification_BaseModel.java
TC_CS_Verification_TcParam.java
----

NOTE: **Warning:** The full name of a class may be very long, e.g.: `nato.ivct.etc.tc_hla_declaration_management.TC_0001_Object_Publication`

==== 3rd party libraries
Because one of the main problem with Java development is the management of dependencies (i.e. librairies), _**all new development (new ETC) must use already existing libraries**_. It will avoid some inconsistency and incompatibility between codes developed by different developers that may use different versions of the same library.
All 3rd party libraries must be declared in ETC Gradle files, as it is done in HelloWorld example.

**Question:** Where do new 3rd party libraries must be dropped off? It seems that Gradle manages some cache.

**Question:** How to have access to the libraries list that are already used by developed ETC? Who is responsible for the management of that list?

=== Development best practices
==== Test Case Parameters
It is mandatory to use JSON file to define parameter values.
3 steps in the initialization of Test Case Parameters (file `TC_[ETC name]_TcParam.java`) :

. Declaration with a NULL value
. Assignation to the value read using JSON parser
. Systematic check to detect invalid value

==== Test Case Variables
It is mandatory to manage Test Case Variables in the model source code (file `TC_[ETC name]_BaseModel.java`).

==== Logging

It is mandatory to use of the logger implementation (lockback) delivered by the framework.
Lockback configuration file: `[ETC name]/src/main/resources/logback.xml`.
There is 2 appenders: FILE and STDOUT.
There is currently a technical limitation that does not allow to place the output of a test case into a test case specific file. So, in order to facilitate the reading of the log file :

* At the beginning of each text case, the following specific message is logged: `Start of tc_[ETC name].TC_XXXX_[meaningful name]`
Example:   `Start of tc_hla_declaration_management.TC_0001_Object_Publication`

* At the beginning of each text case, the following specific message is logged:
`End of tc_[ETC name].TC_XXXX_[meaningful name]`
Ex.: `End of tc_hla_declaration_management.TC_0001_Object_Publication`

==== GUI
No GUI in the ETC, only parameters.

==== Results
The result of an ETC must be the following:

* INCONCLUSIVE: Corresponds to an error during initialisation (preambleAction method) or termination (postambleAction method) of the test.
* FAILED: An error / a problem occurred during the execution of the ETC that leads to a failure
* PASSED: No error / problem occurred during the execution of the ETC, the test is passed


Update 2017-02-20-Testing-DNS-Infrastructure-with-Goss.adoc

= Testing DNS Infrastructure with Goss
:hp-tags: Goss, DNS, Testing, DevOps, Linux, Monitoring
:hp-image: images/covers/OFFLINE.jpg


CAMEL-17199: update documentation to align Camel JBang CLI usage w/ Karavan (#6442)

= Camel JBang

A JBang-based Camel app for searching for kamelets, components, languages, running routes.

The `camel-jbang` is available from *Camel 3.12* and newer versions.

When running Camel JBang, it is possible to set the Camel version to use. For instance, to run the commands with the version 3.13.0, define the `camel.jbang.version` property in the command line.

== Using Camel JBang

The CamelJBang supports multiple commands. Running the command below, will print all of them:

[source,bash]
----
jbang -Dcamel.jbang.version=3.13.0 CamelJBang@apache/camel [command]
----

*Note*: the first time you run this command, it may cause dependencies to be cached, therefore taking a few extra seconds to run.

All the commands support the `--help` and will display the appropriate help if that flag is provided.

=== Search

You can use the CLI to search for kamelets, components, languages and miscelaneous components (others). Running the following command will present a list of items that can be searched:

[source,bash]
----
jbang -Dcamel.jbang.version=3.13.0 CamelJBang@apache/camel search --help
----

For example, to search for kamelets named `jms`, you can use:

[source,bash]
----
jbang -Dcamel.jbang.version=3.13.0 CamelJBang@apache/camel search kamelets --search-term=jms
----

To list all the kamelets, just run the command without any search term:

[source,bash]
----
jbang -Dcamel.jbang.version=3.13.0 CamelJBang@apache/camel search kamelets
----

The same behavior also works for all the other search commands. The table below lists all search commands available at the moment:

|===
|Command |Description

|kamelets
|search for kamelets

|components
|search for components

|languages
|search for languages

|others
|search for miscellaneous components

|===

=== Init Kamelets

The init sub-command can be used to simplify creating Kamelets. Through this command, it is possible to create new Kamelets through pre-configured templates. It works in two steps: first it is necessary to bootstrap the Kamelet by creating a properties file with the parameters necessary to create the Kamelet. Once the properties file is correctly set, then it is possible to create a pre-filled Kamelet by processing that properties file.

To bootstrap the Kamelet run:

[source,bash]
----
jbang -Dcamel.jbang.version=3.13.0 CamelJBang@apache/camel  init kamelet --bootstrap
----

This will create a sub-directory called `work` in the current directory with a properties file named `init-template.properties` inside it.

The keys of the properties file are commented with the details about what need to be filled in order to generate the Kamelet. If a value is missing, it will be ignored when generating the Kamelet and will need to be filled in manually later.

After you have filled the values, you can generate the Kamelet using:

[source,bash]
----
jbang -Dcamel.jbang.version=3.13.0 CamelJBang@apache/camel init kamelet --properties-path work/init-template.properties
----

Running this command will create a new file in the `work` directory. The name of the generated file is determined by the `kameletMetadataName` property in the properties file. As such, parsing the default properties file would generate a file named `my-sample-sink.kamelet.yaml` in the directory.

After the file is generated, it may still need to require final adjustments, such as correctly setting the name, the icon and other requirements for official Kamelets. Please consult the Kamelet development documentation for updated details.

=== Init Bindings

The init sub-command can also be used to simplify creating Kamelets bindings. Through this command, it is possible to create new bindings through pre-configured templates. Use the  `--kamelet` option (you can list the available ones using the search command) to set the Kamelet to generate the binding for.

To execute this feature run:

[source,bash]
----
jbang -Dcamel.jbang.version=3.13.0 CamelJBang@apache/camel init binding --destination /path/to/destination/directory/ --kamelet sftp-source
----

This will create a new sample YAML binding file that can be modified and used in Camel K.

You can also generate bindings that can be run by CamelJBang or Camel Core, but setting the `--project` option:

[source,bash]
----
jbang -Dcamel.jbang.version=3.13.0 CamelJBang@apache/camel init binding --destination /path/to/destination/directory/ --kamelet sftp-source --project core
----

== Running Routes

At the moment it is possible to run YAML-based routes which also refer to Kamelets in the catalog.

In order to do so, write a YAML-based file with the `route`, the `steps` and the `to` destination for the route. The following example, shows a route that uses the Timer Source Kamelet to produce messages every second. The body of the messages will be logged to the standard output. Subsequently, they will be sent to a AMQP 1.0 compliant broker using the JMS AMQ 1.0 Sink Kamelet.

[source,yaml]
----
- route:
    from:
      uri: "kamelet:timer-source"
      parameters:
        period: 1000
        message: "Hello Camel JBang"
    steps:
      - log: "${body}"
      - to:
          uri: "kamelet:jms-amqp-10-sink"
          parameters:
            remoteURI: amqp://localhost:61616
            destinationName: test-queue
----

Execute the following command to run this route:

[source,bash]
----
jbang -Dcamel.jbang.version=3.13.0 CamelJBang@apache/camel run jms-amqp-10-sink-binding.yaml
----

NOTE: it is necessary to have a AMQP 1.0 broker, such as Apache Artemis, running locally and listening on port 61616. Adjust the route accordingly if using a different address for the broker.

== Installation

It is not necessary to install Camel JBang. However, if you prefer to do so, JBang makes it easy for us by providing an installation feature that works with Github. If you have JBang installed on your system, then you can run the following command to install CamelJBang:

[source,bash]
----
jbang app install CamelJBang@apache/camel
----

= Camel JBang

A JBang-based Camel app for searching for kamelets, components, languages, running routes.

The `camel-jbang` is available from *Camel 3.12* and newer versions.

== Installation

JBang makes it easy for us by providing an installation feature that works with Github. If you have JBang installed on your system, then you can run the following command to install CamelJBang:

[source,bash]
----
jbang app install CamelJBang@apache/camel
----

== Using Camel JBang

The CamelJBang supports multiple commands. Running the command below, will print all of them:

[source,bash]
----
CamelJBang.java [command]
----

All the commands support the `--help` and will display the appropriate help if that flag is provided.

=== Search

You can use the CLI to search for kamelets, components, languages and miscelaneous components (others). Running the following command will present a list of items that can be searched:

[source,bash]
----
CamelJBang.java search --help
----

For example, to search for kamelets named `jms`, you can use:

[source,bash]
----
CamelJBang.java search kamelets --search-term=jms
----

To list all the kamelets, just run the command without any search term:

[source,bash]
----
CamelJBang.java search kamelets
----

The same behavior also works for all the other search commands. The table below lists all search commands available at the moment:

|===
|Command |Description

|kamelets
|search for kamelets

|components
|search for components

|languages
|search for languages

|others
|search for miscellaneous components

|===

=== Init Kamelets

The init sub-command can be used to simplify creating Kamelets. Through this command, it is possible to create new Kamelets through pre-configured templates. It works in two steps: first it is necessary to bootstrap the Kamelet by creating a properties file with the parameters necessary to create the Kamelet. Once the properties file is correctly set, then it is possible to create a pre-filled Kamelet by processing that properties file.

To bootstrap the Kamelet run:

[source,bash]
----
CamelJBang init kamelet --bootstrap
----

This will create a sub-directory called `work` in the current directory with a properties file named `init-template.properties` inside it.

The keys of the properties file are commented with the details about what need to be filled in order to generate the Kamelet. If a value is missing, it will be ignored when generating the Kamelet and will need to be filled in manually later.

After you have filled the values, you can generate the Kamelet using:

[source,bash]
----
CamelJBang init kamelet --properties-path work/init-template.properties
----

Running this command will create a new file in the `work` directory. The name of the generated file is determined by the `kameletMetadataName` property in the properties file. As such, parsing the default properties file would generate a file named `my-sample-sink.kamelet.yaml` in the directory.

After the file is generated, it may still need to require final adjustments, such as correctly setting the name, the icon and other requirements for official Kamelets. Please consult the Kamelet development documentation for updated details.

=== Init Bindings

The init sub-command can also be used to simplify creating Kamelets bindings. Through this command, it is possible to create new bindings through pre-configured templates. Use the  `--kamelet` option (you can list the available ones using the search command) to set the Kamelet to generate the binding for.

To execute this feature run:

[source,bash]
----
CamelJBang init binding --destination /path/to/destination/directory/ --kamelet sftp-source
----

This will create a new sample YAML binding file that can be modified and used in Camel K.

You can also generate bindings that can be run by CamelJBang or Camel Core, but setting the `--project` option:

[source,bash]
----
CamelJBang init binding --destination /path/to/destination/directory/ --kamelet sftp-source --project core
----

== Running Routes

At the moment it is possible to run YAML-based routes which also refer to Kamelets in the catalog.

In order to do so, write a YAML-based file with the `route`, the `steps` and the `to` destination for the route. The following example, shows a route that uses the Timer Source Kamelet to produce messages every second. The body of the messages will be logged to the standard output. Subsequently, they will be sent to a AMQP 1.0 compliant broker using the JMS AMQ 1.0 Sink Kamelet.

[source,yaml]
----
- route:
    from:
      uri: "kamelet:timer-source"
      parameters:
        period: 1000
        message: "Hello Camel JBang"
    steps:
      - log: "${body}"
      - to:
          uri: "kamelet:jms-amqp-10-sink"
          parameters:
            remoteURI: amqp://localhost:61616
            destinationName: test-queue
----

Execute the following command to run this route:

[source,bash]
----
CamelJBang run jms-amqp-10-sink-binding.yaml
----

NOTE: it is necessary to have a AMQP 1.0 broker, such as Apache Artemis, running locally and listening on port 61616. Adjust the route accordingly if using a different address for the broker.