...
To understand this article, you need a basic understanding of Java and maven. See Maven in five minutes for a quick introduction to maven.
Info |
---|
This tutorial describes the IGB 9 API, the development version of IGB planned for release to users in spring of 2016. For an earlier version describing the IGB 8 API, IGB 8 API (deprecated). |
About Web Links
When users right-click an annotation, they see a context menu that contains one or more options called "linkouts," menus that run a Google Web search or open a Web page related to the selected item on some external site. The Weblinks module is responsible for creating and adding linkout menu items to the context menu.
The Weblinks module also lets users create all-new custom linkouts using regular expressions. It accomplishes does this feat by allowing regular expression patterns to be applied to the annotation or track currently selected to dynamically populate a context menu for a given selection. If an annotation or track id matches a user-defined pattern, then IGB creates a linkout menu item with URL defined in the custom linkout.
...
- The IGB Toolbar menu contains a menu option labeled Configure Web Links. This is the first hook.
- Selecting Configure Web Links opens the Web links configuration window. IGB includes several built-in linkout patterns in the top section. The middle section contains user-defined Custom Web Links.
- When users right-click an annotation, a context menu appears that contains menu items for each matching Web Link pattern. This is the second hook. Note that if only one Web Link pattern matches, it appears in the main menu, not in sub menus as shown below.
...
Web links project and directory structure
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<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> <parent> <groupId>com.affymetrix</groupId> <artifactId>igb-project</artifactId> <version>8.6.0</version> <relativePath>../../pom.xml</relativePath> </parent> <groupId>org.lorainelab.igb</groupId> <artifactId>weblinks</artifactId> <packaging>bundle</packaging> <name>WebLinks</name> <dependencies> <dependency> <groupId>biz.aQute.bnd</groupId> <artifactId>bndlib</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>com.affymetrix</groupId> <artifactId>genometry</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>com.affymetrix</groupId> <artifactId>igb-services</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>com.affymetrix</groupId> <artifactId>igbSwingExt</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <scope>provided</scope> </dependency> <!--Start of logging dependencies--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <scope>provided</scope> </dependency> <!--End of logging dependencies--> <dependency> <groupId>org.lorainelab.igb</groupId> <artifactId>igb-preferences</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>com.jidesoft</groupId> <artifactId>jide-ultimate</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>com.affymetrix</groupId> <artifactId>affymetrix-common</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.lorainelab.igb</groupId> <artifactId>igb-genoviz-extensions</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.lorainelab.igb</groupId> <artifactId>synonym-lookup</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.lorainelab.igb</groupId> <artifactId>context-menu-api</artifactId> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <configuration> <filesets> <fileset> <directory>${project.parent.basedir}/bundles/dynamic</directory> <includes> <include>${project.build.finalName}.jar</include> </includes> <followSymlinks>false</followSymlinks> </fileset> </filesets> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy</id> <phase>install</phase> <goals> <goal>copy</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>${project.groupId}</groupId> <artifactId>${project.artifactId}</artifactId> <version>${project.version}</version> </artifactItem> </artifactItems> <outputDirectory>${project.parent.basedir}/bundles/dynamic</outputDirectory> <overWriteReleases>true</overWriteReleases> <overWriteSnapshots>true</overWriteSnapshots> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> <configuration> <instructions> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Import-Package>*</Import-Package> <Export-Package/> <Service-Component>*</Service-Component> <Bundle-Description>${bundleDescription}</Bundle-Description> </instructions> </configuration> </plugin> <plugin> <groupId>org.lorainelab.igb</groupId> <artifactId>bundle-markdown-encoder</artifactId> <executions> <execution> <goals> <goal>encodeMarkdown</goal> </goals> </execution> </executions> <configuration> <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile> </configuration> </plugin> </plugins> </build> </project> |
...
Parent Tag
Code Block | ||
---|---|---|
| ||
<parent> <groupId>com.affymetrix</groupId> <artifactId>igb-project</artifactId> <version>8.6.0</version> <relativePath>../../pom.xml</relativePath> </parent> |
The parent tag indicates that the POM for the IGB code base, defined using a relative path, is the parent for the Web Links POM. This means that the Web Links POM can reference dependencies defined in the parent POM. The parent tag also indicates that the is the par the IGB code base using a relative path. By inheriting from the parent POM, the Web Links module's POM can reference dependencies defined in the parent. Dependencies defined in the parent POM is POM are compatible with IGB version 8.6.0 and higher.
...
Code Block | ||
---|---|---|
| ||
<packaging>bundle</packaging> |
We are using packaging type of "bundle" to take advantage of the plug-able architecture of Maven itself and the custom packaging type which is defined in the Apache Felix Maven Bundle Plugin. Throughout the IGB project we use this maven plugin to generate all of the OSGi meta-data which makes the jar file into a module that can be managed in the IGB OSGi runtime.
...
Code Block | ||
---|---|---|
| ||
<dependency> <groupId>biz.aQute.bnd</groupId> <artifactId>bndlib</artifactId> <scope>provided</scope> </dependency> |
com.affymetrix:genometry
Contains data models and utility methods used throughout the project. When the user right-clicks a item to select it, the Web Links module obtains a reference to the selected data model and uses it to create linkouts to external resources. These The genometry module defines these data models and their interfaces.
...
Code Block | ||
---|---|---|
| ||
<dependency> <groupId>com.affymetrix</groupId> <artifactId>igb-services</artifactId> <scope>provided</scope> </dependency> |
com.affymetrix:igbSwingExt
...
A very useful utility module which is used extensively in our project. We highly recommend you take a look at the content of this project (see https://code.google.com/p/guava-libraries/), and occasionally even demmand demand in our interfaces you leverage some of the collection data structures from Guava (e.g. Multimap). You will thank us later!
...
Code Block | ||
---|---|---|
| ||
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <scope>provided</scope> </dependency> |
...
org.lorainelab.igb:context-menu-api
...
Code Block | ||
---|---|---|
| ||
<dependency> <groupId>org.lorainelab.igb</groupId> <artifactId>context-menu-api</artifactId> <scope>provided</scope> </dependency> |
Build and plugins section
...
The Web Links module accesses implementation of the IGB Service interfaces via the service registry managed by the OSGI runtime. There are several ways this could be done; however, our preferred way to access services is with the use of the Declarative Service @Component annotation.
Note that in 2016, the core IGB team will focus on refining the IGB Services module to make the APIs easier to use for developers.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component(immediate = true) public class LinkControl implements AnnotationContextMenuProvider { private static final String SEARCH_WEB_ICONPATH = "searchweb.png"; private static final org.slf4j.Logger logger = LoggerFactory.getLogger(MenuIcon.class); private IgbService igbService; public LinkControl() { } @Activate private void activate() { } @Reference public void setIgbService(IgbService igbService) { this.igbService = igbService; } ... @Override public Optional<ContextMenuItem> buildMenuItem(AnnotationContextEvent event) { if (event.getSelectedItems().isEmpty()) { return Optional.empty(); } SeqSymmetry primarySym = event.getSelectedItems().get(0); if (primarySym instanceof CdsSeqSymmetry) { primarySym = ((CdsSeqSymmetry) primarySym).getPropertySymmetry(); } return buildContextMenuItem(primarySym); // a private method defined elsewhere in the class } |
...
Note that this design facilitates moving IGB from using Swing to JavaFX, a newer GUI toolkit that is replacing Swing in Java applications. framework handles the work of creating
IgbMenuItemProvider
This interface, defined in the IGB Services module, is designed to allow module developers to hook into the applications main toolbar.
Code Block | ||
---|---|---|
| ||
public interface IgbMenuItemProvider { public String getParentMenuName(); public JRPMenuItem getMenuItem(); public int getMenuItemWeight(); } |
...