This addon exports services for use in other addons. The Resources addon provides APIs and services for interacting with real and virtual resources, typically for the purpose of reading and manipulating files or other data-structures. The resources API also allows for wrapping of low-level resource constructs with higher level operations.
This addon requires the following installation steps.
To use this addon, you must add it as a dependency in the pom.xml of your forge-addon
classified artifact:
<dependency>
<groupId>org.jboss.forge.addon</groupId>
<artifactId>resources</artifactId>
<classifier>forge-addon</classifier>
<version>${version}</version>
</dependency>
- Abstraction of low-level functionality
-
This enables abstraction of common operations such as testing for existence, retrieving input streams, naming, deletion, and listing of child resources.
- ResourceFactory service for resource creation
-
The ResourceFactory is used for creating both generic and specific resources from underlying resource instances. When creating resources, the factory will select the most appropriate resource API type to represent the given real or virtual resource.
@Inject private ResourceFactory factory; ... Resource<?> resource = factory.create(...);
TipIf your addon uses a container that does not support "@Inject" annotations, services such as the
ResourceFactory
may also be accessed via theAddonRegistry
:AddonRegistry registry = ... Imported<ResourceFactory> imported = registry.getServices(ResourceFactory.class); ResourceFactory factory = imported.get();
- Built-in support for common resource types
-
The resources addon comes pre-configured with several types for interacting with common resources.
Resource Underlying Type Description FileResource<?>
java.io.File
Used to interact with the standard Java filesystem API. Can be extended with custom resource types to provide name or contents based specialization. (E.g.: PropertiesFileResource)
DirectoryResource
java.io.File
Used to interact with directories via standard Java filesystem API.
URLResource
java.net.URL
Used to interact with standard Java URLs.
- Custom resource types
-
The resources API may be extended to support custom resource types. This is a two step process involving creation of a new type that extends from
Resource
, and aResourceGenerator
. These custom resource types will be made automatically available to other addons depending on the resources addon.public class Thing { }
public class MyResource extends AbstractResource<Thing> implements Resource<Thing> { public void doSomething() { // custom functionality for your resource } }
Once the resource interface has been implemented, simply add methods and functionality to the resource implementation; this allows consumers of the resource type to use the functionality you have created. You may then implement a resource generator, which will be responsible for constructing instances via the
ResourceFactory
.public class MyResourceGenerator implements ResourceGenerator<MyResource, Thing> { @Override public boolean handles(Class<?> type, Object resource) { return resource instanceof Thing; } @Override public <T extends MyResource> T getResource(ResourceFactory factory, Class<MyResource> type, Thing resource) { return (T) new MyResource(resource); } @Override public <T extends MyResource> Class<?> getResourceType(Class<MyResource> type, Thing resource) { return MyResource.class; } }
- Consistent programming experience
-
Because the resources API provides a consistent set of interfaces for interacting with real and virtual resources, it is used in a number of addons and should be considered the standard approach for interacting with both the local file-system, as well as with other resource types.
- Resource monitoring
-
The resources API provides a service to monitor FileResource events.
Event type Description ResourceCreated
Fired when a resource (eg: directory or a file) is created.
ResourceDeleted
Fired when a resource (eg: directory or a file) is deleted.
ResourceModified
Fired when a resource (eg: directory or a file) is modified.
@Inject private ResourceFactory factory; ... Resource<?> resource = factory.create(...); ResourceMonitor monitor = factory.monitor(resource); monitor.addResourceListener(new ResourceListener() { @Override public void processEvent(ResourceEvent evt) { ... } }); ... // If the monitor is no longer needed, dispose properly by calling cancel monitor.cancel();
Tip-
It’s always a good practice to cancel monitors when they are no longer needed
-
From a FileResource object, it’s possible to fetch a reference to a ResourceMonitor by simply calling monitor() on it.
-
- Resource transactions
-
The resources API provides a transaction service on FileResources. If you are familiar with UserTransaction in Java EE applications, this should feel pretty comfortable.
ResourceTransaction transaction = factory.getTransaction(); try { // Starts the transaction transaction.begin(); FileResource<?> resource = factory.create(...); // The file won't be updated until commit is performed resource.setContents("Hello World"); String contents = resource.getContents(); // Returns "Hello World" FileResource<?> anotherResource = factory.create(...); // The file won't be deleted until commit is performed anotherResource.delete(); FileResource<?> newResource = factory.create(...); // The file won't be created until commit is performed newResource.createNewFile(); transaction.commit(); } catch (Exception e){ // Discard all changes since the beginning of this transaction transaction.rollback(); }
Additionally, transactions support change-set inspection, so you can compare file contents before deciding whether or not a given transaction should be committed or rolled back:
... Collection<ResourceEvent> changeSet = transaction.getChangeSet(); ... transaction.commit();
According to the above example, this change set contains the following entries:
Collection [ ResourceModified: <DirectoryResource>, ResourceCreated: <FileResource<?>>, ResourceModified: <FileResource<?>>, ResourceDeleted: <FileResource<?>>, ResourceCreated: <FileResource<?>> ]
- Built-in support for zip files
-
The resources API provides a built-in support for zip files through the
ZipFileResource
object:... ZipFileResource resource = resourceFactory.create(ZipFileResource.class, new File("file.zip")); DirectoryResource outputDir = ...; // Extract the zip contents to the specified directory resource.extractTo(outputDir);