Skip to content

Latest commit

 

History

History
168 lines (143 loc) · 4.98 KB

README.asciidoc

File metadata and controls

168 lines (143 loc) · 4.98 KB

facets

This addon exports services for use in other addons. The Facets addon allows for modularization and extension of core functionality by creating a standard integration point and set of installation/removal APIs.

Dependencies: None

Setup

This Addon requires the following installation steps.

Add configuration to pom.xml

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>facets</artifactId>
   <classifier>forge-addon</classifier>
   <version>${version}</version>
</dependency>

Features

Modular functionality

Use small building-blocks to compose functionality into higher level constructs. Facets are small pieces of functionality that may be accessed individually, or built upon to create decoupled extensions for a known Faceted type. While a circular dependency exists in the base type implementations, this ultimately leads to a simplified development experience.

public class MyFacet extends AbstractFacet<FacetedObject> implements Facet<FacetedObject> {
  @Override
  public boolean install() {
     return true;
  }

  @Override
  public boolean isInstalled() {
     return true;
  }

  public void doSomething() {
     // custom functionality for your facet
  }
}

And the corresponding Faceted type.

public class FacetedObject extends AbstractFaceted<MyFacet> implements Faceted<MyFacet> {
}

Once the facet interfaces are implemented, simply add methods and functionality to the facet implementation. This allows consumers of the facet to use the functionality you have created:

Faceted<MyFacet> faceted = ...;
MyFacet facet = faceted.getFacet(MyFacet.class);
facet.doSomething();
FacetFactory service for simple installation/removal

The FacetFactory provides a single API for all Facet operations: both creation of new, detached facet instances, and also handles the installation of facets directly.

@Inject
private FacetFactory factory;
...
FacetedObject faceted = new FacetedObject();
MyFacet facet = factory.install(faceted, MyFacet.class);
Tip

If your addon uses a container that does not support "@Inject" annotations, services such as the FacetFactory may also be accessed via the AddonRegistry:

AddonRegistry registry = ...
Imported<FacetFactory> imported = registry.getServices(FacetFactory.class);
FacetFactory factory = imported.get();
Simple facet prerequisite management

Since Facet implementations are designed for re-use, the projects addon API provides the @FacetConstraint annotation, for quickly defining dependencies between facet implementations. The default constraint type is REQUIRED.

@FacetConstraint({OtherFacet.class})
public class MyFacet extends AbstractFacet<FacetedObject> {
   ...
}

@FacetConstraints({
   @FacetConstraint({OtherFacet.class}),
   @FacetConstraint(value={OtherFacet2.class}, type=OPTIONAL)
})
public class MyFacet extends AbstractFacet<FacetedObject> {
   ...
}

FacetConstraint declarations may then be read using the FacetInspector utility to inspect annotated types.

Set<Facet<?>> required = FacetInspector.getRequiredFacets(FacetedObject.class);
Consistent programming experience

Because the Facet API provides an abstract model for extending functionality of an API, it is used in a number of addons and should be considered the standard approach for modular API extension.

Facet Event Support

The Facet API will fire FacetEvents when Facets are installed on Faceted objects.

Event type Description

FacetInstalled

Fired when a facet is installed in a faceted

FacetRegistered

Fired when a facet is registered in a faceted. Facets may be registered when their installation requirements have already been met.

You may observe these events by registering a FacetListener:

  • Classes that implement the FacetListener interface are automatically bound to FacetFactory;

  • In cases where auto-discovery is not possible, FacetFactory provides an addFacetListener(FacetListener) method for explicit registration.

@Inject
private FacetFactory factory;
...
ListenerRegistration<FacetListener> registration = null;
registration = factory.addFacetListener(new FacetListener(){
	@Override
	public void processEvent(FacetEvent event) {
		// Do something
	}
});
...
// Remove listener when it is no longer needed
registration.removeListener();
  • The event is also fired using Furnace’s event architecture, so it’s possible to listen for events using the add-on container implementation.

Important

Project objects are invalidated when the pom.xml changes and facets are re-calculated when this happens. For this reason, a FacetListener MUST be idempotent and perform a no-op on repeatable FacetRegistered events.