Development

Project Documentation

Commons

Legend

External Link

Opens in a new window

What are Attributes?

Attributes are value objects that can be added to language elements such as
classes, methods and fields.

Value Objects

What is a value object? Simply stated, a value object is an object that is
read-only, constant and can be replaced with another object of the same value
without it making any difference. For example, instances of the class
java.lang.Integer are value objects. You can replace any instance
of that class with any other instance, provided that they are equal. An
java.io.Socket is not a value object, as you can't replace an
instance of a socket with another - it corresponds to a real resource, in
this case a connection.

You should therefore not allow your attribute classes to be mutable, and not
use Sockets or similar classes as attributes.

How Are They Added?

Let's look at the way attributes are added to the code. The general form of the
attribute expression is (optional parts are in [brackets]):

@@[target] ClassName ([constructor args] [named args])

target

This name indicates what sub-element the attribute is to be applied to.
Classes and fields have no sub-elements, but methods do. The sub-elements
of a method are (1) the arguments and (2) the return value. In order to
apply an element to a method argument, you let the target be .argument name.
For example:

The attribute compiler will pass any parameter up to the first one that is
on the form name = expression to the constructor.
For the remaining parameters, it will invoke a method named
setName(expression) on the attribute instance.
So for our example above, the following code will be generated:

MyAttribute attr = new MyAttribute("this is a name");
attr.setOptional(true);

Named parameters are always optional.

How are they Retrieved?

You retrieve attributes by using the methods in the org.apache.commons.attributes.Attributes
class. See the JavaDoc for a description of methods in this class.

How are Attributes Stored?

Gotchas and Other Questions

What happens if I add the same attribute twice?

Let's define the question via a use case. Suppose you have an attribute (MyAttribute), and you have a class MyClass:

/**
* @@MyAttribute()
* @@MyAttribute()
*/
public class MyClass {}

The question is now, will the collection returned by Attributes.getAttributes (MyClass.class) have one or
two elements? The answer is that it depends on the way MyAttribute handles equality. The attributes associated
with a class, method or field always for a Set, meaning that there are no duplicates. So if MyAttribute is
implemented this way:

public class MyAttribute {}

Then you will get two elements, since each instance of MyAttribute is different from every other instance.
However, if MyAttribute is implemented like this:

That is, every instance of MyAttribute is equal to any other instance of the class, then you will only get
one element in the collection.

The above also holds true if the attribute has been inherited.

What are the requirements for an attribute class?

It must have a public constructor. That's all.

I tried adding attributes to an anonymous class and it didn't work.

That's not supported (yet). It is also very hard to implement since the class name is decided by the Java compiler.

I want to add a constant value as an attribute.

So you have this

public class Values {
public static final Integer ONE = new Integer (1);
}

and now you'd like to add ONE as an attribute like this:

/**
* @@Values.ONE
*/
public class MyClass { ... }

how can this be done?

The best that can be offered is:

/**
* @@Integer(Values.ONE)
*/
public class MyClass { ... }

I'm afraid. The expression follwing the @@ must fit the template "new (expression)" optionally suffixed by "()". This makes the compiler much simpler, and the loss of functionality was considered worth it. You can also define a separate ONE class: