Hi Felix,
Thanks for this advice, I have it working now. I copied the mechanism
from SlingAuthenticator (for tracking AuthenticationHandler services)
almost verbatim. The facade checks the path property of each
DelegateAccessManager against the item path, and uses the appropriate
AM(s), or falls back to the default logic if there's no match.
The complication was the dependency on org.apache.jackrabbit.core/spi
classes (for AccessManager, HierarchyManager etc). They aren't exported
anywhere, so I tried embedding them (like the jackrabbit-server
bundle). This enabled the bundle to load, but caused linkage errors
when Jackrabbit tried to instantiate my AccessManager, since
org.apache.jackrabbit.core.security.AccessManager was being loaded in 2
places. The quick solution I found was to modify the jackrabbit-server
pom.xml to export o.a.j.core and o.a.j.spi packages, though I'd be
interested in finding out if there's another way.
I also implemented a basic ACL-based AccessManager bundle to test it
out. Let me know if you think these would be useful as samples.
Regards,
Rory
Felix Meschberger wrote:
Hi Rory,
Rory Douglas schrieb:
I want to write a facade AccessManager implementation that will
delegate to a bundle-provided service. The idea would be to register
one or more bundles providing AccessManager implementations and be
able to configure the paths and/or nodetypes that they control,
though initially it will probably just delegate to one service (if
available), and fallback to SimpleAccessManager logic if no
AccessManager service is available.
Since the AccessManager implementation is instantiated by Jackrabbit
directly (has no Bundle- or ComponentContext), how can I get a handle
to the Felix framework to lookup/listen for services? Would this
even be advisable?
Depends on who you ask ;-) I think this is a valuable extension of
Jackrabbit. Unfortunately, as you correctly note, Jackrabbit is
currently configured in an non-dependency-injection way.
Of course, I assume you know of the risk of allowing any provider to
plug in an AccessManager ;-)
As a solution I suggest you do the following:
* Create a new bundle and export the AccessManagerFacade class
and the extension interface.
* Configure your AccessManagerFacade into Jackrabbit. The
jackrabbit-server bundle will find the AccessManagerFacade
class with a dynamic import.
* Create a BundleActivator in your AccessManagerFacade bundle
along these lines (make sure to _not_export this class) :
public class Activator implements BundleActivator {
private static BundleContext context;
public static BundleContext getBundleContext() {
return context;
}
public void start(BundleContext context) {
this.context = context;
}
public void stop(BundleContext context) {
this.context = null;
}
* To find and use the real access managers the AccessManagerFacade
would then access the Activator.getBundleContext() method
This works thanks to OSGi's class loader isolation. The drawback is,
that the repository of course only works correctly if your
AccessManager bundle is started.
Hope this helps.
Regards
Felix
Regards,
Rory