You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by mb...@apache.org on 2018/02/21 21:01:56 UTC

[06/17] bval git commit: BV2: value extraction

BV2: value extraction


Project: http://git-wip-us.apache.org/repos/asf/bval/repo
Commit: http://git-wip-us.apache.org/repos/asf/bval/commit/a602e414
Tree: http://git-wip-us.apache.org/repos/asf/bval/tree/a602e414
Diff: http://git-wip-us.apache.org/repos/asf/bval/diff/a602e414

Branch: refs/heads/bv2
Commit: a602e414fbf7641395afe80dd744f68e29ef13c4
Parents: fad43eb
Author: Matt Benson <mb...@apache.org>
Authored: Wed Feb 21 14:35:25 2018 -0600
Committer: Matt Benson <mb...@apache.org>
Committed: Wed Feb 21 14:44:28 2018 -0600

----------------------------------------------------------------------
 .../bval/jsr/valueextraction/FxExtractor.java   |  96 ++++++++++
 .../IterableElementExtractor.java               |  30 +++
 .../valueextraction/ListElementExtractor.java   |  34 ++++
 .../bval/jsr/valueextraction/MapExtractor.java  |  42 +++++
 .../jsr/valueextraction/OptionalExtractor.java  |  65 +++++++
 .../jsr/valueextraction/ValueExtractors.java    | 181 +++++++++++++++++++
 .../DefaultExtractors.properties                |  25 +++
 7 files changed, 473 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/bval/blob/a602e414/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/FxExtractor.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/FxExtractor.java b/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/FxExtractor.java
new file mode 100644
index 0000000..15601b2
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/FxExtractor.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.jsr.valueextraction;
+
+import java.util.Optional;
+import java.util.function.BooleanSupplier;
+
+import javax.validation.valueextraction.ExtractedValue;
+import javax.validation.valueextraction.UnwrapByDefault;
+import javax.validation.valueextraction.ValueExtractor;
+
+import org.apache.bval.util.reflection.Reflection;
+
+import javafx.beans.property.ReadOnlyListProperty;
+import javafx.beans.property.ReadOnlyMapProperty;
+import javafx.beans.property.ReadOnlySetProperty;
+import javafx.beans.value.ObservableValue;
+
+@SuppressWarnings("restriction")
+public abstract class FxExtractor {
+    public static class Activation implements BooleanSupplier {
+
+        @Override
+        public boolean getAsBoolean() {
+            try {
+                return Reflection.toClass("javafx.beans.Observable") != null;
+            } catch (ClassNotFoundException e) {
+                return false;
+            }
+        }
+    }
+
+    @UnwrapByDefault
+    public static class ForObservableValue implements ValueExtractor<ObservableValue<@ExtractedValue ?>> {
+
+        @Override
+        public void extractValues(ObservableValue<?> originalValue, ValueExtractor.ValueReceiver receiver) {
+            receiver.value(null, originalValue.getValue());
+        }
+    }
+
+    public static class ForListProperty implements ValueExtractor<ReadOnlyListProperty<@ExtractedValue ?>> {
+
+        @Override
+        public void extractValues(ReadOnlyListProperty<?> originalValue, ValueExtractor.ValueReceiver receiver) {
+            Optional.ofNullable(originalValue.getValue()).ifPresent(l -> {
+                for (int i = 0, sz = l.size(); i < sz; i++) {
+                    receiver.indexedValue("<list element>", i, l.get(i));
+                }
+            });
+        }
+    }
+
+    public static class ForSetProperty implements ValueExtractor<ReadOnlySetProperty<@ExtractedValue ?>> {
+
+        @Override
+        public void extractValues(ReadOnlySetProperty<?> originalValue, ValueExtractor.ValueReceiver receiver) {
+            Optional.ofNullable(originalValue.getValue())
+                .ifPresent(s -> s.forEach(e -> receiver.iterableValue("<iterable element>", e)));
+        }
+    }
+
+    public static class ForMapPropertyKey implements ValueExtractor<ReadOnlyMapProperty<@ExtractedValue ?, ?>> {
+
+        @Override
+        public void extractValues(ReadOnlyMapProperty<?, ?> originalValue, ValueExtractor.ValueReceiver receiver) {
+            Optional.ofNullable(originalValue.getValue())
+                .ifPresent(m -> m.keySet().forEach(k -> receiver.keyedValue("<map key>", k, k)));
+        }
+    }
+
+    public static class ForMapPropertyValue implements ValueExtractor<ReadOnlyMapProperty<?, @ExtractedValue ?>> {
+
+        @Override
+        public void extractValues(ReadOnlyMapProperty<?, ?> originalValue, ValueExtractor.ValueReceiver receiver) {
+            Optional.ofNullable(originalValue.getValue()).ifPresent(
+                m -> m.entrySet().forEach(e -> receiver.keyedValue("<map value>", e.getKey(), e.getValue())));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/bval/blob/a602e414/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/IterableElementExtractor.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/IterableElementExtractor.java b/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/IterableElementExtractor.java
new file mode 100644
index 0000000..8fd2fc0
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/IterableElementExtractor.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.jsr.valueextraction;
+
+import javax.validation.valueextraction.ExtractedValue;
+import javax.validation.valueextraction.ValueExtractor;
+
+public class IterableElementExtractor implements ValueExtractor<Iterable<@ExtractedValue ?>> {
+
+    @Override
+    public void extractValues(Iterable<?> originalValue, ValueExtractor.ValueReceiver receiver) {
+        originalValue.forEach(v -> receiver.iterableValue("<iterable element>", v));
+    }
+}

http://git-wip-us.apache.org/repos/asf/bval/blob/a602e414/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ListElementExtractor.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ListElementExtractor.java b/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ListElementExtractor.java
new file mode 100644
index 0000000..bd84726
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ListElementExtractor.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.jsr.valueextraction;
+
+import java.util.List;
+
+import javax.validation.valueextraction.ExtractedValue;
+import javax.validation.valueextraction.ValueExtractor;
+
+public class ListElementExtractor implements ValueExtractor<List<@ExtractedValue ?>> {
+
+    @Override
+    public void extractValues(List<?> originalValue, ValueExtractor.ValueReceiver receiver) {
+        for (int i = 0, sz = originalValue.size(); i < sz; i++) {
+            receiver.indexedValue("<list element>", i, originalValue.get(i));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/bval/blob/a602e414/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/MapExtractor.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/MapExtractor.java b/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/MapExtractor.java
new file mode 100644
index 0000000..a6848b8
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/MapExtractor.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.jsr.valueextraction;
+
+import java.util.Map;
+
+import javax.validation.valueextraction.ExtractedValue;
+import javax.validation.valueextraction.ValueExtractor;
+
+public abstract class MapExtractor {
+    public static class ForKey implements ValueExtractor<Map<@ExtractedValue ?, ?>> {
+
+        @Override
+        public void extractValues(Map<?, ?> originalValue, ValueExtractor.ValueReceiver receiver) {
+            originalValue.keySet().forEach(k -> receiver.keyedValue("<map key>", k, k));
+        }
+    }
+
+    public static class ForValue implements ValueExtractor<Map<?, @ExtractedValue ?>> {
+
+        @Override
+        public void extractValues(Map<?, ?> originalValue, ValueExtractor.ValueReceiver receiver) {
+            originalValue.entrySet().forEach(e -> receiver.keyedValue("<map value>", e.getKey(), e.getValue()));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/bval/blob/a602e414/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/OptionalExtractor.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/OptionalExtractor.java b/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/OptionalExtractor.java
new file mode 100644
index 0000000..5f073cc
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/OptionalExtractor.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.jsr.valueextraction;
+
+import java.util.Optional;
+import java.util.OptionalDouble;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
+
+import javax.validation.valueextraction.ExtractedValue;
+import javax.validation.valueextraction.UnwrapByDefault;
+import javax.validation.valueextraction.ValueExtractor;
+
+public abstract class OptionalExtractor {
+    public static class ForObject implements ValueExtractor<Optional<@ExtractedValue ?>> {
+
+        @Override
+        public void extractValues(Optional<?> originalValue, ValueExtractor.ValueReceiver receiver) {
+            receiver.value(null, originalValue.orElse(null));
+        }
+    }
+
+    @UnwrapByDefault
+    public static class ForInt implements ValueExtractor<@ExtractedValue(type = Integer.class) OptionalInt> {
+
+        @Override
+        public void extractValues(OptionalInt originalValue, ValueExtractor.ValueReceiver receiver) {
+            receiver.value(null, originalValue.isPresent() ? Integer.valueOf(originalValue.getAsInt()) : null);
+        }
+    }
+
+    @UnwrapByDefault
+    public static class ForLong implements ValueExtractor<@ExtractedValue(type = Long.class) OptionalLong> {
+
+        @Override
+        public void extractValues(OptionalLong originalValue, ValueExtractor.ValueReceiver receiver) {
+            receiver.value(null, originalValue.isPresent() ? Long.valueOf(originalValue.getAsLong()) : null);
+        }
+    }
+
+    @UnwrapByDefault
+    public static class ForDouble implements ValueExtractor<@ExtractedValue(type = Double.class) OptionalDouble> {
+
+        @Override
+        public void extractValues(OptionalDouble originalValue, ValueExtractor.ValueReceiver receiver) {
+            receiver.value(null, originalValue.isPresent() ? Double.valueOf(originalValue.getAsDouble()) : null);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/bval/blob/a602e414/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ValueExtractors.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ValueExtractors.java b/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ValueExtractors.java
new file mode 100644
index 0000000..50feb6c
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ValueExtractors.java
@@ -0,0 +1,181 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.bval.jsr.valueextraction;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.Set;
+import java.util.function.BooleanSupplier;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.validation.valueextraction.ValueExtractor;
+import javax.validation.valueextraction.ValueExtractorDeclarationException;
+import javax.validation.valueextraction.ValueExtractorDefinitionException;
+
+import org.apache.bval.jsr.metadata.ContainerElementKey;
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.Lazy;
+import org.apache.bval.util.StringUtils;
+import org.apache.bval.util.Validate;
+import org.apache.bval.util.reflection.Reflection;
+import org.apache.bval.util.reflection.TypeUtils;
+
+public class ValueExtractors {
+    public static final ValueExtractors DEFAULT;
+
+    static {
+        DEFAULT = new ValueExtractors(null) {
+            {
+                final Properties defaultExtractors = new Properties();
+                try {
+                    defaultExtractors.load(ValueExtractors.class.getResourceAsStream("DefaultExtractors.properties"));
+                } catch (IOException e) {
+                    throw new IllegalStateException(e);
+                }
+                split(defaultExtractors.getProperty(ValueExtractor.class.getName())).map(cn -> {
+                    try {
+                        @SuppressWarnings("unchecked")
+                        final Class<? extends ValueExtractor<?>> result =
+                            (Class<? extends ValueExtractor<?>>) Reflection.toClass(cn)
+                                .asSubclass(ValueExtractor.class);
+                        return result;
+                    } catch (Exception e) {
+                        throw new IllegalStateException(e);
+                    }
+                }).map(ValueExtractors::newInstance).forEach(super::add);
+
+                split(defaultExtractors.getProperty(ValueExtractor.class.getName() + ".container"))
+                    .flatMap(ValueExtractors::loadValueExtractors).forEach(super::add);
+            }
+
+            @Override
+            public void add(ValueExtractor<?> extractor) {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    public static Class<?> getExtractedType(ValueExtractor<?> extractor, Type target) {
+        final ContainerElementKey key = ContainerElementKey.forValueExtractor(extractor);
+        Type result = key.getAnnotatedType().getType();
+        if (result instanceof TypeVariable<?>) {
+            result = TypeUtils.getTypeArguments(target, key.getContainerClass()).get(result);
+        }
+        Exceptions.raiseUnless(result instanceof Class<?>, ValueExtractorDefinitionException::new,
+            "%s did not resolve to a %s relative to %s", key, Class.class.getName(), target);
+        return (Class<?>) result;
+    }
+
+    private static Stream<String> split(String s) {
+        return Stream.of(StringUtils.split(s, ','));
+    }
+
+    private static <T> T newInstance(Class<T> t) {
+        try {
+            return t.newInstance();
+        } catch (InstantiationException | IllegalAccessException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    private static Stream<ValueExtractor<?>> loadValueExtractors(String containerClassName) {
+        try {
+            final Class<? extends BooleanSupplier> activation =
+                Reflection.toClass(containerClassName + "$Activation").asSubclass(BooleanSupplier.class);
+            if (!newInstance(activation).getAsBoolean()) {
+                return Stream.empty();
+            }
+        } catch (ClassNotFoundException e) {
+            // always active
+        }
+        final Class<?> containerClass;
+        try {
+            containerClass = Reflection.toClass(containerClassName);
+        } catch (ClassNotFoundException e) {
+            throw new IllegalStateException(e);
+        }
+        return Stream.of(containerClass.getClasses()).filter(ValueExtractor.class::isAssignableFrom).map(c -> {
+            @SuppressWarnings("unchecked")
+            final Class<? extends ValueExtractor<?>> result =
+                (Class<? extends ValueExtractor<?>>) c.asSubclass(ValueExtractor.class);
+            return result;
+        }).map(ValueExtractors::newInstance);
+    }
+
+    private final Lazy<Map<ContainerElementKey, ValueExtractor<?>>> valueExtractors = new Lazy<>(HashMap::new);
+    private final ValueExtractors parent;
+
+    public ValueExtractors() {
+        this(DEFAULT);
+    }
+
+    private ValueExtractors(ValueExtractors parent) {
+        this.parent = parent;
+    }
+
+    public ValueExtractors createChild() {
+        return new ValueExtractors(this);
+    }
+
+    public void add(ValueExtractor<?> extractor) {
+        Validate.notNull(extractor);
+        valueExtractors.get().compute(ContainerElementKey.forValueExtractor(extractor), (k, v) -> {
+            Exceptions.raiseIf(v != null, ValueExtractorDeclarationException::new,
+                "Multiple context-level %ss specified for %s", ValueExtractor.class.getSimpleName(), k);
+            return extractor;
+        });
+    }
+
+    public Map<ContainerElementKey, ValueExtractor<?>> getValueExtractors() {
+        final Lazy<Map<ContainerElementKey, ValueExtractor<?>>> result = new Lazy<>(HashMap::new);
+        populate(result);
+        return result.optional().orElseGet(Collections::emptyMap);
+    }
+
+    public ValueExtractor<?> find(ContainerElementKey key) {
+        final Map<ContainerElementKey, ValueExtractor<?>> allValueExtractors = getValueExtractors();
+        if (allValueExtractors.containsKey(key)) {
+            return allValueExtractors.get(key);
+        }
+        // search for assignable ContainerElementKey:
+        Set<ContainerElementKey> assignableKeys = key.getAssignableKeys();
+        while (!assignableKeys.isEmpty()) {
+            final Optional<ValueExtractor<?>> found = assignableKeys.stream().filter(allValueExtractors::containsKey)
+                .<ValueExtractor<?>> map(allValueExtractors::get).findFirst();
+            if (found.isPresent()) {
+                return found.get();
+            }
+            assignableKeys = assignableKeys.stream().map(ContainerElementKey::getAssignableKeys)
+                .flatMap(Collection::stream).collect(Collectors.toSet());
+        }
+        return null;
+    }
+
+    protected void populate(Supplier<Map<ContainerElementKey, ValueExtractor<?>>> target) {
+        Optional.ofNullable(parent).ifPresent(p -> p.populate(target));
+        valueExtractors.optional().ifPresent(m -> target.get().putAll(m));
+    }
+}

http://git-wip-us.apache.org/repos/asf/bval/blob/a602e414/bval-jsr/src/main/resources/org/apache/bval/jsr/valueextraction/DefaultExtractors.properties
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/resources/org/apache/bval/jsr/valueextraction/DefaultExtractors.properties b/bval-jsr/src/main/resources/org/apache/bval/jsr/valueextraction/DefaultExtractors.properties
new file mode 100644
index 0000000..9d9b768
--- /dev/null
+++ b/bval-jsr/src/main/resources/org/apache/bval/jsr/valueextraction/DefaultExtractors.properties
@@ -0,0 +1,25 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+javax.validation.valueextraction.ValueExtractor=\
+  org.apache.bval.jsr.valueextraction.IterableElementExtractor,\
+  org.apache.bval.jsr.valueextraction.ListElementExtractor
+
+javax.validation.valueextraction.ValueExtractor.container=\
+  org.apache.bval.jsr.valueextraction.MapExtractor,\
+  org.apache.bval.jsr.valueextraction.OptionalExtractor,\
+  org.apache.bval.jsr.valueextraction.FxExtractor