diff --git a/.gitignore b/.gitignore index 2b4251a..e60c34c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ /api/out/ /api/run/ /run/ +/reflection/build/ /string/build/ /string/out/ /string/run/ diff --git a/api/src/main/java/net/kyori/examination/Examinable.java b/api/src/main/java/net/kyori/examination/Examinable.java index 63dee1b..2a4b11e 100644 --- a/api/src/main/java/net/kyori/examination/Examinable.java +++ b/api/src/main/java/net/kyori/examination/Examinable.java @@ -31,7 +31,7 @@ * * @since 1.0.0 */ -public interface Examinable { +public interface Examinable extends ExaminablePropertySource { /** * Gets the examinable name. * @@ -48,6 +48,7 @@ public interface Examinable { * @return a stream of examinable properties * @since 1.0.0 */ + @Override default @NonNull Stream extends ExaminableProperty> examinableProperties() { return Stream.empty(); } diff --git a/api/src/main/java/net/kyori/examination/ExaminablePropertySource.java b/api/src/main/java/net/kyori/examination/ExaminablePropertySource.java new file mode 100644 index 0000000..be9cc38 --- /dev/null +++ b/api/src/main/java/net/kyori/examination/ExaminablePropertySource.java @@ -0,0 +1,42 @@ +/* + * This file is part of examination, licensed under the MIT License. + * + * Copyright (c) 2018-2020 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.examination; + +import java.util.stream.Stream; +import org.checkerframework.checker.nullness.qual.NonNull; + +/** + * A source of {@link ExaminableProperty properties}. + * + * @since 1.1.0 + */ +public interface ExaminablePropertySource { + /** + * Gets a stream of examinable properties. + * + * @return a stream of examinable properties + * @since 1.1.0 + */ + @NonNull Stream extends ExaminableProperty> examinableProperties(); +} diff --git a/reflection/build.gradle b/reflection/build.gradle new file mode 100644 index 0000000..d21e17c --- /dev/null +++ b/reflection/build.gradle @@ -0,0 +1,10 @@ +dependencies { + api project(':examination-api') + testImplementation(project(':examination-string')) +} + +jar { + manifest.attributes( + 'Automatic-Module-Name': 'net.kyori.examination.reflection' + ) +} diff --git a/reflection/src/main/java/net/kyori/examination/reflection/Examine.java b/reflection/src/main/java/net/kyori/examination/reflection/Examine.java new file mode 100644 index 0000000..24c9ca6 --- /dev/null +++ b/reflection/src/main/java/net/kyori/examination/reflection/Examine.java @@ -0,0 +1,48 @@ +/* + * This file is part of examination, licensed under the MIT License. + * + * Copyright (c) 2018-2020 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.examination.reflection; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks a field which should be examined. + * + * @since 1.1.0 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Examine { + /** + * Gets the name. + * + *
The name of the field will be used if no value is provided.
+ * + * @return the name + * @since 1.1.0 + */ + String name() default ""; +} diff --git a/reflection/src/main/java/net/kyori/examination/reflection/ReflectiveExaminableProperties.java b/reflection/src/main/java/net/kyori/examination/reflection/ReflectiveExaminableProperties.java new file mode 100644 index 0000000..a9b9eaa --- /dev/null +++ b/reflection/src/main/java/net/kyori/examination/reflection/ReflectiveExaminableProperties.java @@ -0,0 +1,46 @@ +/* + * This file is part of examination, licensed under the MIT License. + * + * Copyright (c) 2018-2020 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.examination.reflection; + +import net.kyori.examination.ExaminableProperty; +import net.kyori.examination.ExaminablePropertySource; +import org.checkerframework.checker.nullness.qual.NonNull; + +/** + * An examinable property source which provides {@link ExaminableProperty properties} by reflectively examining an object. + * + * @since 1.1.0 + */ +public interface ReflectiveExaminableProperties extends ExaminablePropertySource { + /** + * Creates an examinable property source from the fields in {@code object} annotated with {@link Examine}. + * + * @param object the object to be examined + * @return an examinable property source + * @since 1.1.0 + */ + static @NonNull ReflectiveExaminableProperties forFields(final @NonNull Object object) { + return ReflectiveExaminablePropertiesImpl.forFields(object); + } +} diff --git a/reflection/src/main/java/net/kyori/examination/reflection/ReflectiveExaminablePropertiesImpl.java b/reflection/src/main/java/net/kyori/examination/reflection/ReflectiveExaminablePropertiesImpl.java new file mode 100644 index 0000000..5931f90 --- /dev/null +++ b/reflection/src/main/java/net/kyori/examination/reflection/ReflectiveExaminablePropertiesImpl.java @@ -0,0 +1,90 @@ +/* + * This file is part of examination, licensed under the MIT License. + * + * Copyright (c) 2018-2020 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.examination.reflection; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.Supplier; +import java.util.stream.Stream; +import net.kyori.examination.ExaminableProperty; +import org.checkerframework.checker.nullness.qual.NonNull; + +final class ReflectiveExaminablePropertiesImpl implements ReflectiveExaminableProperties { + private final List