• No results found

I MPLEMENTATION D ETAILS

6.3 Frontend Project

Figure 6.6:Mock-up of the Frontend.

6.3 Frontend Project

The Frontend project implements a basic graphical user interface for the ETG framework, to provide browsing functionality to the user. With this simple interface, the ETG projects, the graphs, and their entities can be explored and manipulated. The functionality of the Frontend project matches the requirement (r7). Because of the pluggable UI architecture, it also provides a part of the solution for requirement (r6).

The frontend is implemented using the Vaadin 76framework. This framework is based on the Google Web Toolkit (GWT)7and provides basic GUI components and widgets like buttons, windows, and even tables or lists.

6Vaadin -https://vaadin.com/home

7GWT -https://developers.google.com/web-toolkit/

6 Implementation Details

The GUI is divided in two main areas: The navigation tree to navigate through the meta graph of the ETG framework (described in 5.2.3) and the main area to display the properties and environment information of the projects, graphs or even entities (see Figure 6.6). A list of all nodes and all edges of a selected graph is shown as tab in the main area, too. The toolbar on the top of the screen is designed to extend the web interface with other management framework interfaces.

6.3.1 Plug-In Management

A main feature of the frontend is the possibility to extend the interface by plug-in specific GUI components. These components are delegated to the frontend, when the plug-in is deployed and registered. The registration of the plug-ins is managed by thePluginRegistrationBean, which implements the IPluginRegistration interface. The plug-ins have to call the

registerPluginmethod in their start-up sequence (more information in 6.4). This method inserts the plug-in in the singletonPluginManager, which holds all registered plug-ins and provides a way to registerIPluginLoadListeners for status updates of the plug-in set. With this listener interface UI components can react on plug-in registrations and can load the appropriate plug-in UI components.

The plug-in components are used by the main frontend. They have to be updated and placed in different containers. To make this usage possible, the components have to be loaded in the same classloading context as the main frontend interface. To achieve this goal, the

registerPluginmethod expects a path to a .jar archive containing the UI components. This .jar file is scanned for a specific plug-in class, which implements theIPlugininterface.

Each plug-in can define a plug-in panel, which is inserted in the plug-in view of the specified context (see 6.3.2). In addition, the plug-in can define a set of actions. Each action has to extend the abstractETGActionclass and must define a target class. With the help of the target class the frontend determines the objects, on which the actions can be performed.

For more information on how to implement a plug-in, the registering and the loading sequence, the next Section (Plug-Ins) can be consulted.

6.3.2 GUI Context

A GUI context defines constants and methods, which can be used in the interface implemen-tation of a plug-in. Every GUI context implemenimplemen-tation has to implement theIGuiContext

interface. A context is passed to the plug-ins interface object, when it is created by a frontend view. That’s because different views can be created in a different context (e.g. a property view can be used to display properties of a snapshot or an entity.). The context holds the id of the object in the scope, e.g. the graph id of a snapshot. In addition, the IGuiContextinterface provides a default method to create closable tabs in the main area of the frontend. With this method plug-ins can create their own tabs.

52

6.4 Plug-Ins

TheIGuiContextinterface can be extended in the future. If different requirements occur in the different contexts, additional interfaces and implementations can be added. For example, if the entity context needs to extend a property view, a new interface for an entity context can be created. This new interface has to extend theIGuiContextand can provide the information and methods to manipulate the property view. The implementation of this new context has to be added to the frontend project. With this possibility for extension, the context can easily used to manipulate the frontend UI in a controlled way and the framework’s interface can be modified to match future plug-ins requirements.

6.4 Plug-Ins

This Section will describe the process to implement a plug-in to extend the functionality and user interface of the ETG framework in 6.4.1. After that, in 6.4.2 the registering and loading process of plug-ins and their corresponding UI components will be shown. At the end, two example plug-ins will be shown: The Random Graph Creator Plug-In (in 6.4.3), which creates random ETGs with direct usage of the Graph Backend (see 6.2.6), and the Search Plug-In (in 6.4.4), which provides base search functionality and neighborhood discovery for entities using the Search Backend (see 6.2.7).

6.4.1 Plug-In Implementation

To implement a plug-in for the ETG framework, basically three parts have to be created:

• The interfaces

• The functionality

• The graphical user interface

First, the interfaces have to be defined. These interfaces describe the usage of the plug-ins functionality and are used to define session beans or even Web Services. These interfaces have to be provided in a common project of the plug-in, because the UI objects have to use them and this components are in a different deployment unit.

Second, the functionality must be implemented using session beans. The bean project can be implemented without caring about the ETG framework. The features, provided by the framework, can be accessed through the frameworks public beans.

If the implementation of the beans is finished, a start-up bean has to be added with a post-construct method, to trigger the registration process after the plug-ins deployment. In the post-construct method the PluginRegistrationBean (described in 6.3.1) has to be used to register the plug-in. To deregister the plug-in also a pre-destroy method has to be added.

Application servers differ in the mechanism to define and use start-up beans.

6 Implementation Details

Listing 6.2Example implementation of a PluginRegistrator for a plug-in.

/**

* Session Bean implementation class PluginRegistrator

*/

@Singleton

@Startup

public class PluginRegistrator {

private static final Logger logger = Logger .getLogger(PluginRegistrator.class);

/**

* Executed at the startup of this module. Registers the plug-in in the

* framework.

logger.warn("Could not find the PluginRegistration service.");

logger.trace(e.getMessage(), e);

* Deregisters the plug-in in the framework on shutdown.

*/

logger.warn("Could not find the PluginRegistration service.");

logger.trace(e.getMessage(), e);

} } }

54

6.4 Plug-Ins

The Figure 6.2 shows an example PluginRegistratorbean, using a JBoss 7.1.1 application server runtime. TheConfigholds all plug-in properties and is contained in the common project of the plug-in.

The plug-in is now ready to be used. But if the plug-in needs to extend the graphical user interfaceof the framework another project must be added. In the GUI project a panel implementing theIPluginPanelinterface can be added. This panel behaves like a standard Vaadin panel and can be designed like every Vaadin component. This panel is the main GUI component of the plug-in. In addition, actions can be implemented using the abstract

ETGActionclass. To delegate this UI components to the frontend, a plug-in class is needed. This class must extend theIPlugininterface.

The listing 6.3 shows an example implementation of the IPlugin interface for a plug-in providing a panel and an action for two different targets.

The implementation of the plug-in does not require any more steps. In the Appendix A, more information about the deployment possibilities can be obtained.

6.4.2 Register- and Load-Sequence

After the implementation of a plug-in, this Section gives more insight into the registration and loading process of plug-ins. These processes are illustrated with the UML sequence diagram in Figure 6.7.

The registration process starts with the invocation of the post-construct method of the

PluginRegistratorof the plug-in. This method calls thePluginRegistrationBeanand passes the plug-ins unique identifier and the name or even the path to the .jar file containing the plug-ins UI classes. ThePluginRegistrationBeantries to load the UI from the given path with the help of thePluginLoader. If no path is given or the file can not be found on the given path, thePluginLoadersearches for a matching .jar file in the default plug-ins folder.

The default plug-in folder can be configured in the Data Service. If the PluginLoaderfinds the classes, a new classloader will be created. This classloader is a child loader of the fron-tends classloader, because of that, the new classloader is aware of the existing context and all classes in the frontend and common project can be linked properly. With this new class-loader the plug-ins implementation of theIPlugininterface is instantiated and passed to the

PluginManager. In the manager, the new plug-in is added to the list of initialized plug-ins and all registeredIPluginLoadListenersare informed by calling theirpluginInitializedmethod.

The registration process is completed.

The plug-in loading process can be started on two different ways: First, if a new

IPluginLoadListenersis added to thePluginManager, for each plug-in in the list of initialized plug-ins the listeners methodpluginInitializedis called. The view, which has implemented the listener, is then aware of the plug-in. The view can instantiate a new plug-in panel and can attach the plug-ins actions to the target objects. The second way to start the plug-in

6 Implementation Details

Listing 6.3Example IPlugin implementation.

/**

* The entry point for the example plug-ins GUI.

*

* @author Hannes Todenhagen

*

*/

public class ExampleGuiPlugin implements IPlugin {

@Override

return "Example Plug-in showing the "

+ "implementation of a plug-in";

return new ExamplePanel(context); // The plug-ins panel.

}

6.4 Plug-Ins

Plug-In

Registrator PluginRegistrationBean PluginManager GUI view

(IPluginLoadListener)

post-construct registerPlugin (id, guiJarName)

PluginLoader

loadPlugin(guiJarName)

IPlugin plugin

addPlugin(plugin)

addPluginLoadListener(this)

pluginInitialized(plugin) Loop

for each plugin pluginInitialized(plugin)

update the UI components

update the UI components

Registration Process Loading Process

Figure 6.7:Plug-In registration and loading process.

loading process can be triggered by a completed in registration process. If the plug-in successfully got added to thePluginManager, all listeners get informed about the new plug-in.

The deregistration process is similar to the registration process. The listeners also will get informed about the deregistration by calling theirpluginShutdownmethod. A deregistration process is triggered by the undeployment of a plug-in. This can only happen, if the plug-ins are deployed in their own Enterprise Application Archive. More information about the different deployment possibilities can be obtain by reading the Appendix A.

6.4.3 Random Graph Creator Plug-In

The Random Graph Creator Plug-In provides a possibility to create new ETG projects with an initial, random snapshot. The snapshot is created randomly and has a defined number of nodes. This plug-in also offers a plug-in panel to trigger the creation process in the user

6 Implementation Details

interface. This plug-in directly uses theGraphBackendBeanin the Data Service, to be able to create very big graphs without running the risk of aOutOfMemoryException.

6.4.4 Search Plug-In

The Search Plug-In only extends the user interface and does not offer new framework function-ality. The plug-in offers a panel, to send a query to the framework. The resulting segments are displayed in a table with collapsible items. The plug-in also offers actions to execute a neighborhood discovery for entities. This action executes a pre-defined query.

START first=node:<graphIndex>("id:<entityId>")MATCH first-[rel]-second RETURN first, COLLECT(rel), COLLECT(second)

This query results in a segment containing the neighborhood of the specified entity with depth one. TheCOLLECTaggregation joins the different paths on the first node. If theCOLLECT is removed, the result of the query would be a list of segments, each with two nodes and one edge.

Related documents