RSS

Maven and XPages Plugin – From Scratch / Part III – The Testsuite

Part I has covered the building of the parent pom.xml, Part II was about the plugin and now in Part III we talk about the test suite. It’s fair to say that this part seems not to be very interesting, but in this Part we talk also about the why.

Why do I make the org.openntf.base.jaxb.dxl plugin?

The core purpose of the jaxb.dxl plugin is to convert a DXL export of a document, or of some design elements into an object based representation. Imagine this: You have a document with 2 rich text fields, one is a traditional rich text field and the other is mime based. For some reason (like transforming the content of the rich text field to a POI document or PDF document) there is an interest in the structure of this rich text field. A simple export as DXL and conversion to this java objects which are cascaded helps a lot.

Or you have this database, and you want to scan the content of all design element for a specific @Formula….. Export the database to DXL and convert it with jaxb to java object tree. And the scan the tree and analyse.

But why not start with the implementation, that sound better than testing!

Agree. Implementing is always better than writing test for the sake of writing tests. But after reading the book “Test Driven Developement” by Kent Beck, my understanding of test has changed. Tests explains what I want to do. Read the following test:

150

This test covers my user story “Reading a dxl-document.xml and convert it to a java object structure”. To make this test work, I’ve to writte a lot of implementation stuff, so stay tuned.

The next Maven module -> org.openntf.base.jaxb.dxl.testsuite

Again with the eclipse client:

151

select as packaging type “eclipse-test-plugin”:

152And we have a new project.

And now repeat the following steps, like you have done for the plugin in Part II

  1. New file called MANIFEST.MF into the folder META-INF
  2. New file called build.properties

Open the MANIFEST.MF File and go to the MANIFEST.MF Tab and enter the following stuff:

153The directive “Fragment-Host” makes this plugin to a fragment of org.openntf.base.jaxb.dxl. This is the best behavior to separate test and implementation in a plugin.

Open the build.properties File and go to the build.properties tab. Enter the following stuff:

154Now is a good moment to do a right-click on the project go to Plugin-Tools and execute “Update Classpath”

Open the MANIFEST.MF again and add the following dependency. This is needed that we can start writing our test class.

155

Let’s write the first Test:

156

We have also imported the dxl-db-test.xml and the dxl-document-test.xml. This documents were produced by a nice simple DXL Export.

To make the test compile (STEP 2 in TDD), we have to import the XSD File for domino_9_0_1 and convert it to classes. We use for this the JAXB import

JAXB Import of the domino xsd

160

Start with menu “New” and select the JAXB Classes from Schema Wizard

161

Select the target project for the import (yes our plugin)

162

If you do not have the domino_9_0_1.xsd in a project in your workspace, you can import it from your Notes/Data directory

163

Please specify carefully the package, where the classes should be produced. Existing classes will be overwritten (note to myself, move the DXLActivator Class to an other package or a level up)164

Select finish. The import will now generate a lot of classes.

You can now resolve the import of the Document object (yes its a …jaxb.dxl.Document object)

165

Time to finish the compilation problems in the test class.

Create the ConvertorFactor in the plugin (see the package that I select? It’s outside of the dxl package, because the content of this package was generated before).

166

We build also a dummy implementation of “convert2DocumentFromStream”. 167

Only one step, and we can test (with executing our runtime configuration)

We have to include the *.xml Files in our binary build. We open for this step the MANIFEST.MF and add the 2 files

168

Lets build the project by executing org.openntf.base clean install169

Oh yes the build fails! This is total ok at this point, because our test fails, and a failing test should stop our build!

Now its time to have some fun and finalize the plugin… The next Part will cover how to build the feature and the update site

If you wanna follow the project, please watch this repository on github.com https://github.com/guedeWebGate/org.openntf.base

 
Leave a comment

Posted by on December 23, 2014 in Architektur, Java, Maven, XPages

 

Tags: ,

A word about Maven

When I try to explain what Maven is, then I’m using often the following picture:

Maven is a factory building with a brilliant factory manager

Imagine this: There is this empty factory building and you walk with your construction plan to the office of the factory manager. You enter the room and the factory manager takes your construction plan. He read it and then he runs to tool storage. In a short time he has all the tools to build your construction taken from the storage and build a production line.

According to your plan, he has also hired the Q & A people, which let first run some unit tests directly in the production line and also some integration tests. At the end of the whole production line is also an assembly line to build the kit that is ready to ship.

… at this point you say. “mvn clean install” and the factory manager builds the software.

The other day, you come back to the factory building with a new construction plan. And the factory manager “cleans” the building and setup a new production line for you. If he finds some tools not in the storage, he orders the tools directly from *Maven Central*. But with the same passion and quality as the day before the manager tries to build the software.

What Maven can do for you depends on your construction plan and the tools that are available

Back from the analogy:

  • factory building -> maven
  • factory manager -> mvn
  • construction plan -> pom.xml
  • tool storage -> maven repository
  • tools -> maven plugins

Your construction plan contains all instruction about what builder should be used, how unit testing should work, and also how the assembly should run.

And it is not some kind of magic to build your own builder. I’ve built the headless designer integration, also a builder to build complete XPages Applications. It’s only hard work, nothing more and nothing less (and also a lot of fun 🙂 )

 
Leave a comment

Posted by on December 23, 2014 in Architektur, Maven

 

Tags:

Maven and XPages Plugin – From Scratch / Part II – The Plugin

The core purpose of org.openntf.base.* is to bring some core plugins to the community. This plugin could be used in conjunction with other plugins, like org.eclipse.core.runtime. The first plugin that I want to build is a JAXB representation of the domino9 dxl. This plugin should offer some basic method to convert any domino object to a java object tree based on the domino dxl definition. This could be used to explore the design of a domino database, but also to represent the content of a single rich text item.

We will focus in this part on how to build the plugin based on the parent, that we have already build in Part 1

As in Part 1, we will do the stuff again with our Eclipse Kepler IDE.

1. Build a Maven module

100

Go to your parent project and use “right-click” for the context menu. Browse to Maven / New Maven Module Project.

101

The module name should be the same as your plugin id (later).

102

While you fill out the dialog, it seems that the group id is necessary, but you can delete this later. Be sure that you specify as packaging type: eclipse-plugin. This has a huge impact on the build process and your new maven module will now be handled as eclipse-plugin.

Nice we have now created some folders and files, but unfortunately not the necessary files to handle this project as a plugin project.

Create some files….

That a plugin project is a plugin project, it needs to files.

  1. META-INF/MANIFEST.FM
  2. build.properties

With the right content -> so let’s build this files.

Create the META-INF Folder:

103Create the MANIFEST.MF File:

104

Let’s open the MANIFEST.MF File with the Manifest Editor

And we do this with a right-click on the project and browse to “Plugin Tools / Open manifest”

105

Lets fill out some base information for the plugin.

Btw. the Version should correspond to the version in the parent’s pom file, instead of SNAPSHOT use qualifier (as the plugin would expect)

106

Now its a good moment to update the classpath of the plugin project (do it again with a right click on the project) and the go to Plugin Tools / Update classpath

107

To complete the plugin configuration, we add the dependency to org.eclipse.core.runtime108

And we create the file build.properties109

We open again our MANIFEST.MF and go to the last tab called build.properties.

There we complete the build.properties with the yellow marked text. (bin.includes and sources.. are needed for the whole plugin build process)
110

Give the Plugin an Activator

We build now the Activator class for the plugin, by building first the package and then the class.

111

Creating the class file112

Let’s open the MANIFEST.MF again and assign the activator class113

Build a run configuration to build the project with Maven

Now its time for the fun part. We build a run configuration, to execute the goal clean and install in the maven build cycle

  • clean will delete all genearted code
  • install will compile, test and package all code

114

Select “Maven Build” as category and click on the blank sheet to build a new run configuration115

Please fill out all yellow highlighted fields. Be aware of the goals field. We define with -Dnotes-platform=file:/// the external variable ${notes-platform} for our parent pom file.

Click “Run” to check if all is builded correct the output should look like this:

116

 
1 Comment

Posted by on December 22, 2014 in Java, Maven, OpenNTF, XPages

 

Tags: , ,

Maven and XPages Plugin – From Scratch / Part I – The Parent

Is it a good Idea to start writing a blog series about Maven, XPages Plugin with the topic “The Parent” on your birthday? I don’t know but the birthday reminds me a lot about my parents. About my father and mother who gave me the base structure of my life and lot of my being. But also my heavenly father, the creator of heaven and earth. The same it is with “The parent” in a Maven based project.

But let me first explain something about Maven. Maven is an absolute brilliant idea. Maven is a bit like God. Maven is an Open Build Tool. Maven can create everything you can imagine…. or Maven ban build nothing. The architecture of Maven is plugin (not to be confused with OSGI plugin or FireFox plugins) based. This means that Maven needs a Plugin for each type of code or project Maven can build. But at this point there are no boundaries.

The POM.xml contains the magic….. or it’s simply the build plan

Like with Lego, it is good to have a build plan. Software is become so complex that it needs build instructions. The main File for this build instructions is the pom.xm. One of the strength of Maven is, that it can build different modules in the right order and combine it to a ship able package. Because of that, there is a Parent file needed. This parent file is normally in the root folder of the Maven project structure. To illustrate this process, I’ve built a folder called D:\EGit\org.openntf.base. I’ve also setup Eclipse Kepler, which contains the m2eclipse Plugin (the Maven integration 4 Eclipse). Unlike to other tutorial, I try to explain all steps directly from Eclipse, without any command line magic 😉

1. Create a new Maven Project

Create Maven Project

Select “Create a simple project” and select the project location002

Give a group ID like you know it from the OSGI Plugin development and also an artifact ID (The artifact ID will be the project name)

Please select “POM” as Packaging Type. This type is used for parent POM files or for pom files that contains instructions for a group of other modules

003

2. Setup the POM.xml File for our modules

Please open the pom.xml file and add some properties:

For all text sample that you now use, please refer to this file -> https://github.com/OpenNTF/BuildAndTestPattern4Xpages/blob/develop/testpatterns/org.openntf.junit.xsp.parent/pom.xml and copy / paste the fragments.

The properties contain values, which are used in this pom or the child poms.

  • tycho-version is the version of the Tycho Framework
  • compiler is the version of the java compiler
  • project.build.sourceEncoding and project.reporting.outputEncoding controls the charset of the build / reporting process

004The repositories

Maven is an Open Build platform and we are using the Tycho Framework to build the Eclipse Plugins and Features. For this reason it is important to have a repository defined, where all the plugins for the compilation and test cycle are. We define 2 repository. The first repository called “notes” points to the local location of the IBM Domino UpdateSite for BuildManagement. This local location can be different on each developer machine. For this reason I use a ${notes-platform} variable, which can be defined outside. I will show later, how I do this. It is definitely needed to do so, if your plugin should be build via Jenkins or Bamboo.

005

The build section

As you have already recognized, the pom.xml has several section, which represents parts of the build/life-cycle. We start now to pre fill the build section. The first plugin, is the java compiler. As you see in the definition, the section starts with …. each plugin has its own section. The compiler has also ${compiler} variables, which points back to the properties. This means that all compilations based on the version 1.6 and we can at one point change this to a more accurate Java version, as soon, as Domino supports JDK 1.7 or 1.8

006The Tycho Plugins!

The next plugins, that we add are the Tycho plugins. This plugins, developed by SAP helps us to build eclipse-plugins, eclipse-features and eclipse-updatesites.

007

One of the important parts of the Tycho plugins is the target-plattform-configuration. I wanna point specially to the extra-requirements because this section contains the magic to include the notes.jar! It points back to a part of the notes repository.008And last, but not least some stuff to complete the build configuration

009

All done for the <plugins> section….

… BUT we are working with eclipse

And I hope that I’ve understood this part right, but Eclipse needs some instructions how to manage all the plugins, for this we have the following definition, which gives clear instructions to org.eclipse.m2e how to handle maven and some build jobs.

010

Yes and now we are ready to build our first plugin in this project…..

 
2 Comments

Posted by on December 22, 2014 in Java, Maven, OpenNTF, XPages

 

Reading and writing Resource Bundles – an alternative approach

Dan Soares explains at NotesIn9 a nice way to read and write resource bundles. It’s a good read so enjoy his work. I was also faced with the problem of reading and a specially writing properties files, because Switzerland is multilingual and my idea was to give the power of translation to the hands of the business project leaders. But how to write properties files, and how to do it in am more productive way? I did go the same way as Dan, I did also find some sample from Sven Hasselbach, but the I asked my self, how can I provide this in an easy to consume way to my developers and to the community. This was the birth of a new part in the XPages Toolkit.

Btw. we started with the development of the XPages Tookit one year before we mad it public available on OpenNTF. And we want to be shure that we provide something useful and approved by our own developer team.

The result is a very easy to use API (requirement: Install the XPages Toolkit):

SSJS:
to get the properties as java.util.Properties object:
var properties = xptPropertiesBean.getProperties( databaseFilePath,
                               fileNameOfyourProperties );
to save the properties:
var success = xptPropertiesBean.saveProperties( databaseFilePath, 
                               fileNameOfYourProperties, properties);
Or to use in Java:
XPTPropertiesBean bean = org.openntf.xpt.properties.beans.XPTPropertiesBean.get();
Properties props = bean.getProperties( databaseFilePath, 
                                fileNameOfyourProperties ); 
int success = bean.saveProperties( databaseFilePath, 
                                fileNameOfYourProperties, properties);

But be aware of the following. Each change to properties seems to reload your application on the server.

 

To stay informed about the recent development on the XPages Toolkit, please register here and discuss ideas and give feedback.

 
Leave a comment

Posted by on September 6, 2014 in Domino, Java, OpenNTF, XPages

 

org.openntf.junit.xsp – now with EasyMock support

Frank van der Linden asked in his blog post (http://elstarit.nl/?p=157) if EasyMock or PowerMock can be integrated into the org.openntf.junit.xsp and Ryan J. Baxter mentioned also that a testing framework without a good mocking solution is only the half worth.

Only the half worth is a good reason to complete the effort. So I implemented also EasyMock and PowerMock to the org.openntf.junit.xsp. With version 1.1.0 you get the capabilty to mock objects. You may ask how does EasyMock work. Her a small example:

Imagine this. You have this class called Share. The class can be initialized with a builder method called initFromDocument( Document doc) and you want to test this method.

package org.openntf.junit.example.bo;

import lotus.domino.Document;

public class Share {

    private String m_ShareName;
    private int m_Count;
    private int m_PricePerShare;
    
    public static Share initFromDocument( Document doc) {
        Share share = new Share();
        try {
            share.m_ShareName = doc.getItemValueString("ShareName");
            share.m_Count = doc.getItemValueInteger("Count");
            share.m_PricePerShare = doc.getItemValueInteger("PricePerShare");
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
        return share;
    }
    
    public String getShareName() {
        return m_ShareName;
    }
    public int getCount() {
        return m_Count;
    }
    public int getPricePerShare() {
        return m_PricePerShare;
    }

    public Object getValue() {
        return m_Count * m_PricePerShare;
    }
    
    
}

Your intention is now to write a test for that (or better you write first the test). But you wont initialize a Notes Document, because one thing that unit testing is about has to do with isolation. At this point comes EasyMock to the game:

package org.openntf.junit.example;

import lotus.domino.Document;

import org.junit.Test;
import org.openntf.junit.example.bo.Share;
import org.openntf.junit.xsp.easymock.EasyMockWrapper;

import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;

public class ShareTest {

	@Test
	public void testShareWithDocumentMock() {
		Document docMock = EasyMockWrapper.createNiceMock(Document.class);
		try {
			expect(docMock.getItemValueString("ShareName")).andReturn("WebGate");
			expect(docMock.getItemValueInteger("Count")).andReturn(5);
			expect(docMock.getItemValueInteger("PricePerShare")).andReturn(2870);
			replay(docMock);
			Share shareWebGate = Share.initFromDocument(docMock);
			assertEquals("WebGate", shareWebGate.getShareName());
			assertEquals(5 * 2870, shareWebGate.getValue());
		} catch (Exception e) {
			e.printStackTrace();
			assertFalse(true);
		}
	}
}

With

Document docMock = EasyMockWrapper.createNiceMock(Document.class);

initialize EasyMock a new document object. You may recognize that instead of calling EasyMock.createNiceMock(), I’m calling EasyMockWrapper.createNiceMock(). This is needed because of security issues.

Now we can “record” what will happen to the docMock object. We have 1 call of getItemValueString(“ShareName”) and 2 calls to getItemValueInteger(). For each call can we define what value should be returned.

expect(docMock.getItemValueString("ShareName")).andReturn("WebGate");
expect(docMock.getItemValueInteger("Count")).andReturn(5);
expect(docMock.getItemValueInteger("PricePerShare")).andReturn(2870);

Like on the tape recorder. It’s time to go back to start. You do this with

 
 replay(docMock);

Now our mocked document object is ready and you can test the initFromDocument method.

There is a lot more to cove about mocking and this only the start.

 

Have fun (and don’t forget to use the EasyMockWrapper)

Christian

 

 
1 Comment

Posted by on September 2, 2014 in Domino, Java, OpenNTF, XPages

 

Using JUnit in XPages Projects

Yes! I’ve read some books during my holidays. Clean Code was one of them and also Test Driven Development. Both of them where very interesting and has closed some open questions. Back from holidays, I’ve started to research how I can implement JUnit testing to XPages Applications. The following StackOverflow question brings it to the reality: There is no easy way!

But wait, Jakob Majkilde had a good idea! Why not integrate the testing direct to the application and using the XPages rendering engine to present the result. This would not be the first time, that testing was done direct in the project. Inspired by this idea, I began to research, how eclipse presents the results of JUnit tests and also how the maven-surfire-plugin generates its results. I learned a lot about JAXB and the junit-4.xsd to generate the xml. Some short test, figured out that I’ve to make another plugin. But this time somehow different. I decide to work aligned to the TDD principles. It was a very nice experience. And also a very fast approach (I was really surprised!).

And here it is the org.openntf.junit.xsp plugin. Install it like you do it with the ExtLib or the OpenNTF Essentials (maybe it will become a part of it). And yes, server and DDE. Now you can activate the library in the xsp.properties.

junit-xsppropsActivating the junit library gives you the capability to write tests and use the TestSuite control. But lets start with a simple test class. This class makes not a lot of sense, but shows a bit of the capabilities of JUnit.

package org.openntf.junit.example;

import static org.junit.Assert.*;

import org.junit.Test;

public class TestMock2 {

    @Test
    public void checkTrue() {
        assertTrue(true);
    }

    @Test
    public void checkFalse() {
        System.err.println("MOCK2SYSERR");
        System.out.println("MOCK2SYSOUT");
        assertFalse(true);
    }

    @Test
    public void checkEquals() throws InterruptedException {
        Thread.sleep(201);
        assertEquals(10, 10);
    }
}

The class contains 3 test. They are marked with the @Test annotation as a test. The most methods ends with some kind of a assertXXXXX. With the assertXXXX functionality is the result checked. Two of this tests will be successful, one will fail. To test the capacity of my JUnit runner implementation, I’ve made in checkEquals a Thread.sleep to see if my time measuring works. checkFalse() contains System.out and System.err to check, if I can capture the Output during the test. Fortunatly its possible 🙂

Next step -> new XPage called junit.xsp

I’ve then made a new XPages called junit.xsp (but call it the way you love). Include the TestSuite Control on this XPages and define the classes to test. The following code shows the result:junitxsp

When you load the page, you will get the following result rendered for the junit:testsuite control:

junit-resultAnd yes you are right! The red bar is not the thing you wanna see! Now you can go and fix the problems. After that a refresh on this page and you see, that all is green 🙂

Btw. the definition

downloadFile="TEST-Failures.xml"

gives you the capability to download the report with <pagename.xsp>/<downloadFile> e.g. junit.xsp/TEST-Failures.xml

Have fun!

Christian

 
3 Comments

Posted by on August 21, 2014 in OpenNTF

 

Tags: