I see a couple things going on hereā¦ First, I think the reason you are going to see an infinite recursion situation is because you haven't defined HOW Resource will adapt to Foo. All the AdapterFactory should do is take an Object and a class and create a new Object of that Class FROM the adaptable Object you passed in. That means you need to have a way to create a Foo out of a Resource, if you want to adapt the latter to the former. The simplest example is by adding a Foo constructor that takes Resource (i.e. "return (AdapterType) new Foo(adaptable)" where adaptable is a Resource). If you cannot change the Foo class, there are probably a variety of other ways to handle it.
Second, the "if some condition" logic to occasionally return Bar does not belong in this AdapterFactory. The AdapterFactory should probably only be responsible for converting one Object to a certain Class. Logic determining WHAT that Class should be, belongs elsewhere, in whatever code is calling the adaptTo() function. What you'll probably want to implement as an AdapterFactory that can adapt Resource to both Foo or Bar, depending on what class gets called in. Then your "if some condition" logic should call resource.adaptTo() passing in either of those classes. Third, the service may not be registered, and that's why it's not getting called on resource.adaptTo(). Try using @Server(value=AdapterFactory.class). Hope this helps. Adaptables are not very clearly documented (in my opinion), so I'm curious if anyone else has feedback as well. It helped me quite a bit to look at some of the Adaptable and AdatperFactory implementations in the Sling code base. -- Ryan D. Lunka On Dec 17, 2012, at 1:06 PM, Sam Lee <skyn...@gmail.com> wrote: > Hey, > > Given > public class Bar implements Foo { > ... > } > > > I want to provide AdapterFactory that returns Bar instance when > resource.adaptTo(Foo.class) is called. > > > Here is my attempt: > =>8= > @Component(metatype = false, immediate = true) > @Service > @Properties({ > @Property(name = SlingConstants.PROPERTY_ADAPTABLE_CLASSES, value = > {"org.apache.sling.api.resource.Resource"}), > @Property(name = SlingConstants.PROPERTY_ADAPTER_CLASSES, value = > {"com.example.Foo"}), > @Property(name = "service.ranking", intValue = -1)//this doesn't seem > to be observed > }) > public class MyAdaptToFoo implements AdapterFactory { > @Override > public <AdapterType> AdapterType getAdapter(Object adaptable, > Class<AdapterType> type) { > final Resource resource = (Resource) adaptable; > final Foo foo = resource.adaptTo(Foo.class);//I don't want infinite > recursion here. > if (someCondition) { > final Bar bar = new Bar(foo); > return (AdapterType) bar; > } > return (AdapterType) foo; > } > > } > =>8= > > first of all, that adapter factory doesn't get called when > resource.adaptTo(Foo.class); is called.. > Even if MyAdaptToFoo gets called, I don't want infinite recursion when its > .getAdapter() calls resource.adaptTo(Foo.class). > > The reason why I'm doing this is because I have a massive code base that > uses resource.adaptTo(Foo.class).. and I need to augment Foo (with Bar) in > some cases. > > Is this possible?