Tutorial: Writing your own extensions
Speedment is built up using a number of different components. These components handle everything from translating the relational database results into an object-oriented metadata model for logging debug messages throughout the system. One important feature of the component system is the ability to extend the platform with your own code. In this tutorial, we will go through how to create a new custom component and add it to an existing Speedment project.
Each custom component should reside in its own maven project. This will allow you to add it as a dependency to any project where you want to make use of the component. Begin by creating a new project and specify the pom.xml
file to extend the speedment main project with the same version as the project version:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.speedment</groupId>
<artifactId>speedment-awesome-plugin</artifactId>
<version>3.2.0</version>
<packaging>jar</packaging>
<name>Awesome Speedment Plugin</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.speedment</groupId>
<artifactId>runtime</artifactId>
<version>${project.version}</version>
<type>pom</type>
</dependency>
</dependencies>
</project>
The real magic of the plugins is done inside the component class. Here we can hook up code to run at different stages during the execution.
public final class Awesome extends AbstractComponent {
@Override
public Class<? extends Component> getComponentClass() {
return Awesome.class;
}
@ExecuteBefore(INITIALIZED)
public AbstractComponent initialize() {
// Write some code here...
return this;
}
@ExecuteBefore(RESOLVED)
public AbstractComponent resolve( @WithState(INITIALIZED) OtherComponent other) {
// ...or here...
return this;
}
@ExecuteBefore(STARTED)
public AbstractComponent start() {
// ...or even here.
return this;
}
}
Other components can be made available by declaring them as parameters. During start-up components, progress through the states CREATED
, INITIALIZED
, RESOLVED
and STARTED
in that order. Initialization order dependencies of components may be expressed with the @WithState
annotation. The number of available states to ask for in the @WithState
annotation are limited by the fact that no component will enter a state before all other components have reached the preceding state (thus all components will reach for example INITIALIZED
before any component can reach RESOLVED
).
Here is an example of how a plugin could define a new DbmsType
:
@ExecuteBefore(RESOLVED)
public AbstractComponent resolve(@WithState(RESOLVED) DbmsHandlerComponent dbmsHandler) {
dbmsHandler.install(
new ReallyCoolNewDbmsType()
);
}
Another example of the power in the component system is the extendability of the GUI. In this example, we will add some extra logic to analyze the generated metamodel before it is shown in the GUI.
@ExecuteBefore(RESOLVED)
public AbstractComponent resolve(@WithState(RESOLVED) EventComponent eventComponent) {
eventComponent.on(ProjectLoaded.EVENT, event -> {
event.project().traverseOver(ForeignKey.class).forEach(fk -> {
System.out.println("Found path between " +
fk.ancestor(Table.class).map(Table::getName).get() +
" and " +
fk.getForeignTableName() + "."
);
});
}
return this;
}
If you want to use your new component in an external project and you want it to be executed in the same java runtime as for an example the GUI, you need to do two small adjustments to the speedment-maven-plugin
-tag of your pom.xml
. You need to add your new component project as a dependency to the Speedment plugin and configure it to load it.
...
<plugin>
<groupId>com.speedment</groupId>
<artifactId>speedment-maven-plugin</artifactId>
<version>3.2.10</version>
<!-- Add your awesome plugin to the list of dependencies -->
<dependencies>
<dependency>
<groupId>com.speedment</groupId>
<artifactId>speedment-awesome-plugin</artifactId>
<version>3.2.0</version>
</dependency>
</dependencies>
<!-- Make sure the builder is loaded when the maven plugin is started -->
<configuration>
<components>
<component implementation="com.speedment.plugin.awesome.AwesomeBuilder"></component>
</components>
</configuration>
</plugin>
Speedment is available under the Apache 2 license.
Want to learn more about the enterprise version? Visit www.speedment.com!