Martin Grotzke wrote:
> Hi Frank,
>
> very interesting, the declarative security thing!
>
> Regarding injectors, I didn't understand your last comment:
>
>> (11:01:38 AM) FrankMartinez: But what if you can register only one
>> Injectable wich is selected if there is no Injectable for the
>> specified type? ...
>
> Do you mean that you want to be able to register a *CatchAllInjectable*
> for a given annotation class, that is asked to return an instance for a
> given class?
>
> In the svn spring-integration branch [1] (r915) I changed
> WebApplicationImpl.injectResources to inject instances pulled from the
> ComponentProvider for @Context annotated fields, if there's no
> injectable mapped to that type.
> With this you can do s.th. like this:
>
> @Context
> MyDaoType dao;
>
> which injects a instance that is returned by your
>
> ComponentProvider.getInstance( Scope scope, Class<T> clazz )
>
> with scope beeing Scope.Undefined (still to be implemented, right now
> getInstance is invoked with scope null).
>
> Would that be appropriate for you?
>
I think Frank wanted to use his own annotation. But i *really* do want
to avoid duplicate IoC functionality in Jersey and keep Jersey stuff to
a minimum and concentrate on the things in Jersey that differentiate
from IoC functionality.
>
> Additionally I can imagine s.th. like this for ComponentProvider:
>
> getInjectableValue( Annotation[] as, Class<?> injectable )
>
> which is invoked, if a field is annotated but there's no injectable
> mapped to the fields type.
>
> Then one might implement it like this:
>
> getInjectableValue( Annotation[] as, Class<?> injectable ) {
> if ( containsDAOAnnotation( as ) ) {
> // get an instance for the given dao type
> return getDAOInstance( injectable );
> }
> }
>
It might be better to refactor the Injectable class to provide support
for the case when one does not want to register an injectable instance
for 'n' set of Type with the same Annotation. Then one does not have to
implement ComponentProvider.
For example:
// For inject related to an annotation for any annotated type
public abstract class Injectable<T extends Annotation> {
public abstract Class<T> getAnnotationClass();
public abstract Object getInjectableValue(Object o, Field f);
public void inject(Object o, Field f) {
if (getFieldValue(resource, f) != null) {
// skip fields that already have a value
// (may have been injected by the container impl)
return;
}
T a = f.getAnnotation(getAnnotationClass());
if (a == null) {
// skip if the annotation is not declared
return;
}
Object value = getInjectableValue(o, f);
if (value != null)
setFieldValue(o, f, value);
}
}
// For inject related to an annotation for a specific annotated type
public abstract class TypeInjectable<T extends Annotation, V> extends
Injectable<T> {
public Object getInjectableValue(Object o, Field f) {
return getInjectableValue(a);
}
public abstract V getInjectableValue(T a);
}
The problem is the current approach uses the key of the generic type of
the field to find the injectable. Searching for an injectable for an
annotation could be performed if an injectable for a specific type
cannot be found. i.e. we have two maps type->injectable and
annotation->injectable.
It may be better to start creating an injectable thing per resource
class (via ResourceClass) if we go this route to be more efficient i.e.
we do the wiring up just once and avoid as much Java reflection as
possible once we are up and running. But i am sure IoC frameworks do
this type of optimization.... they may even generate byte code...
I also think it may be useful to extend ComponentProvider such that
injection can be deferred in general (rather than just the restricted
case using @Context). What is required is a method signature as follows:
getInstance(Annotation[] as, Type t, Class<?> c)
Where t is the generic type (obtained from the field or parameter).
Which means one could support the following:
@XYZ List<ABC> l;
Note that we already support this for @Context as follows:
@Context ContextResolver<JAXBContext> cr;
Paul.
> Cheers,
> Martin
>
> [1] https://jersey.dev.java.net/svn/jersey/branches/spring-integration
>
>
> On Wed, 2008-04-09 at 11:39 -0500, Frank Martínez wrote:
>> Hi Guys,
>> This is a fragment of an IRC chat i have with Paul.
>> The main topic is related to Declarative security possibilities and
>> something about the injectors model.
>>
>> (10:16:44 AM) FrankMartinez: Hey Paul, take a rest of 5 minutes! :)
>> (10:16:52 AM) PaulSandoz: Hi!
>> (10:17:07 AM) PaulSandoz: I need a holiday :-)
>> (10:17:58 AM) FrankMartinez: :D. I have been working with 0.7 (the trunk) .....
>> (10:18:04 AM) PaulSandoz: ok
>> (10:18:07 AM) FrankMartinez: Great work!
>> (10:18:10 AM) PaulSandoz: thanks
>> (10:18:46 AM) FrankMartinez: I started a BIG application, and i am
>> using: iBatis - Jersey - ExtJS
>> (10:18:57 AM) PaulSandoz: Does it work OK?
>> (10:19:07 AM) FrankMartinez: Like a charm!
>> (10:19:22 AM) PaulSandoz: Phew now i can relax, that is really good to
>> hear, well done!
>> (10:19:25 AM) FrankMartinez: But i have had to write my own JSON writer.
>> (10:19:57 AM) PaulSandoz: Yes, this is an area we are still finding
>> our feet with, i hoped the JAXB approach would be OK but i think we
>> need to get more into the JAXB model to improve it
>> (10:20:27 AM) FrankMartinez: Yes
>> (10:20:50 AM) FrankMartinez: Now i am working in a declarative security ...
>> (10:21:28 AM) PaulSandoz: re: Json can you provide some feedback (did
>> you already?) what what form of JSon you would like and if using beans
>> what would work for you?
>> (10:24:08 AM) FrankMartinez: I used a free lib called json-lib, then i
>> wrote a MessageBodyWriter ... thats all.
>> (10:24:19 AM) PaulSandoz: ok
>> (10:24:32 AM) PaulSandoz: declarative security?
>> (10:24:39 AM) FrankMartinez: Yes.
>> What do you think about something like this:
>>
>> @Path(...)
>> @SecurityConstraint(...)
>> public XXX someMethod(...) { ... }
>>
>> (10:25:09 AM) PaulSandoz: The plan is to utilize @RolesAllowed, but it
>> is not implemented yet.
>> (10:26:15 AM) FrankMartinez: Is @RolesAllowed part of an
>> specification or something like a standard? or is it a Jersey concept?
>> (10:26:36 AM) PaulSandoz: It is copied from EE, but we will not
>> require EE to use it.
>> (10:26:45 AM) PaulSandoz: ... in Jersey.
>> (10:27:19 AM) PaulSandoz: Basically any authenticated principle that
>> is a member of a role....
>> (10:27:50 AM) PaulSandoz:
>>
>> @Path("admin") @RolesAllowed("admin") public XXX xxx(...)
>>
>> (10:27:57 AM) FrankMartinez: And what happen when the security is
>> based in some strategy not based in roles? i.e. Permissions or Rules ?
>> (10:29:25 AM) PaulSandoz: I am not sure... need to think about that,
>> off the top of my head a role is just a name that encpasulates
>> permissions/rules
>> (10:30:05 AM) PaulSandoz: It seems sufficient for EJBs in an EE container
>> (10:31:00 AM) FrankMartinez: I does not allow constraints based on
>> contextual state or complex rules!
>> (10:31:33 AM) PaulSandoz: Can you give an example?
>> (10:34:41 AM) FrankMartinez: If permissions are assigned dynamicaly:
>> (10:34:59 AM) FrankMartinez:
>>
>> @SecurityConstraint("s:hasPermission('actor.update')")
>>
>> (10:35:18 AM) PaulSandoz: Oh, i see you want to utilize some form of
>> security language
>> (10:35:24 AM) FrankMartinez: Yes
>> (10:35:38 AM) FrankMartinez: Did you know Seam security?
>> (10:35:42 AM) PaulSandoz: No.
>> (10:35:59 AM) PaulSandoz: I think we need to depend on an IoC
>> framework for such support
>> (10:36:57 AM) FrankMartinez: Maybe. I am working in this issue for
>> this project! I dont know if it need to be a Jersey Feature.
>> (10:37:36 AM) FrankMartinez:
>>
>> http://docs.jboss.org/seam/1.2.1.GA/reference/en/html/security.html
>>
>> (10:38:23 AM) PaulSandoz: Me neither yet. I was kind of hoping the
>> resource class could be proxied by the IoC container. Many discussions
>> on the list w.r.t. Spring/Guice. The plan is to enable transacted
>> methods by relying on an IoC container.
>> (10:39:16 AM) PaulSandoz: Interesintg link
>> (10:39:32 AM) FrankMartinez: Is there any (easy) way to intercept
>> method calls without a Proxy ?
>> (10:40:42 AM) PaulSandoz: Not currently, i have been relucant to
>> introduce an interceptor model if it can be done using an IoC
>> framework, as i don't want to introduce yet another interceptor model,
>> but if the use-case is compelling enough we could do it...
>> (10:42:25 AM) FrankMartinez: :D. I am reluctant to use an IoC
>> container in this project! I am trying to maintain it as simple as
>> possible!
>> (10:43:04 AM) FrankMartinez: I wrote my own Injectors ....
>> (10:43:33 AM) PaulSandoz: I see. Would you like to investigate what
>> might be possible with Jersey?
>> (10:44:02 AM) FrankMartinez: Yes i would like
>> (10:44:07 AM) PaulSandoz: Cool :-)
>> (10:44:44 AM) PaulSandoz: Feel free to create a branch and experiment...
>> (10:45:56 AM) FrankMartinez: Ok. I will.
>> (10:46:14 AM) PaulSandoz: I know others on the list will be very
>> interested in this
>> (10:46:42 AM) FrankMartinez: Can you give me some tips on where to
>> start? (in the code struture)
>> (10:48:24 AM) PaulSandoz: Yes, it would be easier if i send this by
>> email, might not get around to it until late Thu for Fri. If you want
>> a quick clue, look at the implementations of UriRule interface and put
>> break points in the accept method.
>> (10:49:03 AM) FrankMartinez: Ok. Good!
>> (10:50:35 AM) FrankMartinez: I have a specific question: Is possible
>> to register an Injector that catch all not registered types?
>> (10:50:58 AM) PaulSandoz: what do you mean by "registered type"
>> (10:51:02 AM) PaulSandoz: ?
>> (10:51:31 AM) PaulSandoz: A root resource class, message body reader/writer ?
>> (10:51:51 AM) FrankMartinez: You register Injectors associating it with a Class
>> (10:52:47 AM) PaulSandoz: You mean for injecting say @Context Foo foo.
>> But an instance of Foo does not exist?
>> (10:54:45 AM) FrankMartinez:
>>
>> @DAO
>> MyDaoType dao;
>>
>> but there is no wa.addInjectable(MyDaoType.class, injector)
>> instead there is wa.addInjectable(Object.class, injector) or something
>> like this.
>>
>> (10:56:30 AM) PaulSandoz: It is encapsulated in the injector instance
>> (10:56:55 AM) PaulSandoz: See WebApplicationImpl.createInjectables
>> (10:57:13 AM) FrankMartinez: ok. thanks!
>> (10:58:08 AM) PaulSandoz: I think you can extend ServletContainer and
>> add your own for @DAO and the type MyDaoType
>> (10:58:46 AM) FrankMartinez: I did.
>>
>> But i have had to do this:
>>
>> protected void configure(ServletConfig servletConfig,
>> ResourceConfig rc, WebApplication wa) {
>>
>> super.configure(servletConfig, rc, wa);
>>
>> AnnotatedClassScanner scanner = new AnnotatedClassScanner(DAO.class);
>> Set<Class> daos = scanner.scan(new String[] {"com.zonacomun.zc.dao"});
>>
>> for (Class cls : daos) {
>> wa.addInjectable(cls, new DataServiceInjectable());
>> LOGGER.log(Level.INFO, "iBatis-Ext DAO: " + cls.getSimpleName());
>> }
>>
>> }
>>
>>
>> (11:00:02 AM) PaulSandoz: WHat is the problem :-)
>> (11:00:16 AM) FrankMartinez: No problem!
>> (11:00:23 AM) PaulSandoz: Oh!
>> (11:00:26 AM) PaulSandoz: :-)
>> (11:01:38 AM) FrankMartinez: But what if you can register only one
>> Injectable wich is selected if there is no Injectable for the
>> specified type? ...
>> (11:03:58 AM) PaulSandoz: I see, Martin Grotzke as been experimenting
>> with something like that for just the @Context annotation and we could
>> generalize this for any annotation.
>> (11:04:13 AM) PaulSandoz: Do you want email the users list and sync up
>> with him on that?
>> (11:04:27 AM) FrankMartinez: Ok.
>>
>> Cheers,
>> Frank.
>
--
| ? + ? = To question
----------------\
Paul Sandoz
x38109
+33-4-76188109