This is an automated email from the ASF dual-hosted git repository. jamesbognar pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/juneau.git
commit 6dc9a18ab5eca9c40a2951d9f7ec98c9cde98844 Author: James Bognar <[email protected]> AuthorDate: Tue May 12 10:05:47 2026 -0400 refactor: extract @BeanIgnore from @MarshalledIgnore for bean-detection (Phase 4 of bean-layer split) Split @MarshalledIgnore's mixed semantics into two annotations with cleaner responsibilities: - @BeanIgnore (new, org.apache.juneau.commons.bean): TYPE/FIELD/METHOD/CONSTRUCTOR. Bean-modeling concern. On TYPE: "not a bean — marshaller falls through to swaps, @Marshalled(as=STRING), etc.". On FIELD/METHOD/CONSTRUCTOR: excludes member from bean property/constructor detection. Lives in juneau-commons so the bean layer doesn't depend on marshalling. - @MarshalledIgnore (existing, juneau-marshall): trimmed to @Target({TYPE}) only. Marshalling-layer concern: "skip this type entirely — serializers output null, parsers return null". Removed the now-obsolete ignoreAccessors attribute. Migrated runtime sites in BeanMeta, AutoObjectSwap, AutoMapSwap, AutoListSwap, AutoNumberSwap, and SurrogateSwap to check @BeanIgnore for member/class-level bean detection. The TYPE-level "null swap" path in ClassMeta still checks @MarshalledIgnore. Migrated callsites: member-level @MarshalledIgnore usages (fields/methods/ctors) moved to @BeanIgnore; class-level usages on BasicHttpEntity, BasicResource, MediaType, MediaRanges, StringRange, StringRanges, and various test classes where the intent was "not a bean (fall through to toString)" moved to @BeanIgnore. Test class-level usages where the intent was "skip during marshalling, emit null" remain on @MarshalledIgnore. Added new tests: BeanIgnore_Test and BeanIgnoreAnnotation_Test. Trimmed MarshalledIgnore_Test to TYPE-level skip behavior only. Deleted obsolete shadow annotation org.apache.juneau.commons.annotation.MarshalledIgnore. Co-authored-by: Cursor <[email protected]> --- .../apache/juneau/bean/jsonschema/JsonSchema.java | 22 +- .../commons/annotation/MarshalledIgnore.java | 58 ------ .../org/apache/juneau/commons/bean/BeanIgnore.java | 87 ++++++++ .../juneau/commons/bean/BeanIgnoreAnnotation.java} | 48 +++-- .../apache/juneau/commons/http/MediaRanges.java | 4 +- .../org/apache/juneau/commons/http/MediaType.java | 4 +- .../apache/juneau/commons/http/StringRange.java | 4 +- .../apache/juneau/commons/http/StringRanges.java | 4 +- .../juneau/commons/inject/BeanInstantiator.java | 2 +- .../src/main/java/org/apache/juneau/BeanMeta.java | 44 ++-- .../src/main/java/org/apache/juneau/Context.java | 1 + .../java/org/apache/juneau/MarshallingContext.java | 20 +- .../org/apache/juneau/MarshallingContextable.java | 20 +- .../apache/juneau/annotation/BeanIgnoreApply.java | 101 +++++++++ .../annotation/BeanIgnoreApplyAnnotation.java | 232 +++++++++++++++++++++ .../apache/juneau/annotation/MarshalledIgnore.java | 59 ++---- .../annotation/MarshalledIgnoreAnnotation.java | 21 +- .../java/org/apache/juneau/swap/AutoListSwap.java | 13 +- .../java/org/apache/juneau/swap/AutoMapSwap.java | 13 +- .../org/apache/juneau/swap/AutoNumberSwap.java | 13 +- .../org/apache/juneau/swap/AutoObjectSwap.java | 13 +- .../java/org/apache/juneau/swap/SurrogateSwap.java | 3 +- .../apache/juneau/http/entity/BasicHttpEntity.java | 4 +- .../apache/juneau/http/resource/BasicResource.java | 4 +- .../test/java/org/apache/juneau/BeanMap_Test.java | 22 +- .../src/test/java/org/apache/juneau/TestUtils.java | 8 +- .../src/test/java/org/apache/juneau/a/A1.java | 12 +- .../juneau/a/rttests/RoundTripBeanMaps_Test.java | 8 +- ...on_Test.java => BeanIgnoreAnnotation_Test.java} | 27 ++- ...halledIgnore_Test.java => BeanIgnore_Test.java} | 103 ++++----- .../MarshalledIgnoreAnnotation_Test.java | 2 +- .../juneau/annotation/MarshalledIgnore_Test.java | 94 +-------- .../apache/juneau/transform/AutoListSwapTest.java | 17 +- .../apache/juneau/transform/AutoMapSwapTest.java | 17 +- .../juneau/transform/AutoNumberSwapTest.java | 17 +- .../juneau/transform/AutoObjectSwapTest.java | 17 +- 36 files changed, 688 insertions(+), 450 deletions(-) diff --git a/juneau-bean/juneau-bean-jsonschema/src/main/java/org/apache/juneau/bean/jsonschema/JsonSchema.java b/juneau-bean/juneau-bean-jsonschema/src/main/java/org/apache/juneau/bean/jsonschema/JsonSchema.java index 773cfb53bb..851d86cc76 100644 --- a/juneau-bean/juneau-bean-jsonschema/src/main/java/org/apache/juneau/bean/jsonschema/JsonSchema.java +++ b/juneau-bean/juneau-bean-jsonschema/src/main/java/org/apache/juneau/bean/jsonschema/JsonSchema.java @@ -687,7 +687,7 @@ public class JsonSchema { * * @return The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link JsonSchemaArray}. */ - @MarshalledIgnore + @BeanIgnore public Boolean getAdditionalItemsAsBoolean() { return additionalItemsBoolean; } /** @@ -699,7 +699,7 @@ public class JsonSchema { * * @return The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link Boolean}. */ - @MarshalledIgnore + @BeanIgnore public List<JsonSchema> getAdditionalItemsAsSchemaArray() { return additionalItemsSchemaArray; } /** @@ -726,7 +726,7 @@ public class JsonSchema { * * @return The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link JsonSchema}. */ - @MarshalledIgnore + @BeanIgnore public Boolean getAdditionalPropertiesAsBoolean() { return additionalPropertiesBoolean; } /** @@ -738,7 +738,7 @@ public class JsonSchema { * * @return The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link Boolean}. */ - @MarshalledIgnore + @BeanIgnore public JsonSchema getAdditionalPropertiesAsSchema() { return additionalPropertiesSchema; } /** @@ -966,7 +966,7 @@ public class JsonSchema { * * @return The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link JsonSchemaArray}. */ - @MarshalledIgnore + @BeanIgnore public JsonSchema getItemsAsSchema() { return itemsSchema; } /** @@ -977,7 +977,7 @@ public class JsonSchema { * * @return The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link JsonSchema}. */ - @MarshalledIgnore + @BeanIgnore public JsonSchemaArray getItemsAsSchemaArray() { return itemsSchemaArray; } /** @@ -1053,7 +1053,7 @@ public class JsonSchema { * * @return The value of the <property>name</property> property on this bean, or <jk>null</jk> if it is not set. */ - @MarshalledIgnore + @BeanIgnore public String getName() { return name; } /** @@ -1215,7 +1215,7 @@ public class JsonSchema { * @return * The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link JsonTypeArray}. */ - @MarshalledIgnore + @BeanIgnore public JsonType getTypeAsJsonType() { return typeJsonType; } /** @@ -1226,7 +1226,7 @@ public class JsonSchema { * * @return The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link JsonType}. */ - @MarshalledIgnore + @BeanIgnore public JsonTypeArray getTypeAsJsonTypeArray() { return typeJsonTypeArray; } /** @@ -1757,7 +1757,7 @@ public class JsonSchema { * @param value The new value for the <property>name</property> property on this bean. * @return This object. */ - @MarshalledIgnore + @BeanIgnore public JsonSchema setName(String value) { this.name = value; return this; @@ -1900,7 +1900,7 @@ public class JsonSchema { * @param value The schema map to associate with this schema. Can be <jk>null</jk>. * @return This object. */ - @MarshalledIgnore + @BeanIgnore public JsonSchema setSchemaMap(JsonSchemaMap value) { this.schemaMap = value; return this; diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/annotation/MarshalledIgnore.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/annotation/MarshalledIgnore.java deleted file mode 100644 index f0116e9fa9..0000000000 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/annotation/MarshalledIgnore.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.juneau.commons.annotation; - -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; - -import java.lang.annotation.*; - -/** - * Marks types in <c>juneau-commons</c> that must not be interpreted as beans (for example HTTP header value types - * serialized as strings). - * - * <p> - * Marshall's {@code org.apache.juneau.annotation.MarshalledIgnore} is the full-featured annotation (repeatable, dynamically - * applied, and so on). This annotation is recognized alongside it when classes are analyzed in juneau-marshall. - * </p> - * - * <h5 class='section'>See Also:</h5><ul> - * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/MarshalledIgnoreAnnotation">@MarshalledIgnore Annotation</a> - * </ul> - */ -@Documented -@Target({ FIELD, METHOD, TYPE, CONSTRUCTOR }) -@Retention(RUNTIME) -@Inherited -public @interface MarshalledIgnore { - - /** - * Optional description for the exposed API. - * - * @return The annotation value. - * @since 9.2.0 - */ - String[] description() default {}; - - /** - * When <jk>true</jk> and this annotation is on a <jk>field</jk>, JavaBean accessors for the same logical property - * are also excluded from bean metadata. - * - * @return The annotation value. - */ - boolean ignoreAccessors() default false; -} diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanIgnore.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanIgnore.java new file mode 100644 index 0000000000..508581277a --- /dev/null +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanIgnore.java @@ -0,0 +1,87 @@ +/* + * 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.juneau.commons.bean; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +import java.lang.annotation.*; + +/** + * Excludes a class, field, method, or constructor from bean introspection. + * + * <p> + * The bean-modeling sibling of {@code @MarshalledIgnore}: where {@code @MarshalledIgnore} (in + * <c>juneau-marshall</c>) controls whether the marshaller skips a type entirely at the wire-format + * layer, this annotation describes whether something participates in <i>bean detection</i>. It lives + * in <c>juneau-commons</c> so the bean-modeling layer can describe non-bean types and excluded bean + * members without depending on the marshalling layer. + * + * <p> + * Behavior depends on the target: + * <ul> + * <li><b>TYPE (class)</b> — marks the class as <i>not a bean</i>. The marshaller falls through to + * its other type-detection logic (object swaps, {@link org.apache.juneau.commons.bean.BeanType @BeanType}-style + * hints, {@code @Marshalled(as=STRING)}, etc.) instead of treating the class as a bean. This is + * the original pre-TODO-21 {@code @BeanIgnore} semantic. + * <li><b>FIELD</b> — excludes the field from bean property discovery. Use {@link #ignoreAccessors()} + * to also suppress matching JavaBean accessors. + * <li><b>METHOD</b> — excludes the getter/setter from bean property discovery. + * <li><b>CONSTRUCTOR</b> — excludes the constructor from constructor detection. + * </ul> + * + * <h5 class='section'>Java Records:</h5> + * <p> + * Ignoring individual record components is not supported during parsing. Because records are + * immutable, all components must be provided to the canonical constructor. Applying this + * annotation to a record component's accessor method or field will exclude it from serialization + * output, but the parser will be unable to instantiate the record if the component value is missing + * from the input. + * + * <h5 class='section'>See Also:</h5><ul> + * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/BeanIgnoreAnnotation">@BeanIgnore Annotation</a> + * </ul> + */ +@Documented +@Target({ FIELD, METHOD, TYPE, CONSTRUCTOR }) +@Retention(RUNTIME) +@Inherited +public @interface BeanIgnore { + + /** + * Optional description for the exposed API. + * + * @return The annotation value. + * @since 9.2.0 + */ + String[] description() default {}; + + /** + * When <jk>true</jk> and this annotation is on a <jk>field</jk>, JavaBean accessors (<c>getX</c>/<c>setX</c>, + * <c>isX</c>) for the same logical property are also excluded from bean metadata. + * + * <p> + * Default is <jk>false</jk>: {@code @BeanIgnore} on a field only excludes the field from field-based discovery; + * accessors can still expose the property (for example when bean field visibility is set to {@code NONE}). + * Set to <jk>true</jk> to omit the property from serialization and parsing while keeping accessors for other + * frameworks. + * + * @return The annotation value. + */ + boolean ignoreAccessors() default false; + +} diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/MarshalledIgnoreAnnotation.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanIgnoreAnnotation.java similarity index 68% copy from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/MarshalledIgnoreAnnotation.java copy to juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanIgnoreAnnotation.java index a78e194bf8..1cb6cb55e2 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/MarshalledIgnoreAnnotation.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanIgnoreAnnotation.java @@ -14,31 +14,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.juneau.annotation; +package org.apache.juneau.commons.bean; import static org.apache.juneau.commons.utils.CollectionUtils.*; -import java.lang.annotation.*; - import org.apache.juneau.commons.annotation.*; /** - * Utility classes and methods for the {@link MarshalledIgnore @MarshalledIgnore} annotation. + * Utility classes and methods for the {@link BeanIgnore @BeanIgnore} annotation. + * + * <p> + * Provides a {@link Builder} that constructs a synthetic {@link BeanIgnore @BeanIgnore} annotation instance + * programmatically without requiring it to be declared on a program element at compile time. * + * <h5 class='section'>See Also:</h5><ul> + * <li class='ja'>{@link BeanIgnore} + * <li class='jc'>{@link AnnotationObject} + * </ul> */ -public class MarshalledIgnoreAnnotation { +public class BeanIgnoreAnnotation { /** * Prevents instantiation. */ - private MarshalledIgnoreAnnotation() {} + private BeanIgnoreAnnotation() {} /** * Builder class. - * - * <h5 class='section'>See Also:</h5><ul> - * <li class='jm'>{@link org.apache.juneau.MarshallingContext.Builder#annotations(Annotation...)} - * </ul> */ public static class Builder extends AnnotationObject.Builder { @@ -49,15 +51,15 @@ public class MarshalledIgnoreAnnotation { * Constructor. */ protected Builder() { - super(MarshalledIgnore.class); + super(BeanIgnore.class); } /** - * Instantiates a new {@link MarshalledIgnore @MarshalledIgnore} object initialized with this builder. + * Instantiates a new {@link BeanIgnore @BeanIgnore} object initialized with this builder. * - * @return A new {@link MarshalledIgnore @MarshalledIgnore} object. + * @return A new {@link BeanIgnore @BeanIgnore} object. */ - public MarshalledIgnore build() { + public BeanIgnore build() { return new Object(this); } @@ -73,7 +75,7 @@ public class MarshalledIgnoreAnnotation { } /** - * Sets {@link MarshalledIgnore#ignoreAccessors()}. + * Sets {@link BeanIgnore#ignoreAccessors()}. * * @param value The new value. * @return This object. @@ -88,30 +90,30 @@ public class MarshalledIgnoreAnnotation { @SuppressWarnings({ "java:S2160" // equals() inherited from AnnotationObject compares all annotation interface methods; subclass fields are accessed via those methods }) - private static class Object extends AnnotationObject implements MarshalledIgnore { + private static class Object extends AnnotationObject implements BeanIgnore { private final String[] description; private final boolean ignoreAccessors; - Object(MarshalledIgnoreAnnotation.Builder b) { + Object(BeanIgnoreAnnotation.Builder b) { super(b); - this.description = copyOf(b.description); - this.ignoreAccessors = b.ignoreAccessors; + description = copyOf(b.description); + ignoreAccessors = b.ignoreAccessors; } - @Override /* Overridden from MarshalledIgnore */ + @Override /* Overridden from BeanIgnore */ public String[] description() { return description; } - @Override /* Overridden from MarshalledIgnore */ + @Override /* Overridden from BeanIgnore */ public boolean ignoreAccessors() { return ignoreAccessors; } } /** Default value */ - public static final MarshalledIgnore DEFAULT = create().build(); + public static final BeanIgnore DEFAULT = create().build(); /** * Instantiates a new builder for this class. @@ -121,4 +123,4 @@ public class MarshalledIgnoreAnnotation { public static Builder create() { return new Builder(); } -} \ No newline at end of file +} diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/MediaRanges.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/MediaRanges.java index f6647abdf5..30da447808 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/MediaRanges.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/MediaRanges.java @@ -23,7 +23,7 @@ import static org.apache.juneau.commons.utils.Utils.*; import java.util.*; import java.util.function.*; -import org.apache.juneau.commons.annotation.MarshalledIgnore; +import org.apache.juneau.commons.bean.BeanIgnore; import org.apache.juneau.commons.collections.*; /** @@ -53,7 +53,7 @@ import org.apache.juneau.commons.collections.*; * <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a> * </ul> */ -@MarshalledIgnore +@BeanIgnore public class MediaRanges { /** Represents an empty media ranges object. */ diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/MediaType.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/MediaType.java index 9f5c5c5b61..fa681d9bc7 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/MediaType.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/MediaType.java @@ -23,7 +23,7 @@ import static org.apache.juneau.commons.utils.Utils.*; import java.util.*; import java.util.function.*; -import org.apache.juneau.commons.annotation.MarshalledIgnore; +import org.apache.juneau.commons.bean.BeanIgnore; import org.apache.juneau.commons.collections.*; import org.apache.juneau.commons.utils.*; @@ -36,7 +36,7 @@ import org.apache.juneau.commons.utils.*; * <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a> * </ul> */ -@MarshalledIgnore +@BeanIgnore @SuppressWarnings({ "java:S1700", // Field 'mediaType' intentionally shares the class name; it holds the canonical string form of this MediaType instance "java:S1845" // Field name intentionally matches method name diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/StringRange.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/StringRange.java index a1cc5d8ba3..4b5fcf607f 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/StringRange.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/StringRange.java @@ -23,7 +23,7 @@ import static org.apache.juneau.commons.utils.Utils.*; import java.util.*; import java.util.function.*; -import org.apache.juneau.commons.annotation.MarshalledIgnore; +import org.apache.juneau.commons.bean.BeanIgnore; /** * Represents a single value in a comma-delimited header value that optionally contains a quality metric for @@ -42,7 +42,7 @@ import org.apache.juneau.commons.annotation.MarshalledIgnore; * </ul> */ -@MarshalledIgnore +@BeanIgnore public class StringRange { private static HeaderElement parse(String value) { diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/StringRanges.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/StringRanges.java index 8e8b0e0d8c..7468440706 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/StringRanges.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/StringRanges.java @@ -23,7 +23,7 @@ import static org.apache.juneau.commons.utils.Utils.*; import java.util.*; import java.util.function.*; -import org.apache.juneau.commons.annotation.MarshalledIgnore; +import org.apache.juneau.commons.bean.BeanIgnore; import org.apache.juneau.commons.collections.*; /** @@ -59,7 +59,7 @@ import org.apache.juneau.commons.collections.*; * <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a> * </ul> */ -@MarshalledIgnore +@BeanIgnore public class StringRanges { /** Represents an empty string ranges object. */ diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BeanInstantiator.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BeanInstantiator.java index 85d903f269..a95213ca8d 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BeanInstantiator.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BeanInstantiator.java @@ -174,7 +174,7 @@ import org.apache.juneau.commons.reflect.*; * <li class='note'>All constructors and methods except {@link Optional} and {@link List} parameters * must have beans available in the store. * <li class='note'>If multiple constructors/methods are found, the one with the most matching parameters is used. - * <li class='note'>Deprecated and <a class="doclink" href="https://juneau.apache.org/site/apidocs/org/apache/juneau/annotation/MarshalledIgnore.html">@MarshalledIgnore</a>-annotated methods/constructors are ignored. + * <li class='note'>Deprecated and <a class="doclink" href="https://juneau.apache.org/site/apidocs/org/apache/juneau/commons/bean/BeanIgnore.html">@BeanIgnore</a>-annotated methods/constructors are ignored. * </ul> * * <h5 class='section'>See Also:</h5><ul> diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java index 5e73b2ae68..fc12d17631 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java @@ -225,8 +225,8 @@ public class BeanMeta<T> { if (bc.isBeansRequireSerializable() && ! cm.isAssignableTo(Serializable.class) && ! ap.has(Marshalled.class, cm) && ! ap.has(org.apache.juneau.commons.bean.BeanType.class, cm)) return notABean("Class is not serializable"); - if (ap.has(MarshalledIgnore.class, cm) || ap.has(org.apache.juneau.commons.annotation.MarshalledIgnore.class, cm)) - return notABean("Class is annotated with @MarshalledIgnore"); + if (ap.has(BeanIgnore.class, cm)) + return notABean("Class is annotated with @BeanIgnore"); if ((! bc.getBeanClassVisibility().isVisible(cm.getModifiers()) || cm.isAnonymousClass()) && ! ap.has(Marshalled.class, cm) && ! ap.has(org.apache.juneau.commons.bean.BeanType.class, cm)) return notABean("Class is not public"); @@ -1099,7 +1099,7 @@ public class BeanMeta<T> { * <li>Not static * <li>Not transient (unless transient fields are not ignored) * <li>Not annotated with {@link Transient @Transient} (unless transient fields are not ignored) - * <li>Not annotated with {@link MarshalledIgnore @MarshalledIgnore} + * <li>Not annotated with {@link BeanIgnore @BeanIgnore} * <li>Visible according to the specified visibility level, or annotated with {@link BeanProp @BeanProp} * </ul> * @@ -1119,7 +1119,7 @@ public class BeanMeta<T> { .filter(x -> x.isNotStatic() && (x.isNotTransient() || noIgnoreTransients) && (! x.hasAnnotation(Transient.class) || noIgnoreTransients) - && ! ap.has(MarshalledIgnore.class, x) + && ! ap.has(BeanIgnore.class, x) && (v.isVisible(x.inner()) || ap.has(BeanProp.class, x) || (isRecord && recordComponentNames.contains(x.getName())))) .toList(); @@ -1156,7 +1156,7 @@ public class BeanMeta<T> { * <ul> * <li>Not static, not bridge methods * <li>Parameter count ≤ 2 - * <li>Not annotated with {@link MarshalledIgnore @MarshalledIgnore} + * <li>Not annotated with {@link BeanIgnore @BeanIgnore} * <li>Not annotated with {@link Transient @Transient} * <li>Visible according to the specified visibility level, or annotated with {@link BeanProp @BeanProp} or {@link Name @Name} * </ul> @@ -1179,7 +1179,7 @@ public class BeanMeta<T> { var ci = classMeta; var v = marshallingContext.getBeanMethodVisibility(); var pn = opt(beanFilter).map(x -> x.getPropertyNamer()).orElse(marshallingContext.getPropertyNamer()); - var suppressedFromMarshalledIgnoredFields = findSuppressedPropertyNamesFromIgnoredFields(pn); + var suppressedFromBeanIgnoredFields = findSuppressedPropertyNamesFromIgnoredFields(pn); classHierarchy.get().stream().forEach(c2 -> { for (var m : c2.getDeclaredMethods()) { @@ -1188,7 +1188,7 @@ public class BeanMeta<T> { var names = ap.find(Name.class, m).stream().map(AnnotationInfo::inner).toList(); // Skip static, bridge, or methods with >2 params; skip if ignored, transient, or not visible if (m.isStatic() || m.isBridge() || m.getParameterCount() > 2 - || mm.stream().anyMatch(m2 -> ap.has(MarshalledIgnore.class, m2, SELF)) + || mm.stream().anyMatch(m2 -> ap.has(BeanIgnore.class, m2, SELF)) || mm.stream().anyMatch(m2 -> ap.find(Transient.class, m2, SELF).stream().map(x -> x.inner().value()).findFirst().orElse(false)) || ! (m.isVisible(v) || ne(beanps) || ne(names))) continue; @@ -1271,7 +1271,7 @@ public class BeanMeta<T> { if (methodType != UNKNOWN) { if (nn(bpName) && ! bpName.isEmpty()) n = bpName; - if (nn(n) && ! suppressedFromMarshalledIgnoredFields.contains(n)) + if (nn(n) && ! suppressedFromBeanIgnoredFields.contains(n)) l.add(new BeanMethod(n, methodType, m.inner())); } } @@ -1446,18 +1446,18 @@ public class BeanMeta<T> { /* * Merges standard JavaBeans {@link BeanInfo} property descriptors into {@code normalProps}, skipping the class - * pseudo-property and logical names suppressed when {@link MarshalledIgnore#ignoreAccessors()} is <jk>true</jk> on a field. + * pseudo-property and logical names suppressed when {@link BeanIgnore#ignoreAccessors()} is <jk>true</jk> on a field. */ @SuppressWarnings({ - "java:S135" // Two continues: skip class pseudo-property and names suppressed via @MarshalledIgnore(ignoreAccessors) + "java:S135" // Two continues: skip class pseudo-property and names suppressed via @BeanIgnore(ignoreAccessors) }) private void mergeJavaBeanPropertyDescriptorsIntoNormalProps(BeanInfo bi, Map<String,BeanPropertyMeta.Builder> normalProps, PropertyNamer propertyNamer) { - var suppressedFromMarshalledIgnoredFields = findSuppressedPropertyNamesFromIgnoredFields(propertyNamer); + var suppressedFromBeanIgnoredFields = findSuppressedPropertyNamesFromIgnoredFields(propertyNamer); for (var pd : bi.getPropertyDescriptors()) { if (PROP_class.equals(pd.getName())) continue; - if (suppressedFromMarshalledIgnoredFields.contains(pd.getName())) + if (suppressedFromBeanIgnoredFields.contains(pd.getName())) continue; var builder = normalProps.computeIfAbsent(pd.getName(), n -> BeanPropertyMeta.builder(this, n)); if (pd.getReadMethod() != null) @@ -1469,24 +1469,24 @@ public class BeanMeta<T> { /* * Property names suppressed from getter/setter discovery because a non-static field with that logical name is - * annotated with {@link MarshalledIgnore @MarshalledIgnore} and {@link MarshalledIgnore#ignoreAccessors()} is <jk>true</jk>. + * annotated with {@link BeanIgnore @BeanIgnore} and {@link BeanIgnore#ignoreAccessors()} is <jk>true</jk>. * * <p> - * When {@link MarshalledIgnore#ignoreAccessors()} is <jk>false</jk> (the default), ignored fields do not suppress - * JavaBean accessors so patterns such as {@code @MarshalledIgnore} on a private field with a public {@code getX()} still + * When {@link BeanIgnore#ignoreAccessors()} is <jk>false</jk> (the default), ignored fields do not suppress + * JavaBean accessors so patterns such as {@code @BeanIgnore} on a private field with a public {@code getX()} still * expose {@code x} when field visibility excludes the field. */ @SuppressWarnings({ - "java:S135" // Two continues in inner loop: skip fields without @MarshalledIgnore or without ignoreAccessors + "java:S135" // Two continues in inner loop: skip fields without @BeanIgnore or without ignoreAccessors }) private Set<String> findSuppressedPropertyNamesFromIgnoredFields(PropertyNamer propertyNamer) { var s = new HashSet<String>(); var ap = marshallingContext.getAnnotationProvider(); for (var c2 : classHierarchy.get()) { for (var x : c2.getDeclaredFields()) { - if (! x.isNotStatic() || ! ap.has(MarshalledIgnore.class, x)) + if (! x.isNotStatic() || ! ap.has(BeanIgnore.class, x)) continue; - if (! fieldMarshalledIgnoreIgnoresAccessors(x)) + if (! fieldBeanIgnoreIgnoresAccessors(x)) continue; var name = ap.find(x).stream() .filter(x2 -> x2.isType(BeanProp.class) || x2.isType(Name.class)) @@ -1502,8 +1502,8 @@ public class BeanMeta<T> { return s; } - private static boolean fieldMarshalledIgnoreIgnoresAccessors(FieldInfo x) { - for (var bi : x.inner().getAnnotationsByType(MarshalledIgnore.class)) + private static boolean fieldBeanIgnoreIgnoresAccessors(FieldInfo x) { + for (var bi : x.inner().getAnnotationsByType(BeanIgnore.class)) if (bi.ignoreAccessors()) return true; return false; @@ -1524,7 +1524,7 @@ public class BeanMeta<T> { * <li>Is not static * <li>Is not transient (unless transient fields are not ignored) * <li>Is not annotated with {@link Transient @Transient} (unless transient fields are not ignored) - * <li>Is not annotated with {@link MarshalledIgnore @MarshalledIgnore} + * <li>Is not annotated with {@link BeanIgnore @BeanIgnore} * </ul> * * <p> @@ -1546,7 +1546,7 @@ public class BeanMeta<T> { x -> x.isNotStatic() && (x.isNotTransient() || noIgnoreTransients) && (! x.hasAnnotation(Transient.class) || noIgnoreTransients) - && ! ap.has(MarshalledIgnore.class, x) + && ! ap.has(BeanIgnore.class, x) && x.hasName(name) ).stream()) .findFirst(); diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java index 87f4496858..8093a3e2bd 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java @@ -208,6 +208,7 @@ public abstract class Context { * <ul class='javatreec'> * <li class='ja'>{@link MarshalledAnnotation} * <li class='ja'>{@link org.apache.juneau.commons.bean.BeanCtorAnnotation} + * <li class='ja'>{@link org.apache.juneau.commons.bean.BeanIgnoreAnnotation} * <li class='ja'>{@link MarshalledIgnoreAnnotation} * <li class='ja'>{@link org.apache.juneau.commons.bean.BeanPropAnnotation} * <li class='ja'>{@link MarshalledPropAnnotation} diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingContext.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingContext.java index a30c4f9b84..0573beb4c7 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingContext.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingContext.java @@ -436,7 +436,7 @@ public class MarshallingContext extends Context implements ConversionFinder { * * <h5 class='section'>Notes:</h5><ul> * <li class='note'>The {@link Bean @Marshalled} annotation can be used on a non-public bean class to override this setting. - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on a public bean class to ignore it as a bean. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a public bean class to ignore it as a bean. * </ul> * * <h5 class='section'>See Also:</h5><ul> @@ -485,7 +485,7 @@ public class MarshallingContext extends Context implements ConversionFinder { * * <h5 class='section'>Notes:</h5><ul> * <li class='note'>The {@link org.apache.juneau.commons.bean.BeanCtor @BeanCtor} annotation can also be used to expose a non-public constructor. - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on a public bean constructor to ignore it. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a public bean constructor to ignore it. * </ul> * * <h5 class='section'>See Also:</h5><ul> @@ -681,7 +681,7 @@ public class MarshallingContext extends Context implements ConversionFinder { * * <h5 class='section'>Notes:</h5><ul> * <li class='note'>The {@link org.apache.juneau.commons.bean.BeanProp @BeanProp} annotation can also be used to expose a non-public field. - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on a public bean field to ignore it as a bean property. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a public bean field to ignore it as a bean property. * </ul> * * <h5 class='section'>See Also:</h5><ul> @@ -831,7 +831,7 @@ public class MarshallingContext extends Context implements ConversionFinder { * * <h5 class='section'>Notes:</h5><ul> * <li class='note'>The {@link org.apache.juneau.commons.bean.BeanProp @BeanProp} annotation can also be used to expose a non-public method. - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on a public bean getter/setter to ignore it as a bean property. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a public bean getter/setter to ignore it as a bean property. * </ul> * * <h5 class='section'>See Also:</h5><ul> @@ -1592,7 +1592,7 @@ public class MarshallingContext extends Context implements ConversionFinder { * * <h5 class='section'>Notes:</h5><ul> * <li class='note'>The {@link Bean @Marshalled} annotation can be used on a bean class to override this setting. - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on a class to ignore it as a bean. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a class to ignore it as a bean. * </ul> * * <h5 class='section'>See Also:</h5><ul> @@ -1649,7 +1649,7 @@ public class MarshallingContext extends Context implements ConversionFinder { * * <h5 class='section'>Notes:</h5><ul> * <li class='note'>The {@link Bean @Marshalled} annotation can be used on a bean class to override this setting. - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on a class to ignore it as a bean. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a class to ignore it as a bean. * </ul> * * <h5 class='section'>See Also:</h5><ul> @@ -1704,7 +1704,7 @@ public class MarshallingContext extends Context implements ConversionFinder { * * <h5 class='section'>Notes:</h5><ul> * <li class='note'>The {@link org.apache.juneau.commons.bean.BeanProp @BeanProp} annotation can be used on the getter to override this setting. - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on getters to ignore them as bean properties. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on getters to ignore them as bean properties. * </ul> * * @return This object. @@ -1913,7 +1913,7 @@ public class MarshallingContext extends Context implements ConversionFinder { * </p> * * <h5 class='section'>Notes:</h5><ul> - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on getters and fields to ignore them. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on getters and fields to ignore them. * </ul> * * <h5 class='section'>See Also:</h5><ul> @@ -2802,11 +2802,11 @@ public class MarshallingContext extends Context implements ConversionFinder { * </p> * * <h5 class='section'>Notes:</h5><ul> - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on classes to prevent them from being recognized as beans. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on classes to prevent them from being recognized as beans. * </ul> * * <h5 class='section'>See Also:</h5><ul> - * <li class='ja'>{@link org.apache.juneau.annotation.MarshalledIgnore} + * <li class='ja'>{@link org.apache.juneau.commons.bean.BeanIgnore} * <li class='ja'>{@link org.apache.juneau.annotation.MarshalledConfig#notBeanClasses()} * </ul> * diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingContextable.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingContextable.java index f0f0ff8590..3cb72fdd8f 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingContextable.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingContextable.java @@ -167,7 +167,7 @@ public abstract class MarshallingContextable extends Context { * <h5 class='section'>Notes:</h5> * <ul> * <li class='note'>The {@link Bean @Marshalled} annotation can be used on a non-public bean class to override this setting. - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on a public bean class to ignore it as a bean. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a public bean class to ignore it as a bean. * </ul> * * <h5 class='section'>See Also:</h5> @@ -217,7 +217,7 @@ public abstract class MarshallingContextable extends Context { * * <h5 class='section'>Notes:</h5><ul> * <li class='note'>The {@link org.apache.juneau.commons.bean.BeanCtor @BeanCtor} annotation can also be used to expose a non-public constructor. - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on a public bean constructor to ignore it. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a public bean constructor to ignore it. * </ul> * * <h5 class='section'>See Also:</h5><ul> @@ -427,7 +427,7 @@ public abstract class MarshallingContextable extends Context { * * <h5 class='section'>Notes:</h5><ul> * <li class='note'>The {@link org.apache.juneau.commons.bean.BeanProp @BeanProp} annotation can also be used to expose a non-public field. - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on a public bean field to ignore it as a bean property. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a public bean field to ignore it as a bean property. * </ul> * * <h5 class='section'>See Also:</h5><ul> @@ -567,7 +567,7 @@ public abstract class MarshallingContextable extends Context { * * <h5 class='section'>Notes:</h5><ul> * <li class='note'>The {@link org.apache.juneau.commons.bean.BeanProp @BeanProp} annotation can also be used to expose a non-public method. - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on a public bean getter/setter to ignore it as a bean property. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a public bean getter/setter to ignore it as a bean property. * </ul> * * <h5 class='section'>See Also:</h5><ul> @@ -1318,7 +1318,7 @@ public abstract class MarshallingContextable extends Context { * * <h5 class='section'>Notes:</h5><ul> * <li class='note'>The {@link Bean @Marshalled} annotation can be used on a bean class to override this setting. - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on a class to ignore it as a bean. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a class to ignore it as a bean. * </ul> * * <h5 class='section'>See Also:</h5><ul> @@ -1366,7 +1366,7 @@ public abstract class MarshallingContextable extends Context { * * <h5 class='section'>Notes:</h5><ul> * <li class='note'>The {@link Bean @Marshalled} annotation can be used on a bean class to override this setting. - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on a class to ignore it as a bean. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a class to ignore it as a bean. * </ul> * * <h5 class='section'>See Also:</h5><ul> @@ -1412,7 +1412,7 @@ public abstract class MarshallingContextable extends Context { * * <h5 class='section'>Notes:</h5><ul> * <li class='note'>The {@link org.apache.juneau.commons.bean.BeanProp @BeanProp} annotation can be used on the getter to override this setting. - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on getters to ignore them as bean properties. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on getters to ignore them as bean properties. * </ul> * * <h5 class='section'>See Also:</h5><ul> @@ -1564,7 +1564,7 @@ public abstract class MarshallingContextable extends Context { * </p> * * <h5 class='section'>Notes:</h5><ul> - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on getters and fields to ignore them. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on getters and fields to ignore them. * </ul> * * <h5 class='section'>See Also:</h5><ul> @@ -2314,11 +2314,11 @@ public abstract class MarshallingContextable extends Context { * </p> * * <h5 class='section'>Notes:</h5><ul> - * <li class='note'>The {@link MarshalledIgnore @MarshalledIgnore} annotation can also be used on classes to prevent them from being recognized as beans. + * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on classes to prevent them from being recognized as beans. * </ul> * * <h5 class='section'>See Also:</h5><ul> - * <li class='ja'>{@link MarshalledIgnore} + * <li class='ja'>{@link BeanIgnore} * <li class='ja'>{@link MarshalledConfig#notBeanClasses()} * <li class='jf'>{@link MarshallingContext.Builder#notBeanClasses()} * </ul> diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanIgnoreApply.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanIgnoreApply.java new file mode 100644 index 0000000000..8a4aab6b0b --- /dev/null +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanIgnoreApply.java @@ -0,0 +1,101 @@ +/* + * 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.juneau.annotation; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +import java.lang.annotation.*; + +import org.apache.juneau.commons.bean.*; + +/** + * Dynamically applies a {@link BeanIgnore @BeanIgnore} annotation to specified classes, methods, fields, or constructors. + * + * <p> + * This annotation separates the <b>targeting</b> concern ({@link #on()}/{@link #onClass()}) from the + * <b>content</b> concern ({@link #value()}), enabling {@link BeanIgnore @BeanIgnore} to be a pure data annotation + * without marshall-specific application machinery. + * + * <h5 class='section'>Example:</h5> + * <p class='bjava'> + * <ja>@BeanIgnoreApply</ja>(on=<js>"com.example.Foo.bar"</js>, value=<ja>@BeanIgnore</ja>()) + * <jk>public class</jk> MyConfig {} + * </p> + * + * <h5 class='section'>See Also:</h5><ul> + * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a> + * </ul> + */ +@Documented +@Target({ TYPE, METHOD }) +@Retention(RUNTIME) +@Repeatable(BeanIgnoreApply.Array.class) +@ContextApply(BeanIgnoreApplyAnnotation.Applier.class) +public @interface BeanIgnoreApply { + + /** + * The {@link BeanIgnore @BeanIgnore} annotation to apply. + * + * @return The annotation value. + */ + BeanIgnore value(); + + /** + * Dynamically apply this annotation to the specified classes/methods/fields/constructors. + * + * <p> + * Identifies the targets this annotation applies to using fully-qualified names. + * + * <h5 class='section'>See Also:</h5><ul> + * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a> + * </ul> + * + * @return The annotation value. + */ + String[] on() default {}; + + /** + * Dynamically apply this annotation to the specified classes. + * + * <p> + * Identical to {@link #on()} except allows you to specify class objects instead of strings. + * + * <h5 class='section'>See Also:</h5><ul> + * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a> + * </ul> + * + * @return The annotation value. + */ + Class<?>[] onClass() default {}; + + /** + * A collection of {@link BeanIgnoreApply @BeanIgnoreApply annotations}. + */ + @Documented + @Target({ TYPE, METHOD }) + @Retention(RUNTIME) + public @interface Array { + + /** + * The child annotations. + * + * @return The annotation value. + */ + BeanIgnoreApply[] value(); + } +} diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanIgnoreApplyAnnotation.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanIgnoreApplyAnnotation.java new file mode 100644 index 0000000000..772a8db485 --- /dev/null +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanIgnoreApplyAnnotation.java @@ -0,0 +1,232 @@ +/* + * 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.juneau.annotation; + +import static org.apache.juneau.commons.utils.CollectionUtils.*; + +import java.lang.annotation.*; +import java.lang.reflect.*; + +import org.apache.juneau.*; +import org.apache.juneau.commons.annotation.*; +import org.apache.juneau.commons.bean.*; +import org.apache.juneau.commons.reflect.*; +import org.apache.juneau.svl.*; + +/** + * Utility classes and methods for the {@link BeanIgnoreApply @BeanIgnoreApply} annotation. + * + */ +public class BeanIgnoreApplyAnnotation { + + /** + * Prevents instantiation. + */ + private BeanIgnoreApplyAnnotation() {} + + /** + * Applies targeted {@link BeanIgnoreApply} annotations to a {@link org.apache.juneau.Context.Builder}. + * + * <p> + * Passes the {@link BeanIgnoreApply @BeanIgnoreApply} annotation through to the builder's annotation list. + * The {@link org.apache.juneau.commons.reflect.AnnotationProvider.Builder#addRuntimeAnnotations(java.util.List)} + * method handles unwrapping the nested {@link BeanIgnore @BeanIgnore} from {@link BeanIgnoreApply#value()} and + * registering it under the targets specified by {@link BeanIgnoreApply#on()} and {@link BeanIgnoreApply#onClass()}. + */ + public static class Applier extends AnnotationApplier<BeanIgnoreApply,Context.Builder> { + + /** + * Constructor. + * + * @param vr The resolver for resolving values in annotations. + */ + public Applier(VarResolverSession vr) { + super(BeanIgnoreApply.class, Context.Builder.class, vr); + } + + @Override + public void apply(AnnotationInfo<BeanIgnoreApply> ai, Context.Builder b) { + BeanIgnoreApply a = ai.inner(); + if (isEmptyArray(a.on()) && isEmptyArray(a.onClass())) + return; + b.annotations(a); + } + } + + /** + * Builder class. + * + * <h5 class='section'>See Also:</h5><ul> + * <li class='jm'>{@link org.apache.juneau.MarshallingContext.Builder#annotations(Annotation...)} + * </ul> + */ + public static class Builder extends AppliedAnnotationObject.BuilderTMF { + + BeanIgnore value = BeanIgnoreAnnotation.DEFAULT; + + /** + * Constructor. + */ + protected Builder() { + super(BeanIgnoreApply.class); + } + + /** + * Sets the {@link BeanIgnoreApply#value()} property on this annotation. + * + * @param value The new value for this property. + * @return This object. + */ + public Builder value(BeanIgnore value) { + this.value = value; + return this; + } + + @Override /* Overridden from AppliedAnnotationObject.Builder */ + public Builder on(String...value) { + super.on(value); + return this; + } + + @Override /* Overridden from AppliedAnnotationObject.BuilderT */ + public Builder on(Class<?>...value) { + super.on(value); + return this; + } + + @Override /* Overridden from AppliedOnClassAnnotationObject.Builder */ + public Builder onClass(Class<?>...value) { + super.onClass(value); + return this; + } + + @Override /* Overridden from AppliedAnnotationObject.BuilderM */ + public Builder on(Method...value) { + super.on(value); + return this; + } + + @Override /* Overridden from AppliedAnnotationObject.BuilderMF */ + public Builder on(Field...value) { + super.on(value); + return this; + } + + @Override /* Overridden from AppliedAnnotationObject.BuilderT */ + public Builder on(ClassInfo...value) { + super.on(value); + return this; + } + + @Override /* Overridden from AppliedAnnotationObject.BuilderT */ + public Builder onClass(ClassInfo...value) { + super.onClass(value); + return this; + } + + @Override /* Overridden from AppliedAnnotationObject.BuilderTMF */ + public Builder on(FieldInfo...value) { + super.on(value); + return this; + } + + @Override /* Overridden from AppliedAnnotationObject.BuilderTMF */ + public Builder on(MethodInfo...value) { + super.on(value); + return this; + } + + /** + * Instantiates a new {@link BeanIgnoreApply @BeanIgnoreApply} object initialized with this builder. + * + * @return A new {@link BeanIgnoreApply} object. + */ + public BeanIgnoreApply build() { + return new Object(this); + } + } + + @SuppressWarnings({ + "java:S2160" // equals() inherited from AnnotationObject compares all annotation interface methods; subclass fields are accessed via those methods + }) + private static class Object extends AppliedOnClassAnnotationObject implements BeanIgnoreApply { + + private final BeanIgnore value; + + Object(BeanIgnoreApplyAnnotation.Builder b) { + super(b); + value = b.value; + } + + @Override /* Overridden from BeanIgnoreApply */ + public BeanIgnore value() { + return value; + } + + @Override /* Overridden from BeanIgnoreApply */ + public String[] on() { + return super.on(); + } + + @Override /* Overridden from BeanIgnoreApply */ + public Class<?>[] onClass() { + return super.onClass(); + } + } + + /** Default value */ + public static final BeanIgnoreApply DEFAULT = create().build(); + + /** + * Instantiates a new builder for this class. + * + * @return A new builder object. + */ + public static Builder create() { + return new Builder(); + } + + /** + * Instantiates a new builder for this class. + * + * @param on The targets this annotation applies to. + * @return A new builder object. + */ + public static Builder create(Class<?>...on) { + return create().on(on); + } + + /** + * Instantiates a new builder for this class. + * + * @param on The targets this annotation applies to. + * @return A new builder object. + */ + public static Builder create(String...on) { + return create().on(on); + } + + /** + * Returns <jk>true</jk> if the specified annotation contains all default values. + * + * @param a The annotation to check. + * @return <jk>true</jk> if the specified annotation contains all default values. + */ + public static boolean empty(BeanIgnoreApply a) { + return a == null || DEFAULT.equals(a); + } +} diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/MarshalledIgnore.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/MarshalledIgnore.java index 0b46d43316..3418773849 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/MarshalledIgnore.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/MarshalledIgnore.java @@ -21,40 +21,40 @@ import static java.lang.annotation.RetentionPolicy.*; import java.lang.annotation.*; -import org.apache.juneau.commons.reflect.Visibility; +import org.apache.juneau.commons.bean.*; /** - * Ignore classes, fields, methods, and constructors from being interpreted as bean components, or skip a type - * entirely during serialization and parsing. + * Skip a type entirely during marshalling. * * <p> - * Behavior depends on the target: - * <ul> - * <li><b>TYPE (class)</b> — Skip this type entirely: serializers output {@code null} and parsers return - * {@code null}. Previously {@code @BeanIgnore} on a type meant "force non-bean, fall through to - * {@code toString()}". The "use toString" case is now handled by - * {@link Marshalled @Marshalled}{@code (as=STRING)}. - * <li><b>FIELD</b> — Exclude the field from bean property discovery. Use {@link #ignoreAccessors()} to also - * suppress matching JavaBean accessors. - * <li><b>METHOD</b> — Force getters/setters to be ignored. - * <li><b>CONSTRUCTOR</b> — Exclude the constructor from constructor detection. - * <li><ja>@Rest</ja>-annotated classes and <ja>@RestOp</ja>-annotated methods when used with - * {@link MarshalledIgnoreApply @MarshalledIgnoreApply}. - * </ul> + * Serializers output {@code null} for instances of the annotated type and parsers return {@code null} + * when asked to instantiate it. This is a marshalling-layer concern: the wire format renders the + * value as {@code null} regardless of what (if anything) the bean-modeling layer would do with the + * type. + * + * <p> + * Bean-modeling decisions are controlled by the sibling annotation + * {@link BeanIgnore @BeanIgnore} (in <c>juneau-commons</c>), which is responsible for excluding + * classes from bean detection ("this isn't a bean — fall through to swap/{@code @Marshalled(as=STRING)}/etc.") + * and for excluding fields, methods, and constructors from bean property/constructor detection. * - * <h5 class='section'>Java Records:</h5> * <p> - * Ignoring individual record components is not supported during parsing. - * Because records are immutable, all components must be provided to the canonical constructor. - * Applying this annotation to a record component's accessor method or field will exclude it from serialization - * output, but the parser will be unable to instantiate the record if the component value is missing from the input. + * The two annotations are independent and may be combined: + * <ul> + * <li>{@code @MarshalledIgnore} alone — the class still participates in bean detection (it may be + * treated as a bean by the modeling layer) but the marshaller emits {@code null}. + * <li>{@code @BeanIgnore} alone — the class is not a bean for modeling purposes, but the marshaller + * still tries to render it (typically via {@code toString()} or an installed swap). + * <li>Both — the class is not a bean and the marshaller emits {@code null}. + * </ul> * * <h5 class='section'>See Also:</h5><ul> + * <li class='ja'>{@link BeanIgnore} * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/MarshalledIgnoreAnnotation">@MarshalledIgnore Annotation</a> * </ul> */ @Documented -@Target({ FIELD, METHOD, TYPE, CONSTRUCTOR }) +@Target({ TYPE }) @Retention(RUNTIME) @Inherited public @interface MarshalledIgnore { @@ -67,17 +67,4 @@ public @interface MarshalledIgnore { */ String[] description() default {}; - /** - * When <jk>true</jk> and this annotation is on a <jk>field</jk>, JavaBean accessors (<c>getX</c>/<c>setX</c>, - * <c>isX</c>) for the same logical property are also excluded from bean metadata. - * - * <p> - * Default is <jk>false</jk>: {@code @MarshalledIgnore} on a field only excludes the field from field-based discovery; - * accessors can still expose the property (for example when {@link org.apache.juneau.MarshallingContext.Builder#beanFieldVisibility(Visibility) beanFieldVisibility} is {@link Visibility#NONE NONE}). Set to <jk>true</jk> to - * omit the property from serialization and parsing while keeping accessors for other frameworks. - * - * @return The annotation value. - */ - boolean ignoreAccessors() default false; - -} \ No newline at end of file +} diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/MarshalledIgnoreAnnotation.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/MarshalledIgnoreAnnotation.java index a78e194bf8..51e4252938 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/MarshalledIgnoreAnnotation.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/MarshalledIgnoreAnnotation.java @@ -43,7 +43,6 @@ public class MarshalledIgnoreAnnotation { public static class Builder extends AnnotationObject.Builder { private String[] description = {}; - private boolean ignoreAccessors; /** * Constructor. @@ -72,17 +71,6 @@ public class MarshalledIgnoreAnnotation { return this; } - /** - * Sets {@link MarshalledIgnore#ignoreAccessors()}. - * - * @param value The new value. - * @return This object. - */ - public Builder ignoreAccessors(boolean value) { - ignoreAccessors = value; - return this; - } - } @SuppressWarnings({ @@ -91,23 +79,16 @@ public class MarshalledIgnoreAnnotation { private static class Object extends AnnotationObject implements MarshalledIgnore { private final String[] description; - private final boolean ignoreAccessors; Object(MarshalledIgnoreAnnotation.Builder b) { super(b); this.description = copyOf(b.description); - this.ignoreAccessors = b.ignoreAccessors; } @Override /* Overridden from MarshalledIgnore */ public String[] description() { return description; } - - @Override /* Overridden from MarshalledIgnore */ - public boolean ignoreAccessors() { - return ignoreAccessors; - } } /** Default value */ @@ -121,4 +102,4 @@ public class MarshalledIgnoreAnnotation { public static Builder create() { return new Builder(); } -} \ No newline at end of file +} diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoListSwap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoListSwap.java index 26787fe966..688b34b26d 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoListSwap.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoListSwap.java @@ -25,6 +25,7 @@ import java.util.*; import org.apache.juneau.*; import org.apache.juneau.annotation.*; +import org.apache.juneau.commons.bean.*; import org.apache.juneau.commons.reflect.*; import org.apache.juneau.parser.*; import org.apache.juneau.serializer.*; @@ -65,14 +66,14 @@ import org.apache.juneau.serializer.*; * <p> * Classes are ignored if any of the following are true: * <ul> - * <li>Classes annotated with {@link MarshalledIgnore @MarshalledIgnore}. + * <li>Classes annotated with {@link BeanIgnore @BeanIgnore}. * <li>Non-static member classes. * </ul> * * <p> * Members/constructors are ignored if any of the following are true: * <ul> - * <li>Members/constructors annotated with {@link MarshalledIgnore @MarshalledIgnore}. + * <li>Members/constructors annotated with {@link BeanIgnore @BeanIgnore}. * <li>Deprecated members/constructors. * </ul> * @@ -133,7 +134,7 @@ public class AutoListSwap<T> extends ObjectSwap<T,List<?>> { && mi.hasAnyName(SWAP_METHOD_NAMES) && mi.hasReturnTypeParent(List.class) && mi.hasParameterTypesLenient(MarshallingSession.class) - && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(MarshalledIgnore.class, m2)); + && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(BeanIgnore.class, m2)); // @formatter:on } @@ -143,7 +144,7 @@ public class AutoListSwap<T> extends ObjectSwap<T,List<?>> { cs.isNotDeprecated() && cs.isVisible(bc.getBeanConstructorVisibility()) && cs.hasParameterTypeParents(rt) - && ! bc.getAnnotationProvider().has(MarshalledIgnore.class, cs); + && ! bc.getAnnotationProvider().has(BeanIgnore.class, cs); // @formatter:on } @@ -156,12 +157,12 @@ public class AutoListSwap<T> extends ObjectSwap<T,List<?>> { && mi.hasAnyName(UNSWAP_METHOD_NAMES) && mi.hasParameterTypesLenient(MarshallingSession.class, rt.inner()) && mi.hasReturnTypeParent(ci) - && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(MarshalledIgnore.class, m2)); + && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(BeanIgnore.class, m2)); // @formatter:on } private static boolean shouldIgnore(MarshallingContext bc, ClassInfo ci) { - return ci.isNonStaticMemberClass() || bc.getAnnotationProvider().has(MarshalledIgnore.class, ci); + return ci.isNonStaticMemberClass() || bc.getAnnotationProvider().has(BeanIgnore.class, ci); } //------------------------------------------------------------------------------------------------------------------ diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoMapSwap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoMapSwap.java index 4141845244..79d7656550 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoMapSwap.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoMapSwap.java @@ -25,6 +25,7 @@ import java.util.*; import org.apache.juneau.*; import org.apache.juneau.annotation.*; +import org.apache.juneau.commons.bean.*; import org.apache.juneau.commons.reflect.*; import org.apache.juneau.parser.*; import org.apache.juneau.serializer.*; @@ -65,14 +66,14 @@ import org.apache.juneau.serializer.*; * <p> * Classes are ignored if any of the following are true: * <ul> - * <li>Classes annotated with {@link MarshalledIgnore @MarshalledIgnore}. + * <li>Classes annotated with {@link BeanIgnore @BeanIgnore}. * <li>Non-static member classes. * </ul> * * <p> * Members/constructors are ignored if any of the following are true: * <ul> - * <li>Members/constructors annotated with {@link MarshalledIgnore @MarshalledIgnore}. + * <li>Members/constructors annotated with {@link BeanIgnore @BeanIgnore}. * <li>Deprecated members/constructors. * </ul> * @@ -133,7 +134,7 @@ public class AutoMapSwap<T> extends ObjectSwap<T,Map<?,?>> { && mi.hasAnyName(SWAP_METHOD_NAMES) && mi.hasReturnTypeParent(Map.class) && mi.hasParameterTypesLenient(MarshallingSession.class) - && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(MarshalledIgnore.class, m2)); + && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(BeanIgnore.class, m2)); // @formatter:on } @@ -143,7 +144,7 @@ public class AutoMapSwap<T> extends ObjectSwap<T,Map<?,?>> { cs.isNotDeprecated() && cs.isVisible(bc.getBeanConstructorVisibility()) && cs.hasParameterTypeParents(rt) - && ! bc.getAnnotationProvider().has(MarshalledIgnore.class, cs); + && ! bc.getAnnotationProvider().has(BeanIgnore.class, cs); // @formatter:on } @@ -156,12 +157,12 @@ public class AutoMapSwap<T> extends ObjectSwap<T,Map<?,?>> { && mi.hasAnyName(UNSWAP_METHOD_NAMES) && mi.hasParameterTypesLenient(MarshallingSession.class, rt.inner()) && mi.hasReturnTypeParent(ci) - && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(MarshalledIgnore.class, m2)); + && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(BeanIgnore.class, m2)); // @formatter:on } private static boolean shouldIgnore(MarshallingContext bc, ClassInfo ci) { - return ci.isNonStaticMemberClass() || bc.getAnnotationProvider().has(MarshalledIgnore.class, ci); + return ci.isNonStaticMemberClass() || bc.getAnnotationProvider().has(BeanIgnore.class, ci); } //------------------------------------------------------------------------------------------------------------------ diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoNumberSwap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoNumberSwap.java index 0a67d559d5..f200238e31 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoNumberSwap.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoNumberSwap.java @@ -25,6 +25,7 @@ import java.util.*; import org.apache.juneau.*; import org.apache.juneau.annotation.*; +import org.apache.juneau.commons.bean.*; import org.apache.juneau.commons.conversion.*; import org.apache.juneau.commons.reflect.*; import org.apache.juneau.parser.*; @@ -88,14 +89,14 @@ import org.apache.juneau.serializer.*; * <p> * Classes are ignored if any of the following are true: * <ul> - * <li>Classes annotated with {@link MarshalledIgnore @MarshalledIgnore}. + * <li>Classes annotated with {@link BeanIgnore @BeanIgnore}. * <li>Non-static member classes. * </ul> * * <p> * Members/constructors are ignored if any of the following are true: * <ul> - * <li>Members/constructors annotated with {@link MarshalledIgnore @MarshalledIgnore}. + * <li>Members/constructors annotated with {@link BeanIgnore @BeanIgnore}. * <li>Deprecated members/constructors. * </ul> * @@ -159,7 +160,7 @@ public class AutoNumberSwap<T> extends ObjectSwap<T,Number> { && (rt.isAssignableTo(Number.class) || (rt.isPrimitive() && rt.isAny(int.class, short.class, long.class, float.class, double.class, byte.class))) && mi.hasAnyName(SWAP_METHOD_NAMES) && mi.hasParameterTypesLenient(MarshallingSession.class) - && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(MarshalledIgnore.class, m2)); + && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(BeanIgnore.class, m2)); // @formatter:on } @@ -169,7 +170,7 @@ public class AutoNumberSwap<T> extends ObjectSwap<T,Number> { cs.isNotDeprecated() && cs.isVisible(bc.getBeanConstructorVisibility()) && cs.hasParameterTypeParents(rt) - && ! bc.getAnnotationProvider().has(MarshalledIgnore.class, cs); + && ! bc.getAnnotationProvider().has(BeanIgnore.class, cs); // @formatter:on } @@ -182,7 +183,7 @@ public class AutoNumberSwap<T> extends ObjectSwap<T,Number> { && mi.hasAnyName(UNSWAP_METHOD_NAMES) && mi.hasParameterTypesLenient(MarshallingSession.class, rt.inner()) && mi.hasReturnTypeParent(ci) - && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(MarshalledIgnore.class, m2)); + && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(BeanIgnore.class, m2)); // @formatter:on } @@ -192,7 +193,7 @@ public class AutoNumberSwap<T> extends ObjectSwap<T,Number> { ci.isNonStaticMemberClass() || ci.isPrimitive() || ci.isAssignableTo(Number.class) - || bc.getAnnotationProvider().has(MarshalledIgnore.class, ci); + || bc.getAnnotationProvider().has(BeanIgnore.class, ci); // @formatter:on } diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoObjectSwap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoObjectSwap.java index a11d580753..fd5365409f 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoObjectSwap.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/AutoObjectSwap.java @@ -25,6 +25,7 @@ import java.util.*; import org.apache.juneau.*; import org.apache.juneau.annotation.*; +import org.apache.juneau.commons.bean.*; import org.apache.juneau.commons.reflect.*; import org.apache.juneau.parser.*; import org.apache.juneau.serializer.*; @@ -67,14 +68,14 @@ import org.apache.juneau.serializer.*; * <p> * Classes are ignored if any of the following are true: * <ul> - * <li>Classes annotated with {@link MarshalledIgnore @MarshalledIgnore}. + * <li>Classes annotated with {@link BeanIgnore @BeanIgnore}. * <li>Non-static member classes. * </ul> * * <p> * Members/constructors are ignored if any of the following are true: * <ul> - * <li>Members/constructors annotated with {@link MarshalledIgnore @MarshalledIgnore}. + * <li>Members/constructors annotated with {@link BeanIgnore @BeanIgnore}. * <li>Deprecated members/constructors. * </ul> * @@ -134,7 +135,7 @@ public class AutoObjectSwap<T> extends ObjectSwap<T,Object> { && mi.isVisible(bc.getBeanMethodVisibility()) && mi.hasAnyName(SWAP_METHOD_NAMES) && mi.hasParameterTypesLenient(MarshallingSession.class) - && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(MarshalledIgnore.class, m2)); + && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(BeanIgnore.class, m2)); // @formatter:on } @@ -144,7 +145,7 @@ public class AutoObjectSwap<T> extends ObjectSwap<T,Object> { cs.isNotDeprecated() && cs.isVisible(bc.getBeanConstructorVisibility()) && cs.hasParameterTypeParents(rt) - && ! bc.getAnnotationProvider().has(MarshalledIgnore.class, cs); + && ! bc.getAnnotationProvider().has(BeanIgnore.class, cs); // @formatter:on } @@ -157,12 +158,12 @@ public class AutoObjectSwap<T> extends ObjectSwap<T,Object> { && mi.hasAnyName(UNSWAP_METHOD_NAMES) && mi.hasParameterTypesLenient(MarshallingSession.class, rt.inner()) && mi.hasReturnTypeParent(ci) - && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(MarshalledIgnore.class, m2)); + && mi.getMatchingMethods().stream().noneMatch(m2 -> bc.getAnnotationProvider().has(BeanIgnore.class, m2)); // @formatter:on } private static boolean shouldIgnore(MarshallingContext bc, ClassInfo ci) { - return ci.isNonStaticMemberClass() || bc.getAnnotationProvider().has(MarshalledIgnore.class, ci); + return ci.isNonStaticMemberClass() || bc.getAnnotationProvider().has(BeanIgnore.class, ci); } //------------------------------------------------------------------------------------------------------------------ diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/SurrogateSwap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/SurrogateSwap.java index 9ec64de53a..6ec7e13da0 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/SurrogateSwap.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/SurrogateSwap.java @@ -24,6 +24,7 @@ import java.util.*; import org.apache.juneau.*; import org.apache.juneau.annotation.*; +import org.apache.juneau.commons.bean.*; import org.apache.juneau.commons.reflect.*; import org.apache.juneau.parser.*; import org.apache.juneau.serializer.*; @@ -59,7 +60,7 @@ public class SurrogateSwap<T,F> extends ObjectSwap<T,F> { public static List<SurrogateSwap<?,?>> findObjectSwaps(Class<?> c, MarshallingContext bc) { List<SurrogateSwap<?,?>> l = new LinkedList<>(); var ci = info(c); - ci.getPublicConstructors().stream().filter(x -> ! bc.getAnnotationProvider().has(MarshalledIgnore.class, x) && x.hasNumParameters(1) && x.isPublic()).forEach(x -> { + ci.getPublicConstructors().stream().filter(x -> ! bc.getAnnotationProvider().has(BeanIgnore.class, x) && x.hasNumParameters(1) && x.isPublic()).forEach(x -> { var pt = x.getParameter(0).getParameterType().inner(); if (! pt.equals(c.getDeclaringClass())) { // Find the unswap method if there is one. diff --git a/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/entity/BasicHttpEntity.java b/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/entity/BasicHttpEntity.java index 3573f1db59..2e23867ed1 100644 --- a/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/entity/BasicHttpEntity.java +++ b/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/entity/BasicHttpEntity.java @@ -25,8 +25,8 @@ import java.nio.charset.*; import java.util.function.*; import org.apache.http.*; -import org.apache.juneau.annotation.*; import org.apache.juneau.assertions.*; +import org.apache.juneau.commons.bean.*; import org.apache.juneau.http.header.*; /** @@ -48,7 +48,7 @@ import org.apache.juneau.http.header.*; * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestCommonBasics">juneau-rest-common Basics</a> * </ul> */ -@MarshalledIgnore +@BeanIgnore @SuppressWarnings({ "resource", // Content may be streams; value equality not practical diff --git a/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/resource/BasicResource.java b/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/resource/BasicResource.java index 3336f35c47..cd3ff59474 100644 --- a/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/resource/BasicResource.java +++ b/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/resource/BasicResource.java @@ -23,8 +23,8 @@ import java.io.*; import java.util.function.*; import org.apache.http.*; -import org.apache.juneau.annotation.*; import org.apache.juneau.assertions.*; +import org.apache.juneau.commons.bean.*; import org.apache.juneau.http.entity.*; import org.apache.juneau.http.header.*; @@ -47,7 +47,7 @@ import org.apache.juneau.http.header.*; * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestCommonBasics">juneau-rest-common Basics</a> * </ul> */ -@MarshalledIgnore /* Use toString() to serialize */ +@BeanIgnore /* Use toString() to serialize */ @SuppressWarnings({ "resource", // Depends on entity (streams); value equality not practical "java:S1206", // equals/hashCode not overridden; value equality not practical for this class diff --git a/juneau-utest/src/test/java/org/apache/juneau/BeanMap_Test.java b/juneau-utest/src/test/java/org/apache/juneau/BeanMap_Test.java index 6650a346e0..28c8f62b55 100755 --- a/juneau-utest/src/test/java/org/apache/juneau/BeanMap_Test.java +++ b/juneau-utest/src/test/java/org/apache/juneau/BeanMap_Test.java @@ -1598,13 +1598,13 @@ class BeanMap_Test extends TestBase { public void setA(String v) { a = v; } public String b; - @MarshalledIgnore public String getB() { return b; } + @BeanIgnore public String getB() { return b; } public void setB(String v) { this.b = v+"(setter)"; } - @MarshalledIgnore public String c; + @BeanIgnore public String c; - @MarshalledIgnore public String getD() { return null; } - @MarshalledIgnore public void setD(String v) {} + @BeanIgnore public String getD() { return null; } + @BeanIgnore public void setD(String v) {} } @Test void a34_hiddenProperties_usingConfig() { @@ -1626,9 +1626,9 @@ class BeanMap_Test extends TestBase { assertEquals("b(setter)", t.b); } - @MarshalledIgnoreApply(on="Dummy1",value=@MarshalledIgnore()) - @MarshalledIgnoreApply(on="Uc.getB,Uc.c,Uc.getD,Uc.setD",value=@MarshalledIgnore()) - @MarshalledIgnoreApply(on="Dummy2",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="Dummy1",value=@BeanIgnore()) + @BeanIgnoreApply(on="Uc.getB,Uc.c,Uc.getD,Uc.setD",value=@BeanIgnore()) + @BeanIgnoreApply(on="Dummy2",value=@BeanIgnore()) private static class UcConfig {} public static class Uc { @@ -1637,13 +1637,13 @@ class BeanMap_Test extends TestBase { public void setA(String v) { a = v; } public String b; - @MarshalledIgnore public String getB() { return b; } + @BeanIgnore public String getB() { return b; } public void setB(String b) { this.b = b+"(setter)"; } - @MarshalledIgnore public String c; + @BeanIgnore public String c; - @MarshalledIgnore public String getD() { return null; } - @MarshalledIgnore public void setD(String v) {} + @BeanIgnore public String getD() { return null; } + @BeanIgnore public void setD(String v) {} } //==================================================================================================== diff --git a/juneau-utest/src/test/java/org/apache/juneau/TestUtils.java b/juneau-utest/src/test/java/org/apache/juneau/TestUtils.java index ca7151a681..9497e8ef3d 100644 --- a/juneau-utest/src/test/java/org/apache/juneau/TestUtils.java +++ b/juneau-utest/src/test/java/org/apache/juneau/TestUtils.java @@ -28,7 +28,7 @@ import java.util.*; import java.util.regex.*; import java.util.stream.*; -import org.apache.juneau.annotation.*; +import org.apache.juneau.commons.bean.*; import org.apache.juneau.bean.swagger.*; import org.apache.juneau.commons.utils.*; import org.apache.juneau.junit.bct.*; @@ -288,17 +288,17 @@ public class TestUtils extends Utils { var f = (Field)null; var c = o.getClass(); var n = Character.toUpperCase(name.charAt(0)) + name.substring(1); - var m = Arrays.stream(c.getMethods()).filter(x -> x.getName().equals("is"+n) && x.getParameterCount() == 0 && x.getAnnotation(MarshalledIgnore.class) == null).findFirst().orElse(null); + var m = Arrays.stream(c.getMethods()).filter(x -> x.getName().equals("is"+n) && x.getParameterCount() == 0 && x.getAnnotation(BeanIgnore.class) == null).findFirst().orElse(null); if (m != null) { m.setAccessible(true); return m.invoke(o); } - m = Arrays.stream(c.getMethods()).filter(x -> x.getName().equals("get"+n) && x.getParameterCount() == 0 && x.getAnnotation(MarshalledIgnore.class) == null).findFirst().orElse(null); + m = Arrays.stream(c.getMethods()).filter(x -> x.getName().equals("get"+n) && x.getParameterCount() == 0 && x.getAnnotation(BeanIgnore.class) == null).findFirst().orElse(null); if (m != null) { m.setAccessible(true); return m.invoke(o); } - m = Arrays.stream(c.getMethods()).filter(x -> x.getName().equals("get") && x.getParameterCount() == 1 && x.getParameterTypes()[0] == String.class && x.getAnnotation(MarshalledIgnore.class) == null).findFirst().orElse(null); + m = Arrays.stream(c.getMethods()).filter(x -> x.getName().equals("get") && x.getParameterCount() == 1 && x.getParameterTypes()[0] == String.class && x.getAnnotation(BeanIgnore.class) == null).findFirst().orElse(null); if (m != null) { m.setAccessible(true); return m.invoke(o, name); diff --git a/juneau-utest/src/test/java/org/apache/juneau/a/A1.java b/juneau-utest/src/test/java/org/apache/juneau/a/A1.java index 70aa9c32a7..495dd9e951 100755 --- a/juneau-utest/src/test/java/org/apache/juneau/a/A1.java +++ b/juneau-utest/src/test/java/org/apache/juneau/a/A1.java @@ -16,7 +16,7 @@ */ package org.apache.juneau.a; -import org.apache.juneau.annotation.*; +import org.apache.juneau.commons.bean.*; // Default class @SuppressWarnings({"unused"}) @@ -26,7 +26,7 @@ public class A1 { int f3; private int f4; - @MarshalledIgnore + @BeanIgnore private int f5, f6, f7, f8; public int getF5() { return f5; } @@ -98,7 +98,7 @@ public class A1 { int f3; private int f4; - @MarshalledIgnore + @BeanIgnore private int f5, f6, f7, f8; public int getF5() { return f5; } @@ -122,7 +122,7 @@ public class A1 { int f3; private int f4; - @MarshalledIgnore + @BeanIgnore private int f5, f6, f7, f8; public int getF5() { return f5; } @@ -146,7 +146,7 @@ public class A1 { int f3; private int f4; - @MarshalledIgnore + @BeanIgnore private int f5, f6, f7, f8; public int getF5() { return f5; } @@ -170,7 +170,7 @@ public class A1 { int f3; private int f4; - @MarshalledIgnore + @BeanIgnore private int f5, f6, f7, f8; public int getF5() { return f5; } diff --git a/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMaps_Test.java b/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMaps_Test.java index 7b280c03b5..fa9d8a01b0 100755 --- a/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMaps_Test.java +++ b/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMaps_Test.java @@ -272,7 +272,7 @@ class RoundTripBeanMaps_Test extends TestBase { @MethodSource("testers") void a05_implMap2(RoundTrip_Tester t) throws Exception { if (isMarkdown(t)) - return; // @MarshalledIgnore / getter-only properties + return; // @BeanIgnore / getter-only properties var b = new A(1); b = t.roundTrip(b); if (t.returnOriginalObject || t.getParser() == null) @@ -302,13 +302,13 @@ class RoundTripBeanMaps_Test extends TestBase { public static class A { - @MarshalledIgnore + @BeanIgnore public int f1, f2; public int f3, f4; private int f5, f6; - @MarshalledIgnore + @BeanIgnore public int getF5() { return f5; } public void setF5(int v) { f5 = v; } @@ -971,7 +971,7 @@ class RoundTripBeanMaps_Test extends TestBase { return t; } - @MarshalledIgnore public KEnum getA() { return KEnum.FOO; } + @BeanIgnore public KEnum getA() { return KEnum.FOO; } @BeanProp(name="a") public String getA2() { return a.toString(); } public void setA(KEnum v) { // This method should not be interpreted as the setter for this diff --git a/juneau-utest/src/test/java/org/apache/juneau/annotation/MarshalledIgnoreAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/annotation/BeanIgnoreAnnotation_Test.java similarity index 82% copy from juneau-utest/src/test/java/org/apache/juneau/annotation/MarshalledIgnoreAnnotation_Test.java copy to juneau-utest/src/test/java/org/apache/juneau/annotation/BeanIgnoreAnnotation_Test.java index 4c91e08e22..b3d922fa60 100644 --- a/juneau-utest/src/test/java/org/apache/juneau/annotation/MarshalledIgnoreAnnotation_Test.java +++ b/juneau-utest/src/test/java/org/apache/juneau/annotation/BeanIgnoreAnnotation_Test.java @@ -21,27 +21,30 @@ import static org.apache.juneau.junit.bct.BctAssertions.*; import static org.junit.jupiter.api.Assertions.*; import org.apache.juneau.*; +import org.apache.juneau.commons.bean.*; import org.junit.jupiter.api.*; @SuppressWarnings({ "java:S1186" // Empty test method intentional for framework testing }) -class MarshalledIgnoreAnnotation_Test extends TestBase { +class BeanIgnoreAnnotation_Test extends TestBase { //------------------------------------------------------------------------------------------------------------------ // Basic tests //------------------------------------------------------------------------------------------------------------------ - MarshalledIgnore a1 = MarshalledIgnoreAnnotation.create() + BeanIgnore a1 = BeanIgnoreAnnotation.create() .description("a") + .ignoreAccessors(true) .build(); - MarshalledIgnore a2 = MarshalledIgnoreAnnotation.create() + BeanIgnore a2 = BeanIgnoreAnnotation.create() .description("a") + .ignoreAccessors(true) .build(); @Test void a01_basic() { - assertBean(a1, "description,ignoreAccessors", "[a],false"); + assertBean(a1, "description,ignoreAccessors", "[a],true"); } @Test void a02_testEquivalency() { @@ -65,21 +68,23 @@ class MarshalledIgnoreAnnotation_Test extends TestBase { // Comparison with declared annotations. //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnore( - description={ "a" } + @BeanIgnore( + description={ "a" }, + ignoreAccessors=true ) public static class D1 {} - MarshalledIgnore d1 = D1.class.getAnnotationsByType(MarshalledIgnore.class)[0]; + BeanIgnore d1 = D1.class.getAnnotationsByType(BeanIgnore.class)[0]; - @MarshalledIgnore( - description={ "a" } + @BeanIgnore( + description={ "a" }, + ignoreAccessors=true ) public static class D2 {} - MarshalledIgnore d2 = D2.class.getAnnotationsByType(MarshalledIgnore.class)[0]; + BeanIgnore d2 = D2.class.getAnnotationsByType(BeanIgnore.class)[0]; @Test void d01_comparisonWithDeclarativeAnnotations() { assertEqualsAll(a1, d1, d2); assertNotEqualsAny(a1.hashCode(), 0, -1); assertEqualsAll(a1.hashCode(), d1.hashCode(), d2.hashCode()); } -} \ No newline at end of file +} diff --git a/juneau-utest/src/test/java/org/apache/juneau/annotation/MarshalledIgnore_Test.java b/juneau-utest/src/test/java/org/apache/juneau/annotation/BeanIgnore_Test.java similarity index 72% copy from juneau-utest/src/test/java/org/apache/juneau/annotation/MarshalledIgnore_Test.java copy to juneau-utest/src/test/java/org/apache/juneau/annotation/BeanIgnore_Test.java index 40e921d981..78867b208a 100644 --- a/juneau-utest/src/test/java/org/apache/juneau/annotation/MarshalledIgnore_Test.java +++ b/juneau-utest/src/test/java/org/apache/juneau/annotation/BeanIgnore_Test.java @@ -20,13 +20,14 @@ import static org.apache.juneau.TestUtils.*; import static org.junit.jupiter.api.Assertions.*; import org.apache.juneau.*; +import org.apache.juneau.commons.bean.*; import org.apache.juneau.json5.*; import org.junit.jupiter.api.*; -class MarshalledIgnore_Test extends TestBase { +class BeanIgnore_Test extends TestBase { //------------------------------------------------------------------------------------------------------------------ - // Test @MarshalledIgnore on properties + // Test @BeanIgnore on properties (fields, methods). //------------------------------------------------------------------------------------------------------------------ public static class A { @@ -34,22 +35,22 @@ class MarshalledIgnore_Test extends TestBase { return "a"; } - @MarshalledIgnore + @BeanIgnore public String getB() { return "b"; } public String c = "c"; - @MarshalledIgnore public String d = "d"; + @BeanIgnore public String d = "d"; } @Test void a01_beanIgnoreOnProperties() { assertJson("{a:'a',c:'c'}", new A()); } - @MarshalledIgnoreApply(on="Ac.getB",value=@MarshalledIgnore()) - @MarshalledIgnoreApply(on="Ac.d",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="Ac.getB",value=@BeanIgnore()) + @BeanIgnoreApply(on="Ac.d",value=@BeanIgnore()) private static class AcConfig {} public static class Ac { @@ -71,65 +72,13 @@ class MarshalledIgnore_Test extends TestBase { } //------------------------------------------------------------------------------------------------------------------ - // Test @MarshalledIgnore on classes - //------------------------------------------------------------------------------------------------------------------ - - @MarshalledIgnore - public static class B1 { - public int f = 1; - - @Override - public String toString() { - return "xxx"; - } - } - - public static class B { - public int f2 = 2; - public B1 f3 = new B1(); - - public B1 getF4() { - return new B1(); - } - } - - @Test void a03_beanIgnoreOnBean() { - assertJson("{f2:2,f3:null,f4:null}", new B()); - } - - @MarshalledIgnoreApply(on="B1c",value=@MarshalledIgnore()) - private static class B1cConfig {} - - public static class B1c { - public int f = 1; - - @Override - public String toString() { - return "xxx"; - } - } - - public static class Bc { - public int f2 = 2; - public B1c f3 = new B1c(); - - public B1c getF4() { - return new B1c(); - } - } - - @Test void a04_beanIgnoreOnBean_usingConfig() { - assertSerialized(new Bc(), Json5Serializer.DEFAULT.copy().applyAnnotations(B1cConfig.class).build(), "{f2:2,f3:null,f4:null}"); - } - - //------------------------------------------------------------------------------------------------------------------ - // @MarshalledIgnore on private field: suppress accessor pair from bean metadata (default + JavaBean introspector) + // @BeanIgnore on private field: suppress accessor pair from bean metadata (default + JavaBean introspector). //------------------------------------------------------------------------------------------------------------------ public static class PrivateFieldIgnoredWithAccessors { public String visible = "ok"; - @MarshalledIgnore(ignoreAccessors = true) + @BeanIgnore(ignoreAccessors = true) private String foo = "secret"; public String getVisible() { @@ -149,16 +98,44 @@ class MarshalledIgnore_Test extends TestBase { } } - @Test void a05_beanIgnoreOnPrivateFieldSuppressesGetterProperty() { + @Test void a03_beanIgnoreOnPrivateFieldSuppressesGetterProperty() { var bm = MarshallingContext.DEFAULT.getBeanMeta(PrivateFieldIgnoredWithAccessors.class); assertFalse(bm.getProperties().containsKey("foo"), () -> "properties: " + bm.getProperties().keySet()); assertJson("{visible:'ok'}", new PrivateFieldIgnoredWithAccessors()); } - @Test void a06_beanIgnoreOnPrivateField_suppressedWithJavaBeanIntrospector() { + @Test void a04_beanIgnoreOnPrivateField_suppressedWithJavaBeanIntrospector() { var bc = MarshallingContext.create().useJavaBeanIntrospector().build(); var s = Json5Serializer.DEFAULT.copy().marshallingContext(bc).build(); assertFalse(bc.getBeanMeta(PrivateFieldIgnoredWithAccessors.class).getProperties().containsKey("foo")); assertEquals("{visible:'ok'}", s.serialize(new PrivateFieldIgnoredWithAccessors())); } -} \ No newline at end of file + + //------------------------------------------------------------------------------------------------------------------ + // @BeanIgnore on TYPE — marks the class as not a bean. + // The marshaller falls through to other type detection (e.g. toString() via AutoStringSwap). + //------------------------------------------------------------------------------------------------------------------ + + @BeanIgnore + public static class C1 { + public int f = 1; + + @Override + public String toString() { + return "xxx"; + } + } + + public static class C { + public int f2 = 2; + public C1 f3 = new C1(); + + public C1 getF4() { + return new C1(); + } + } + + @Test void a05_beanIgnoreOnType_fallsThroughToToString() { + assertJson("{f2:2,f3:'xxx',f4:'xxx'}", new C()); + } +} diff --git a/juneau-utest/src/test/java/org/apache/juneau/annotation/MarshalledIgnoreAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/annotation/MarshalledIgnoreAnnotation_Test.java index 4c91e08e22..e40623a1ca 100644 --- a/juneau-utest/src/test/java/org/apache/juneau/annotation/MarshalledIgnoreAnnotation_Test.java +++ b/juneau-utest/src/test/java/org/apache/juneau/annotation/MarshalledIgnoreAnnotation_Test.java @@ -41,7 +41,7 @@ class MarshalledIgnoreAnnotation_Test extends TestBase { .build(); @Test void a01_basic() { - assertBean(a1, "description,ignoreAccessors", "[a],false"); + assertBean(a1, "description", "[a]"); } @Test void a02_testEquivalency() { diff --git a/juneau-utest/src/test/java/org/apache/juneau/annotation/MarshalledIgnore_Test.java b/juneau-utest/src/test/java/org/apache/juneau/annotation/MarshalledIgnore_Test.java index 40e921d981..c46b5d745d 100644 --- a/juneau-utest/src/test/java/org/apache/juneau/annotation/MarshalledIgnore_Test.java +++ b/juneau-utest/src/test/java/org/apache/juneau/annotation/MarshalledIgnore_Test.java @@ -17,7 +17,6 @@ package org.apache.juneau.annotation; import static org.apache.juneau.TestUtils.*; -import static org.junit.jupiter.api.Assertions.*; import org.apache.juneau.*; import org.apache.juneau.json5.*; @@ -26,52 +25,7 @@ import org.junit.jupiter.api.*; class MarshalledIgnore_Test extends TestBase { //------------------------------------------------------------------------------------------------------------------ - // Test @MarshalledIgnore on properties - //------------------------------------------------------------------------------------------------------------------ - - public static class A { - public String getA() { - return "a"; - } - - @MarshalledIgnore - public String getB() { - return "b"; - } - - public String c = "c"; - - @MarshalledIgnore public String d = "d"; - } - - @Test void a01_beanIgnoreOnProperties() { - assertJson("{a:'a',c:'c'}", new A()); - } - - @MarshalledIgnoreApply(on="Ac.getB",value=@MarshalledIgnore()) - @MarshalledIgnoreApply(on="Ac.d",value=@MarshalledIgnore()) - private static class AcConfig {} - - public static class Ac { - public String getA() { - return "a"; - } - - public String getB() { - return "b"; - } - - public String c = "c"; - - public String d = "d"; - } - - @Test void a02_beanIgnoreOnProperties_usingConfig() { - assertSerialized(new Ac(), Json5Serializer.DEFAULT.copy().applyAnnotations(AcConfig.class).build(), "{a:'a',c:'c'}"); - } - - //------------------------------------------------------------------------------------------------------------------ - // Test @MarshalledIgnore on classes + // @MarshalledIgnore on TYPE — skip entirely during marshalling: serializers output null, parsers return null. //------------------------------------------------------------------------------------------------------------------ @MarshalledIgnore @@ -93,7 +47,7 @@ class MarshalledIgnore_Test extends TestBase { } } - @Test void a03_beanIgnoreOnBean() { + @Test void a01_marshalledIgnoreOnType() { assertJson("{f2:2,f3:null,f4:null}", new B()); } @@ -118,47 +72,7 @@ class MarshalledIgnore_Test extends TestBase { } } - @Test void a04_beanIgnoreOnBean_usingConfig() { + @Test void a02_marshalledIgnoreOnType_usingConfig() { assertSerialized(new Bc(), Json5Serializer.DEFAULT.copy().applyAnnotations(B1cConfig.class).build(), "{f2:2,f3:null,f4:null}"); } - - //------------------------------------------------------------------------------------------------------------------ - // @MarshalledIgnore on private field: suppress accessor pair from bean metadata (default + JavaBean introspector) - //------------------------------------------------------------------------------------------------------------------ - - public static class PrivateFieldIgnoredWithAccessors { - public String visible = "ok"; - - @MarshalledIgnore(ignoreAccessors = true) - private String foo = "secret"; - - public String getVisible() { - return visible; - } - - public void setVisible(String value) { - visible = value; - } - - public String getFoo() { - return foo; - } - - public void setFoo(String value) { - foo = value; - } - } - - @Test void a05_beanIgnoreOnPrivateFieldSuppressesGetterProperty() { - var bm = MarshallingContext.DEFAULT.getBeanMeta(PrivateFieldIgnoredWithAccessors.class); - assertFalse(bm.getProperties().containsKey("foo"), () -> "properties: " + bm.getProperties().keySet()); - assertJson("{visible:'ok'}", new PrivateFieldIgnoredWithAccessors()); - } - - @Test void a06_beanIgnoreOnPrivateField_suppressedWithJavaBeanIntrospector() { - var bc = MarshallingContext.create().useJavaBeanIntrospector().build(); - var s = Json5Serializer.DEFAULT.copy().marshallingContext(bc).build(); - assertFalse(bc.getBeanMeta(PrivateFieldIgnoredWithAccessors.class).getProperties().containsKey("foo")); - assertEquals("{visible:'ok'}", s.serialize(new PrivateFieldIgnoredWithAccessors())); - } -} \ No newline at end of file +} diff --git a/juneau-utest/src/test/java/org/apache/juneau/transform/AutoListSwapTest.java b/juneau-utest/src/test/java/org/apache/juneau/transform/AutoListSwapTest.java index 6241b0253c..227adb5bea 100644 --- a/juneau-utest/src/test/java/org/apache/juneau/transform/AutoListSwapTest.java +++ b/juneau-utest/src/test/java/org/apache/juneau/transform/AutoListSwapTest.java @@ -25,6 +25,7 @@ import java.util.*; import org.apache.juneau.*; import org.apache.juneau.annotation.*; import org.apache.juneau.collections.*; +import org.apache.juneau.commons.bean.*; import org.apache.juneau.commons.reflect.*; import org.apache.juneau.parser.*; import org.apache.juneau.serializer.*; @@ -172,7 +173,7 @@ class AutoListSwapTest extends TestBase { // Ignore class //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnore + @BeanIgnore public static class D01 { public List<String> toList() { return STRINGLIST; @@ -194,7 +195,7 @@ class AutoListSwapTest extends TestBase { assertNull(find(D02.D02A.class)); } - @MarshalledIgnoreApply(on="D01c",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="D01c",value=@BeanIgnore()) private static class D01cConfig {} public static class D01c { @@ -222,11 +223,11 @@ class AutoListSwapTest extends TestBase { // Ignore swap method //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnoreApply(on="E01c.toList",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="E01c.toList",value=@BeanIgnore()) private static class E01Config {} public static class E01 { - @MarshalledIgnore + @BeanIgnore public List<String> toList() { return STRINGLIST; } @@ -286,14 +287,14 @@ class AutoListSwapTest extends TestBase { // Ignore unswap method //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnoreApply(on="F01c.create",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="F01c.create",value=@BeanIgnore()) private static class F01Config {} public static class F01 { public List<String> toList() { return STRINGLIST; } - @MarshalledIgnore + @BeanIgnore public static F01 create(List<String> o) { return null; } @@ -387,11 +388,11 @@ class AutoListSwapTest extends TestBase { // Ignore constructor //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnoreApply(on="G01c(List)",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="G01c(List)",value=@BeanIgnore()) private static class G01Config {} public static class G01 { - @MarshalledIgnore + @BeanIgnore public G01(List<String> o) {} public List<String> toList() { return STRINGLIST; diff --git a/juneau-utest/src/test/java/org/apache/juneau/transform/AutoMapSwapTest.java b/juneau-utest/src/test/java/org/apache/juneau/transform/AutoMapSwapTest.java index e01a210f99..ab340b8e82 100644 --- a/juneau-utest/src/test/java/org/apache/juneau/transform/AutoMapSwapTest.java +++ b/juneau-utest/src/test/java/org/apache/juneau/transform/AutoMapSwapTest.java @@ -26,6 +26,7 @@ import java.util.*; import org.apache.juneau.*; import org.apache.juneau.annotation.*; import org.apache.juneau.collections.*; +import org.apache.juneau.commons.bean.*; import org.apache.juneau.commons.reflect.*; import org.apache.juneau.parser.*; import org.apache.juneau.serializer.*; @@ -179,10 +180,10 @@ class AutoMapSwapTest extends TestBase { // Ignore class //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnoreApply(on="D01c",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="D01c",value=@BeanIgnore()) private static class D01Config {} - @MarshalledIgnore + @BeanIgnore public static class D01 { public Map<String,String> toMap() { return STRINGMAP; @@ -217,11 +218,11 @@ class AutoMapSwapTest extends TestBase { // Ignore swap method //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnoreApply(on="E01c.toMap",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="E01c.toMap",value=@BeanIgnore()) private static class E01Config {} public static class E01 { - @MarshalledIgnore + @BeanIgnore public Map<String,String> toMap() { return STRINGMAP; } @@ -281,14 +282,14 @@ class AutoMapSwapTest extends TestBase { // Ignore unswap method //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnoreApply(on="F01c.create(Map)",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="F01c.create(Map)",value=@BeanIgnore()) private static class F01Config {} public static class F01 { public Map<String,String> toMap() { return STRINGMAP; } - @MarshalledIgnore + @BeanIgnore public static F01 create(Map<String,String> o) { return null; } @@ -382,11 +383,11 @@ class AutoMapSwapTest extends TestBase { // Ignore constructor //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnoreApply(on="G01c(Map)",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="G01c(Map)",value=@BeanIgnore()) private static class G01Config {} public static class G01 { - @MarshalledIgnore + @BeanIgnore public G01(Map<String,String> o) {} public Map<String,String> toMap() { return STRINGMAP; diff --git a/juneau-utest/src/test/java/org/apache/juneau/transform/AutoNumberSwapTest.java b/juneau-utest/src/test/java/org/apache/juneau/transform/AutoNumberSwapTest.java index 8c360d05a5..db95377a02 100644 --- a/juneau-utest/src/test/java/org/apache/juneau/transform/AutoNumberSwapTest.java +++ b/juneau-utest/src/test/java/org/apache/juneau/transform/AutoNumberSwapTest.java @@ -23,6 +23,7 @@ import java.util.*; import org.apache.juneau.*; import org.apache.juneau.annotation.*; +import org.apache.juneau.commons.bean.*; import org.apache.juneau.commons.reflect.*; import org.apache.juneau.parser.*; import org.apache.juneau.serializer.*; @@ -564,10 +565,10 @@ class AutoNumberSwapTest extends TestBase { // Ignore class //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnoreApply(on="D01c",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="D01c",value=@BeanIgnore()) private static class D01Config {} - @MarshalledIgnore + @BeanIgnore public static class D01 { public Integer toInteger() { return 1; @@ -612,11 +613,11 @@ class AutoNumberSwapTest extends TestBase { // Ignore swap method //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnoreApply(on="E01c.toInteger",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="E01c.toInteger",value=@BeanIgnore()) private static class E01Config {} public static class E01 { - @MarshalledIgnore + @BeanIgnore public Integer toInteger() { return 1; } @@ -676,14 +677,14 @@ class AutoNumberSwapTest extends TestBase { // Ignore unswap method //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnoreApply(on="F01c.create(java.lang.Integer)",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="F01c.create(java.lang.Integer)",value=@BeanIgnore()) private static class F01Config {} public static class F01 { public Integer toInteger() { return 1; } - @MarshalledIgnore + @BeanIgnore public static F01 create(Integer o) { return null; } @@ -777,11 +778,11 @@ class AutoNumberSwapTest extends TestBase { // Ignore constructor //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnoreApply(on="G01c(java.lang.Integer)",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="G01c(java.lang.Integer)",value=@BeanIgnore()) private static class G01Config {} public static class G01 { - @MarshalledIgnore + @BeanIgnore public G01(Integer o) {} public Integer toInteger() { return 1; diff --git a/juneau-utest/src/test/java/org/apache/juneau/transform/AutoObjectSwapTest.java b/juneau-utest/src/test/java/org/apache/juneau/transform/AutoObjectSwapTest.java index 82b7b83fc2..556ab8b070 100644 --- a/juneau-utest/src/test/java/org/apache/juneau/transform/AutoObjectSwapTest.java +++ b/juneau-utest/src/test/java/org/apache/juneau/transform/AutoObjectSwapTest.java @@ -26,6 +26,7 @@ import java.util.*; import org.apache.juneau.*; import org.apache.juneau.annotation.*; import org.apache.juneau.collections.*; +import org.apache.juneau.commons.bean.*; import org.apache.juneau.commons.reflect.*; import org.apache.juneau.parser.*; import org.apache.juneau.serializer.*; @@ -174,10 +175,10 @@ class AutoObjectSwapTest extends TestBase { // Ignore class //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnoreApply(on="D01c",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="D01c",value=@BeanIgnore()) private static class D01Config {} - @MarshalledIgnore + @BeanIgnore public static class D01 { public Map<String,String> swap() { return STRINGMAP; @@ -212,11 +213,11 @@ class AutoObjectSwapTest extends TestBase { // Ignore swap method //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnoreApply(on="E01c.swap",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="E01c.swap",value=@BeanIgnore()) private static class E01Config {} public static class E01 { - @MarshalledIgnore + @BeanIgnore public Map<String,String> swap() { return STRINGMAP; } @@ -267,14 +268,14 @@ class AutoObjectSwapTest extends TestBase { // Ignore unswap method //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnoreApply(on="F01c.create(java.util.Map)",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="F01c.create(java.util.Map)",value=@BeanIgnore()) private static class F01Config {} public static class F01 { public Map<String,String> swap() { return STRINGMAP; } - @MarshalledIgnore + @BeanIgnore public static F01 create(Map<String,String> o) { return null; } @@ -368,11 +369,11 @@ class AutoObjectSwapTest extends TestBase { // Ignore constructor //------------------------------------------------------------------------------------------------------------------ - @MarshalledIgnoreApply(on="G01c(Map)",value=@MarshalledIgnore()) + @BeanIgnoreApply(on="G01c(Map)",value=@BeanIgnore()) private static class G01Config {} public static class G01 { - @MarshalledIgnore + @BeanIgnore public G01(Map<String,String> o) {} public Map<String,String> swap() { return STRINGMAP;
