org.apache.juneau.annotation.BeanProperty Maven / Gradle / Ivy
// ***************************************************************************************************************************
// * 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.*;
/**
* Used tailor how bean properties get interpreted by the framework.
*
*
* This annotation is applied to public fields and public getter/setter methods of beans.
*
*
See Also:
*
* - {@doc juneau-marshall.Transforms.BeanPropertyAnnotation}
*
*/
@Documented
@Target({FIELD,METHOD})
@Retention(RUNTIME)
@Inherited
public @interface BeanProperty {
/**
* Identifies the name of the property.
*
*
* Normally, this is automatically inferred from the field name or getter method name of the property.
* However, this property can be used to assign a different property name from the automatically inferred value.
*
*
* If the {@link BeanContext#BEAN_beanFieldVisibility} setting on the bean context excludes this field (e.g. the
* visibility is set to PUBLIC, but the field is PROTECTED), this annotation can be used to force the field to be
* identified as a property.
*
*
Dynamic beans
*
* The bean property named "*" is the designated "dynamic property" which allows for "extra" bean
* properties not otherwise defined.
* This is similar in concept to the Jackson @JsonGetterAll and @JsonSetterAll annotations.
* The primary purpose is for backwards compatibility in parsing newer streams with addition information into older
* beans.
*
*
* The following examples show how to define dynamic bean properties.
*
* // Option #1 - A simple public Map field.
* // The field name can be anything.
* public class BeanWithDynaField {
*
* @BeanProperty (name="*" )
* public Map<String,Object> extraStuff = new LinkedHashMap<String,Object>();
* }
*
* // Option #2 - Getters and setters.
* // Method names can be anything.
* // Getter must return a Map with String keys.
* // Setter must take in two arguments.
* public class BeanWithDynaMethods {
*
* @BeanProperty (name="*" )
* public Map<String,Object> getMyExtraStuff() {
* ...
* }
*
* @BeanProperty (name="*" )
* public void setAnExtraField(String name, Object value) {
* ...
* }
* }
*
* // Option #3 - Getter only.
* // Properties will be added through the getter.
* public class BeanWithDynaGetterOnly {
*
* @BeanProperty (name="*" )
* public Map<String,Object> getMyExtraStuff() {
* ...
* }
* }
*
* // Option #4 - Getter, setter, and extra-keys method .
* // Define a method that returns a Collection<String> with currently-set property names.
* public class BeanWithDynaExtraKeys {
*
* @BeanProperty (name="*" )
* public Object get(String name) {
* ...
* }
*
* @BeanProperty (name="*" )
* public void set(String name, Object value) {
* ...
* }
*
* @BeanProperty (name="*" )
* public Collection<String> extraKeys() {
* ...
* }
* }
*
*
*
* Similar rules apply for value types and swaps.
* The property values optionally can be any serializable type or use swaps.
*
* // A serializable type other than Object.
* public class BeanWithDynaFieldWithListValues {
*
* @BeanProperty (name="*" )
* public Map<String,List<String>> getMyExtraStuff() {
* ...
* }
* }
*
* // A swapped value.
* public class BeanWithDynaFieldWithSwappedValues {
*
* @BeanProperty (name="*" , swap=CalendarSwap.ISO8601DTZ .class )
* public Map<String,Calendar> getMyExtraStuff() {
* ...
* }
* }
*
*
*
* -
* Note that if you're not interested in these additional properties, you can also use the
* {@link BeanContext#BEAN_ignoreUnknownBeanProperties} setting to ignore values that don't fit into existing
* properties.
*
*/
String name() default "";
/**
* A synonym for {@link #name()}.
*
*
* The following annotations are equivalent:
*
*
* @BeanProperty (name="foo" )
*
* @BeanProperty ("foo" )
*
*/
String value() default "";
/**
* Identifies a specialized class type for the property.
*
*
* Normally this can be inferred through reflection of the field type or getter return type.
* However, you'll want to specify this value if you're parsing beans where the bean property class is an interface
* or abstract class to identify the bean type to instantiate.
* Otherwise, you may cause an {@link InstantiationException} when trying to set these fields.
*
*
* This property must denote a concrete bean class with a no-arg constructor.
*
*
Example:
*
* public class MyBean {
*
* // Identify concrete map type.
* @BeanProperty (type=HashMap.class )
* public Map p1 ;
* }
*
*/
Class> type() default Object.class;
/**
* For bean properties of maps and collections, this annotation can be used to identify the class types of the
* contents of the bean property object when the generic parameter types are interfaces or abstract classes.
*
* Example:
*
* public class MyBean {
*
* // Identify concrete map type with String keys and Integer values.
* @BeanProperty (type=HashMap.class , params={String.class ,Integer.class })
* public Map p1 ;
* }
*
*/
Class>[] params() default {};
/**
* Used to limit which child properties are rendered by the serializers.
*
*
* Can be used on any of the following bean property types:
*
* - Beans - Only render the specified properties of the bean.
*
- Maps - Only render the specified entries in the map.
*
- Bean/Map arrays - Same, but applied to each element in the array.
*
- Bean/Map collections - Same, but applied to each element in the collection.
*
*
* Example:
*
* public class MyClass {
*
* // Only render 'f1' when serializing this bean property.
* @BeanProperty (properties="f1" )
* public MyChildClass x1 = new MyChildClass();
* }
*
* public class MyChildClass {
* public int f1 = 1;
* public int f2 = 2;
* }
*
* // Renders "{x1:{f1:1}}"
* String json = JsonSerializer.DEFAULT .serialize(new MyClass());
*
*/
String properties() default "";
/**
* Bean dictionary.
*
*
* The list of classes that make up the bean dictionary this bean property.
*
*
See Also:
*
* - {@link BeanContext#BEAN_beanDictionary}
*
*/
Class>[] beanDictionary() default {};
/**
* Specifies a String format for converting the bean property value to a formatted string.
*
*
* Note that this is usually a one-way conversion during serialization.
*
*
* During parsing, we will attempt to convert the value to the original form by using the
* {@link BeanSession#convertToType(Object, Class)} but there is no guarantee that this will succeed.
*
*
Example:
*
* @BeanProperty (format="$%.2f" )
* public float price ;
*
*/
String format() default "";
}