|
From: Cameron B. <ca...@da...> - 2004-03-10 23:51:08
|
First of all a short description of commons attributes :
Commons attributes is quite flexable because it converts the attribute
declarations into a source class, which you then compile with your
application.
This allows you to use any java code in the declaration of the attribute.
The technique for not using the fully qualified class name is to specify all
package imports in the attributes-compiler ant task call.
For Example : the SecurityConfig class exists in the
au.acegi.springsecurity.attribute packge therefore the ant task call is :
<taskdef name='attribute-compiler'
classname="org.apache.commons.attributes.compiler.AttributeCompiler"
classpathref="attribute-compiler-classpath"/>
<attribute-compiler destdir="generated"
attributePackages="au.acegi.springsecurity.attribute">
<fileset dir="java"/>
</attribute-compiler>
An extract of the generated code for that getBalance method is :
import au.acegi.springsecurity.attribute.*;
public class BankService$__attributeRepository implements
org.apache.commons.attributes.AttributeRepositoryClass {
---stripped for brevity---
private void initClassAttributes () {
{
SecurityAttribute _attr = new SecurityAttribute("ROLE_TELLER" //
D:/workspace3/acegi-attributes/sample/java/BankService.java:10
);
Object _oattr = _attr; // Need to erase type information
if (_oattr instanceof org.apache.commons.attributes.Sealable)
{((org.apache.commons.attributes.Sealable) _oattr).seal ();}
classAttributes.add ( _attr );
}
---stripped for brevity---
}
so you can see that it basically treats the @@ declaration as a java
constructor call, with one exception.. it converts named values in to bean
property setters.
i.e
@@RoleConstraint(role="ROLE_TELLER")
This will generate code like :
RoleConstraint _attr = new RoleConstraint();
_attr.setRole("ROLE_TELLER")
Also notice that your attribute classes can implement Sealable which means
that their seal() method gets called when they get initialised, allowing you
to do some initialisation.
Therefore to answer your question ;) you can use any java class, as long as
you either fully qualify it, or include the package in the compiler task.
I suggest that you avoid using the same attribute class for all rules, and
instead use a type hierarchy :
For example instead of using
@@ValidationRule("range", "minimum=0.0, maximum=100,000.0")
Have a RangeValidationRule class and do this :
@@RangeValidationRule(minimum=0.0, maximum=100000.0)
I think this is better than
@@ValidationRule("range", new NumberRange(0.0, 100,000.0))
Cameron.
_____
From: spr...@li...
[mailto:spr...@li...] On Behalf Of
Keith Donald
Sent: Thursday, 11 March 2004 6:00 AM
To: spr...@li...
Subject: [Springframework-developer] commons attributes questions
I was browsing Ben and Cameron's new security stuff (looks great) and I like
how they did the attribute markup for the security roles required for
certain methods:
/**
* @@SecurityConfig("ROLE_TELLER")
* @@SecurityConfig("ROLE_SUPERVISOR")
* @@SecurityConfig("BANKSECURITY_CUSTOMER")
* @@SecurityConfig("RUN_AS_SERVER")
*/
public float getBalance(int id);
Specifically, I like how they didn't use a qualified class name, which makes
the attribute more compact & easier to type out. Also I liked how they went
with a generic "SecurityConfig" attribute. I was thinking of applying
something similiar to the validator attributes markup. So instead of
instantating the rule classes directly, you just instantiate a
ValidationRule attribute metadata class, with a String identifier for the
rule, and then a string list for any rule-specific properties. Something
like this:
/**
* @@ValidationRule("required")
* @@ValidationRule("range", "minimum=0.0, maximum=100,000.0")
*/
public float getBalance(int id);
The question I have regarding this is with commons-attributes:
1. Does it let you instantiate arbitrary objects using their constructors
within an attribute declaration? For example, can I say something like:
* @@ValidationRule("range", new NumberRange(0.0, 100,000.0))?
Somehow I doubt it, but I was curious how extensive its support was for
instantating objects declared as attributes (I mean obviously it can handle
Strings, but does it do type conversion too?)
What I am thinking abut doing is just having something like this:
* @@ValidationRule("range", "minimum=0.0, maximum=100,000.0")
.. where the first parameter is a String identifier for the rule, whose
backing PropertyValidationRule instance is looked up using a rule factory
configured by Spring, and the second parameter is a string-separated list of
bean property->value pairs where I'll likely just use BeanWrapper or OGNL
later on...
Keith
|