
net.java.html.json.ComputedProperty Maven / Gradle / Ivy
Show all versions of net.java.html.json Show documentation
/**
* 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 net.java.html.json;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.netbeans.html.json.spi.Technology;
/** Can be used in classes annotated with {@link Model} annotation to
* define a derived property. Value of derived property is based on values
* of regular {@link Property properties} as specified by {@link Model#properties()}.
* The name of the computed/derived property is the name of the annotated method.
*
* Classic Example
*
* Imagine one wants to represent a formula with two variables and certain
* computations performed on top of them. One can represent such computations
* with {@code @ComputedProperty}:
*
* {@codesnippet net.java.html.json.SquaresTest}
*
* There are two variables {@code a} and {@code b} with appropriate getters and
* setters. In addition there are derived properties {@code plus}, {@code minus}
* and {@code aPlusBTimesAMinusB} which is based on the previous two derived
* properties. The usage then follows classical bean patterns:
*
*
* {@codesnippet net.java.html.json.SquaresTest#threeAndTwo}
* {@codesnippet net.java.html.json.SquaresTest#fiveAndTwo}
*
*
* Shorthand Syntax
*
* Sometimes using the getters to compute a property may lead to unnecessary
* verbosity. As such there is a shorthand syntax for defining the derived
* properties. Rather than writing:
*
* {@codesnippet net.java.html.json.SquaresTest#aSquareMinusBSquareClassic}
*
* one can choose decomposition - pattern matching and name the
* properties one wants to access in the signature of the method:
*
* {@codesnippet net.java.html.json.SquaresTest#aSquareMinusBSquare}
*
* The arguments
* of the method must match names and types of some of the properties
* from {@link Model#properties()} list.
*
* As soon as one of the properties the derived property method is accessing
* changes, the method is called again to recompute its new value and the
* change is notified to the underlying {@linkplain Technology (rendering) technology}.
*
* Method's return type defines the type of the derived property. It may be
* any primitive type, {@link String}, {@link Enum enum type} or a
* type generated by {@link Model @Model} annotation. One may
* also return a list of such (boxed) type
* (for example {@link java.util.List List}<{@link String}> or {@link java.util.List List}<{@link Integer}>).
*
* An example testing
* whether a number is a prime using a {@link ComputedProperty} is available
* on-line.
*
* @author Jaroslav Tulach
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
public @interface ComputedProperty {
/** Defines mutable computed property.
* The value of this attribute references another method in the same class
* by its name. The method is then called to handle changes to this computed property
* made by its generated setter.
*
* By default the computed properties are read-only (e.g. they only have a getter),
* however one can make them mutable by defining a static method that takes
* two parameters:
*
* - model class - provides access to "this" and
* allows you to call appropriate setters in response of changing
* the computed property value
*
* - value - either exactly of the same type as is the return type of the annotated method
* or a superclass (like {@link Object}) of that type
*
*
*
* Power of a Value Example
*
* Imagine you want to compute power of a number. You can define simple
* model class and a computed property {@code pow} inside it:
*
* {@codesnippet net.java.html.json.PowerTest}
*
* Such code allows you to find out that the power of three is nine:
*
* {@codesnippet net.java.html.json.PowerTest#computesPower}
*
* However you can change the above example to also compute a square of the
* value by making the {@code power} property writable:
*
* {@codesnippet net.java.html.json.PowerTest#sqrt}
*
* Then it is possible to use the same model to find out that square of four
* is two:
*
* {@codesnippet net.java.html.json.PowerTest#canSetComputedProperty}
*
* Implementation note:
* There cannot be two properties of the same name and different
* behavior and as such the example is using two properties {@code pow}
* and {@code power}. One of them is read-only and the second is writable.
* The body of both methods is the same however.
*
* @return the name of a method to handle changes to the computed
* property
* @since 1.2
*/
public String write() default "";
}