Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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. 

...

  1. The IGB Toolbar menu contains a menu option labeled Configure Web Links. This is the first hook.
  2. 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.
  3. 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
languagexml
titleWeb Links pom.xml
collapsetrue
<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
languagexml
<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
languagexml
<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
languagexml
<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
languagexml
<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
languagexml
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <scope>provided</scope>
</dependency>

...


org.lorainelab.igb:context-menu-api

...

Code Block
languagexml
<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
languagejava
titleExample of Service Access Using DS
linenumberstrue
@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
languagejava
public interface IgbMenuItemProvider {
    public String getParentMenuName();
    public JRPMenuItem getMenuItem();
    public int getMenuItemWeight();
} 

...