Hi Carsten,
here are my 2 cents:
A provider is mounted at a single root - no more support for mounting
it
at different path at the same time; and a provider always owns the
root.
Depending on the use case, you can end up with *many* resource providers
- I remember a POC I did two years ago that had to evaluate how the
system deals with 20k+ resource providers. Result back then: Overall
system performance ok, but the the services tab in the OSGi Felix
console completely overloads the browser with too many json records when
clicking the "services" tab (making that tab unusable). What about
making PROPERTY_ROOT optional? If not set on the service one resource
provider instance could provide resources for the whole tree (having the
framework asking it for any resource requested), if the property is set
the behaviour could be as described. This obviously means such a "global
provider" needs to be implemented with great care (performance!), but
for some use cases it would definitely be cleaner to have this
implementation option.
public abstract @CheckForNull Resource getResource(final @Nonnull
ResolveContext<T> ctx, final @Nonnull String path);
The central function that has to be implemented takes a string path as
argument (in both the old and the new interface). From my feeling it
could be better to use a combination of parent (Resource) and name
(String). This would be in line with listChildren() and makes it easier
to embed resources in an existing tree.
Regards
Georg
On 2015-05-18 08:17, Carsten Ziegeler wrote:
The resource provider API has grown a lot over time and when we started
with it we didn't really think about potential extensions of the api.
Today, each time we add a new feature, we come up with a new marker
interface. There is also the distinction between a resource provider
(singleton/stateless) and the factory (creating stateful providers).
Although the api is not intended to be used by the average resource api
user (it's an extension), we put it in the same package. And there are
more minor things.
Therefore I think it's time to start a new API that is more future
proof
and solves the known problems. I've created a draft prototype at [1].
During the performance analysis by Joel he found out that getParent
calls to a resource a pretty expensive as in the end these are string
based. Therefore, e.g. the JCR implementation can't simply call
getParent on a node and wrap it in a resource. Therefore I think we
should add a getParent(Resource) method to the resource resolver and
have a better way to handle this in a resource provider.
Instead of having a resource provider and a resource provider factory,
we define a single ResourceProvider which is a singleton. If this
provider needs authentication and/or needs to keep state per user, the
PROPERTY_AUTHENTICATE needs to be set to true and in this case the
authenticate method is called. This one returns a data object which is
passed in to each and every method. If auth is not required, the method
is not called and null is passed in as the data object.
For authentication, providers do not support login administrative
anymore, just users and service users.
Instead of using marker interface, we define the ResourceProvider as an
abstract class. This allows us to add new methods without breaking
existing providers.
Each method gets a ResolveContext, containing the resource resolver,
the previously mentioned state data object and other things, e.g. the
parameter support recently added to the resource resolving. In the
future we can pass in additional data without breaking the interface.
Apart from that the resource provider is similar to the aggregation of
the already existing marker interfaces. There are two exceptions,
observation and query which I'll handle in different emails.
[1]
https://svn.apache.org/repos/asf/sling/whiteboard/cziegeler/api-v3/src/main/java/org/apache/sling/api/resource/provider/
Regards
Carsten