Resource API
An abstraction of a XWiki URI (Entity, Template, Skin, etc) |
Type | JAR |
Category | |
Developed by | |
Rating | |
License | GNU Lesser General Public License 2.1 |
Bundled With | XWiki Standard |
Table of contents
Description
A resource in XWiki represents something that can be accessed. For example Entities, Templates, Skin files, Files on the filesystem, Temporary files generated by Macros, etc.
It can be viewed as a URI or as an abstraction of an XWiki URL.
API Tour
The following classes/interfaces are available:
- ResourceType: Represents a type of Resource (eg Entities, Templates, Skin files, Files on the filesystem, Temporary files generated by Macros, etc).
- ResourceReference: represents a reference to a Resource. EntityResourceReference represent a reference to an Entity resource (document, space, page, wiki, etc).
- ResourceTypeResolver: Extract the ResourceType from a representation (text, URL, etc).
- ResourceReferenceResolver: Create a ResourceReference object from a representation (text, URL, etc). For example the StandardURLResourceReferenceResolver is used to create a ResourceReference out of an URL written using the "standard" format.
- ResourceReferenceSerializer: A component role type to convert a Resource reference into something else. For example, the URL module provides a StandardExtendedURLResourceReferenceSerializer to generate a URL out of Resource reference (note that the implementation is not complete as of now and shouldn't be used for the moment).
- ResourceReferenceManager: Provides a getResource() method to access the current resource being processed (located in the Execution Context).
- ResourceLoader: Load Resources pointed to by Resource Reference as an Input Stream (not used yet)
- EntityResourceAction: Represents the action to be executed on an Entity Resource (eg view, delete, get, etc).
- ResourceReferenceHandler: Handles a ResourceReference by executing some actions. For example, for the bin Resource type (which is an Entity Resource Type) this means executing various actions (view, edit, download, etc) for that Entity.
- ResourceReferenceHandlerManager: Entry point for handling Resource References. Will find the proper ResourceReferenceHandler to know how to handle that Resource type and put them in the right priority order.
Resource Reference Handling
This part of the Resource module is in charge of calling the correct backend code to display what the user has asked for (it's the Controller in MVC terminology).
This API supports the following use cases:
- UC1: Handlers should be able to be added without touching at the existing platform code (i.e. someone could write a new Handler in java and plug it in)
- UC2: It should be possible to execute something before or after a Handler's execution.
- UC3: It should be possible to completely replace a Handler with another implementation.
- UC4: It should be possible to add Handlers without stopping the running XWiki instance.
- UC5: Handlers should not know about each other.
- UC6: Handlers should be independent of the URL formats used.
- UC7: Handlers should work for any type of Resource (Entity Resources, Temporary Resources, Skin Resources, etc).
- UC8: It should be possible for a Handler to be registered for one Resource type, a list of Resource types, or all types.
Adding a new Resource Type Handler
Extensions can register a new URL Resource Type.
Here's an example of a webjars Resource Type that would be called for the following types of URLs: http://<server>/<context path>/webjars/<path/to/resource/>.
@Named("webjars")
@Singleton
public class WebJarsResourceReferenceHandler extends AbstractResourceReferenceHandler<ResourceType>
{
/**
* The WebJars Type.
*/
public static final ResourceType TYPE = new ResourceType("webjars");
@Override
public List<ResourceType> getSupportedResourceReferences()
{
return Arrays.asList(TYPE);
}
@Override
public void handle(ResourceReference resourceReference, ResourceReferenceHandlerChain chain)
throws ResourceReferenceHandlerException
{
[...]
}
}
Adding a new Entity Resource Type Handler
Entity Resource References are handled by a ResourceReferenceHandler component with hint bin (that name corresponds to the part of the URL showing that it's a URL about an Entity). That ResourceReferenceHandler, in turn, looks for ResourceReferenceHandler components that are registered for the EntityResourceAction to execute (view, edit, download, etc) and calls them in the right priority order.
Here's an example of a webjars Entity Resource Action that would be called for the following types of URLs: http://<server>/<context path>/bin/webjars/resource/path?value=<resource name>.
@Named("webjars")
@Singleton
public class WebJarsResourceReferenceHandler extends AbstractResourceReferenceHandler<EntityResourceAction>
{
/**
* The WebJars Action.
*/
public static final EntityResourceAction ACTION = new EntityResourceAction("webjars");
/**
* Prefix for locating JS resources in the classloader.
*/
private static final String WEBJARS_RESOURCE_PREFIX = "META-INF/resources/webjars/";
@Inject
private Container container;
@Override
public List<EntityResourceAction> getSupportedResourceReferences()
{
return Arrays.asList(ACTION);
}
@Override
public void handle(ResourceReference reference, ResourceReferenceHandlerChain chain)
throws ResourceReferenceHandlerException
{
String resourceName = reference.getParameterValue("value");
String resourcePath = String.format("%s%s", WEBJARS_RESOURCE_PREFIX, resourceName);
InputStream resourceStream = getClassLoader().getResourceAsStream(resourcePath);
if (resourceStream != null) {
try {
IOUtils.copy(resourceStream, this.container.getResponse().getOutputStream());
} catch (IOException e) {
throw new ResourceReferenceHandlerException(
String.format("Failed to read resource [%s]", resourceName), e);
} finally {
IOUtils.closeQuietly(resourceStream);
}
}
// Be a good citizen, continue the chain, in case some lower-priority Handler has something to do for this
// Resource Reference.
chain.handleNext(reference);
}
/**
* @return the Class Loader from which to look for WebJars resources
*/
protected ClassLoader getClassLoader()
{
// Load the resource from the context class loader in order to support webjars located in XWiki Extensions
// loaded by the Extension Manager.
return Thread.currentThread().getContextClassLoader();
}
}
The context
By default, a ResourceReferenceHandler is called without any initialized XWikiContext.
If you need one with the current user automatically authenticated (to check if the user is allowed to access this resource, for example), you can annotate the handler with @org.xwiki.resource.annotations.Authenticated. It will also trigger the initialization of XWiki (and wait for it to finish) when it's not already the case.
Known Resource Types
Prerequisites & Installation Instructions
We recommend using the Extension Manager to install this extension (Make sure that the text "Installable with the Extension Manager" is displayed at the top right location on this page to know if this extension can be installed with the Extension Manager).
You can also use the manual method which involves dropping the JAR file and all its dependencies into the WEB-INF/lib folder and restarting XWiki.
Dependencies
Dependencies for this extension (org.xwiki.platform:xwiki-platform-resource-api 16.10.1):
- org.xwiki.commons:xwiki-commons-context 16.10.1
- org.xwiki.commons:xwiki-commons-observation-api 16.10.1
- org.xwiki.commons:xwiki-commons-script 16.10.1