Property - Google Project Hosting

Download Report

Transcript Property - Google Project Hosting

Java Properties
BeanUtopia
Yardena Meymann
February 2008
What is a property?
Property is an element of data type
description. For example, name of
objects of type Person.
It consists of a symbolic token “name”
associated with a certain (owner) data
type and another (value) data type.
Property are used to describe and
manipulate data of various kinds
(databases, UI, …)
Property in modern Object
Oriented languages
Java, C++, C#, Delphi
(Also known as field)
 Properties defined by owner classes
 Property values are stored in and accessed
via the owner object instance
 Inheritance of properties
 Override of properties
 Access methods defined in the owner class
(getter/setter)
 Property references are not part of the core
language, can be accessed via reflection on
owner classes
Property in databases and
SQL
(Usually called columns)
 Can be referenced via owner type (table),
regardless of owner instance; used to
construct expressions
 Can be manipulated (added, removed,
changed) via operations on owner type
 Can have constraints and triggers
 Can be computed or stored
 Storage method is abstracted from the user
(can be row-based or column-based)
Property anatomy
Property
type
Value
type
Value
instance
Owner
type
Property
instance
Owner
instance
Properties in Java:
JavaBeans
Actual fields are usually private for
encapsulation purposes
 Most common way of exposing properties in
Java is JavaBeans naming convention,
essentially a pair of methods with get and
set prefixes.
 java.beans.* package (aimed mainly for UI
components) adds more abstraction layers
over basic beans, but does not solve the
problems discussed in the next slides
Properties in Java: Maps



HashMap, HashTable, etc. are different
implementations that store properties by
generic key:value pairs
Maps allow “dynamic” properties – unless
the key is an enum type, set of keys is not
restricted by the compiler
To store multi-type values the Map is
defined to accept the most specific common
value type or a some canonic (e.g. String)
representation of the value – not type-safe
Typical JEE Application
Example
Browser
Transform
HttpRequest
Strings map or
XML to object
Servlet
Pass objects
through set of
rules and
policies
Business
Logic
Map object to
relational
representation:
templates or
ORM
Single user operation
processing round-trip
Browser
JSP/JSF/…
JEE
Tier
Data
Access
Business
Logic
Data
Access
Database
Template around
object properties,
transform to view
representation
Postprocess
results
Transform map-like
ResultSet entries
to objects: DAO or
ORM
Typical JSE Application
Swing: Beans Binding JSR 295
Conclusion: Java needs proper
support for properties.
Flaws of Java Properties






JavaBean properties are verbose
a lot of manual boiler plate coding
Reference to properties by String only
error prone
No way to add properties to beans
redefinition only by means of bytecode manipulation and
aspects
No property declaration
Cannot associate meta-data, aspects
No abstraction over different implementations:
beans and maps (BeanUtils)
Maps – not type safe
requires casts and translations to/from Strings
Flaws of Java Properties Verbosity
In order to create a single mutable
property the programmer needs a
minimum of 7 lines of code. Indexed
property requires at least 13.
When one starts adding property
change listeners etc. the boiler-plate
code bloats and bloats.
Flaws of Java Properties –
Reference by String
Error prone: lack of or typo in
 property reference
 property access method
isn’t detected until runtime and the error
is not predictable.
Flaws of Java Properties –
Scattered definitions


No single property declaration – the references are
associated with the getter, setter, field, embedded in
various Strings – practically no way to track.
No way to associate meta-data (e.g .annotations),
constraints, conversions, aspects, mappings etc. with
a property declaration.
Example: default value is initially referenced by all
instances of the object, instead of being an attribute of
the property declaration itself. Same goes for
constraints (not null, etc.), supported conversions and
notifications. These definitions associated with
property declarations are supported in DDLs.
Flaws of Java Properties –
no abstraction
The object is either a bean or a map,
core Java requires that property is
used this way or the other, while it
shouldn’t matter to the user
 BeanUtils solve this, but rely on
Strings to express properties

Flaws of Java Properties –
no dynamicity



It is not possible to add new JavaBean
property or modify aspects associated with
existing JavaBean properties at run-time
This is a problem: systems that require
reliability and need to be up 99.9999… % of
the time, but also need to be upgraded and
require data schema update without restart.
Just for the programming purposes it is
convenient to define new “temporary” fields
for existing objects or make type-safe maps
(ala tuples) without creating new classes
BeanUtils
Project of Apache Commons, several useful
features:





Abstraction over beans and maps,
DynaBean
“Safe” map wrappers
Type converters
Support for “path” – composition of
properties
Support for ServletRequest and ResultSet
BeanUtils quick overview
DynaClass, DynaBean,
MutableDynaClass, DynaProperty
Lets access maps or beans as if they
were maps
 Lets access beans content via
expressions

PropertyUtils.getProperty(person, “address.street”)

Supports locales and conversions
BeanUtils - problems
Everything is based on Strings
Not “modernized” – stuck in Java 4, no
support or use of generics,
annotations, enums etc.
commons.Collections
google.Collections,
wishing to do the same for BeanUtils
Property – new generation
We’d like to take “best of both worlds”
while avoiding contradicting qualities.
Is it possible?
Abstraction is the way.
Instead of focusing on a Bean object,
focus on the Property itself.
Introducing BeanUtopia


While most of the developed solutions
require changing Java syntax or modifying
the compiler, BeanUtopia is a library.
Non-intrusive: try to avoid sourcegenerations and avoid or minimize the use
of on-the-fly byte-code generation, in case it
will be required (to improve performance for
example), use built-in tools such as APT,
javax.tools, java.lang.instrumentation
More BeanUtopia








Placing Property object in the center of the
picture: Property<Owner,Value>
Several built-in implementation and ability to
extend or provide new ones
Property is not bound to object instance
Read-only and read-write properties
Properties are inheritted
Property extends Function
Function chaining
Dynamic, predicate-based redefinition
BeanUtopia Property

AbstractProperty<B,V>
String name
 V valueType
 B beanType
 Class namespace
 Class<? extends

id
 Annotation[] annotations
AbstractProperty<B,V>>
Abstract
Property
Property
Updatable
Property
Value
Function
BeanUtopia Property

Property<B,V>



V defaultValue()
V of(B bean)
UpdatableProperty<B,V>




List<Constraint<? super V>> constraints()
assign(B bean, V value)
Value value(V value)
Host host(B bean) ???
Example 1-1
class Rectangle extends IntraMap { //definition
static final UpdatableProperty<Rectangle, Integer> length =
new UpdatableProperty<Rectangle, Integer>(0, notNull()) {};
default
constraints
static final UpdatableProperty<Rectangle, Integer> width =
new UpdatableProperty<Rectangle, Integer>(0, notNull(), nonNegativeInteger()) {};
Rectangle(UpdatableProperty<? super Rectangle, ?>.Value... args) {
PropertyUtils.populate(this, args)
}
}
class RectangleTest { //usage
public static void main(String[] args) {
Rectangle r = new Rectangle(length.value(10), width.value(5));
assert(width.of(r) == 5);
}
}
Example 1-2
class Box extends Rectangle { //definition
static final UpdatableProperty<Rectangle, Integer> height =
new UpdatableProperty<Rectangle, Integer>(0, notNull()) {};
Box(UpdatableProperty<? super Box, ?>.Value... args) {
PropertyUtils.populate(this, args)
}
}
class BoxTest { //usage
public static void main(String[] args) {
Box b = new Box(length.value(10), width.value(5), height.value(4));
assert(height.of(b) == 4);
}
}
Example 2
class Apple {
class AppleTest {
static final UpdatableProperty<Apple,String> color =
new UpdatableProperty<Apple,String>() {};
private String _color = null;
public static void main(String[] args) {
Apple a = new Apple(“red”);
assert(color.of(a).equals("red"));
public Apple() {}
public Apple(String color) {
this._color = color;
}
reflection
public String getColor() {
return _color;
}
public void setColor(String color) {
_color = color;
}
}
color.assign(a, “yellow”);
reflection
assert(a.getColor().equals(“yellow”));
}
}
Example 3
static final UpdatableProperty<Object,String> descripion =
new UpdatableProperty<Object,String>("description") {};
{
Object x = new Object();
descripion.assign(x, "Hello World");
assert(descripion.of(x).equals("Hello World"));
}
MAGIC
Property Definition
This is how property is actually
implemented:
given property and object what is the
value? (Projection = Function)
 given updatable property, object and a
new value, make the association
(Injection)

Example 4
static final Property<Object,String> toString =
new Property<Object,String>("n.a.") {};
{
toString.define(
new Function<Object,String>() {
public String apply(Object object) {
return object.toString();
}
});
}
Property definition types
Reflected
 Mapped by property name (String)
 Intra-Mapped

HasProperties interface
 IntraMap class

Extra-Mapped
 Imported
 can be extended…

Intra-Mapped properties
Base bean holds a container for
properties
Now implemented with Map
 Future: array

Extra-Mapped properties
Person1
Integer: age
String: name
Long: id
Age
Map<Person,Integer>
Name
Map<Person,String>
Person2
Integer: age
String: name
Long: id
Id
Map<Person,Long>
Imported property
static final Property<Object,Integer> cardinality =
new Property<Object,Integer>(0) {};
{
defineImported(cardinality, ImporterTest.class);
}
public static void main(String[] args) {
assertTrue(cardinality.apply(null) == 0);
assertTrue(cardinality.apply(5) == 1);
assertTrue(cardinality.apply(Arrays.asList(1,2,3))
== 3);
assertTrue(cardinality.apply(new int[] { 1,2,3 })
== 3);
}
public class ImporterTest {
public static int getCardinality(Object o) {
return 1;
}
public static int getCardinality(Object[] o) {
return o.length;
}
public static int getCardinality(Collection c) {
return c.size();
}
public static int getCardinality(Map m) {
return m.size();
}
}
Property re-definition

Policy<I,O> =
List<Predicate<I> + O>

FunctionPolicy<I,O> =
Policy<I, Function<I,O>>




Property definition is a policy
Based on the quality of parameter bean
(usually its class) the actual definition is
chosen
Definition policy is open for modifications
(additions etc.)
Policy is ordered (…)
Property chaining
and null safety
class CompositeFunction<A,B> implements Function<A,B> {
final Function<A,B> function;
<C> CompositeFunction<A,C> compose(final Function<? super B,C> f) {
return new CompositeFunction<A,C>(new Function<A,C>(){
public C apply(A from) {
return f.apply(CompositeFunction.this.apply(from));
}
});
{
}
Person p = …;
B apply(A from) {
Property<Person,Address> address = …;
return function.apply(from);
Property<Address,Street> street = …;
}
String street =
self(Person.class).compose(address).
}
compose(street).apply(p);
}
Management of Properties
Get properties by bean class,
including inherited ones
 BiDi Map between property id and
instance
…

Multi-value properties

Open Issue
Mapped definition –
type conversions

Open Issue
Binding/Hosting

Open Issue
Adding special behavior

Open Issue
Transactions
 ThreadLocal
 Atomic
 Different reference types

Other possible directions
Integration with Quare
 Full type-safe reflection
 Modularity
 Auto-generate from existing Java
code
 As above, but from DDL, XSD, …

Qi4j
New library (alpha) many innovative
concepts
 Property = mix-in
 Mix-in expressed as Java interface
interface Name {
String getName(); setName(String name);
}
interface Age {
int getAge(); setAge(int age);
}
class Person implements Name, Age { … }
.NET - LINQ

Simplifies and unifies the implementation of
any kind of data access
Data can belong to different domains (db,
array, object, XML, file) and each one has its
own access protocol. LINQ offers a uniform
way to access and manage data without
forcing any particular model.

Introduces queries as first-class concept
into .NET languages
LINQ - example
Code
var query =
from c in Customers
where c.Country == “Italy”
select c.CompanyName;
Results is list of strings.
foreach (string name in query) {
Console.WriteLine(name);
}
LINQ for Java - Quare
Scala Properties
sourceforge: Joda Beans
java.net Bean Properties
java.net Properties