JavaScript sugar of the day

So I needed to use the slice function in the result of a getElementsByClassName() call.  Something like:

var elements = document.getElementsByClassName(‘MyClassName’);

var copyOfElements = elements.slice(0);

However this fails on the second line because slice is not a function on the elements objects.  The elements object is of type HTMLCollection, even though HTMLCollection appears very much like an array it isn’t exactly one, however there is a solution to be able to use slice with my object.

It comes in the form of using the call method on the Function Type.  JavaScript unlike other languages allows you to get a handle on a Function just like its any other type.  So for instance if I return ‘MyString’.indexOf it literally gives me the Function Object.  Now once you understand that, you can see that maybe the Function Object has methods of its own.  One of these methods is ‘call’  what call allows you to do is basically inject your own object for the ‘this’ of a Function.  In my example I can use the call method to use Array’s slice method on an object of another type, very easily.  Like so:

var elements = document.getElementsByClassName(‘MyClassName’);

var copyOfElements = [].slice.call(elements, 0);

However be careful of doing this as obviously not all objects are equal and therefore could cause you issues down the road if the structures and methods don’t line up.

Advertisements

JAX-RS or THE way to do REST in Domino Part 1

The IBM Domino community has had servlets on its mind lately, and XAgents, and Rest Services.  These are all great advances to using IBM Domino in a modern world.  However to bring IBM Domino into a more modern age of Java Development we must go beyond just writing servlets like it was 1999.  The next few blog posts will show you how to setup a REST Service that uses JAX-RS and runs on Domino.  This will require creating an OSGi plugin.  I am going to assume you have never written such and will try to explain all of the pieces that need to be done and why.

Below are the first few steps to create the plugin.

1.  Download Vanilla Eclipse.  Any version should work, but I would recommend getting the latest, which is Eclispe Luna SR2.  Specifically the one for Java EE Developers.  Its available here:

http://eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/lunasr2

After its downloaded unzip it somewhere, There isn’t an install just a bunch of files that need to be on your hard drive somewhere.

Once that done you can go about running it by executing “eclipse.exe” There are a few welcome screens that you can skip to get to the screen that is somewhat similar to Domino Designer Workspace.

2a.  I’m making an assumption here that you are either running a local full Domino Server or you have File Access to an install.  If you don’t have either of these, you really should consider it as it will make all of your development work a lot easier, even your normal XPages work.

To give you a little more understanding of how OSGi works, it helps to know that you are creating a bundle (plugin) and that it will interact with other bundles all within a container.  When dealing with Java in our XPages context we tend to think of Java as either source “.java” or libraries “.jar” files.  We need to add a third category of a bundle to create a plugin that does much.  So with that said we have to create whats called a “Target Platform”  inside of eclipse.  This is a profile of what environment will your bundle run in.  For our limited example all we need to add is the directories of where the Domino Bundles live.  There is a couple of them and its really just so our new Bundle can see those.

From the Eclipse menu go to Window-> Preferences.  This will open a dialog.  On the left side of the Dialog you should see Plug-in Development

prefpane1

Expand that section and you will see a new area called “Target Platform” Click on it and you should see a single platform called “Running Platform”, we will be creating a new one, so click “Add”

prefpane2

From there it will prompt if you want to start from an old one or from scratch.   We will be creating one from scratch. So leave it on

“Nothing: Start with an empty target definition”

targetdef1

In the Locations Tab you will Add 4 Directories

target1

C:\Program Files\IBM\Domino\data\domino\workspace\applications\eclipse\plugins\

C:\Program Files\IBM\Domino\jvm\lib\ext\

C:\Program Files\IBM\Domino\osgi\rcp\eclipse\plugins\

C:\Program Files\IBM\Domino\osgi\shared\eclipse\plugins\

Once you have completed these steps you now have setup Eclipse to be able to develop OSGi Bundles for Domino.  In the next part we will create the bundle and discuss each part of the plugin.xml that needs to be setup to create a JAX-RS Service.

Maven, and an easy way to use it with XPages

For some time now the Domino community, with good reason, has been very focused on using Java inside of Domino, specifically with XPages.  There are some great reasons to use Java, but one of the foremost reasons is support from the Java community in both word (Stackoverflow) and deed (Third party libraries).   These third party libraries are a huge reason to be a Java developer.  They come in all shapes and sizes but in the end it means less code that you have to write that you can trust.  I’m sure that if you have been using Java for any length of time, you have probably searched for a library to do something, found it, and went to the download page, only to be presented with some XML tags instead of a download link.  These XML Tags might look like this:

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.1.1</version>
</dependency>

This is the typical structure to add a Maven dependency to your project.

Maven is an application that can do many things as listed below, however in this case we are using Maven as a package tool so that you when you go to build your project it will download any dependencies and (here is the key) any dependencies the dependencies have.  For Instance I might add the Social Business Toolkit as a dependency to my project.  When maven runs on my project it will download the apache http client library because its a dependency for the sbt.  I don’t have to mention the apache http client anywhere, Maven looks at the projects configuration and figure out its dependencies.

  • Making the build process easy
  • Providing a uniform build system
  • Providing quality project information
  • Providing guidelines for best practices development
  • Allowing transparent migration to new features

So with Domino we are use to having dependencies as JAR files instead of as a list in an XML file.  There is a way to make Maven build all of the Dependencies you have as a single JAR file.  Basically this will allow you to work inside of your project as you always have without adding a dependency on Maven and hopefully will make your life easier.

Its really pretty simple also.

Maven is an install-able executable that you can get from here:

https://maven.apache.org

Once installed on your PC, you just have to make sure the mvn.exe is in your PATH environment variable

So every project that is to be build with Maven requires a pom.xml this file describes what dependencies the project has among other things.

So if you add a dependency like the apache http client above, when maven builds your project it will download the appropriate version for you.

If you use the maven-assembly-plugin it will then build put all of the jars together into a single jar that you can add to an agent or an xpages project.

So How do you do this you might be wondering. First you need a pom.xml file inside of an empty directory.  It needs some basic information about your project, Below is the a sample

 

<project xmlns=”http://maven.apache.org/POM/4.0.0&#8243; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”&gt;
<modelVersion>4.0.0</modelVersion>
<groupId>com.tobysamples.test</groupId>
<artifactId>tsamples</artifactId>
<version>0.1.0</version>
<packaging>jar</packaging>
<name>test</name>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
</project>

 

So you can create a new pom.xml file with the above in it in an otherwise empty directory.

Then all you have to do is change to that directory using the command line then run “mvn package”

This will try to package all of the dependencies together as a single jar and save them in your directory.

If you look in you will now see a Target directory that holds the jar that you can attach to your project.  Hopefully this will help some of you not get stuck in dependency hell that Java can be sometimes.

Maven can get a little complex and is a whole new set of skills to learn, but they can and will make your life easier if you get your head wrapped around it.

XPages Custom Converters: Change the data, Change the world!

So as my next installment of the XPages feature series I will be discussing Converters, This seemingly boring feature actually has a lot of functionality packed into it.  Almost everyone who has ever written an xpage has probably used at least one of the standard converters that come out of the box.  I would say the most used one is the date converter.  An example of a simple date control with a datepicker looks like this:

<xp:inputText id=”inputText1″>
<xp:this.converter>
<xp:convertDateTime type=”date”></xp:convertDateTime>
</xp:this.converter>
<xp:dateTimeHelper></xp:dateTimeHelper>
</xp:inputText>

As you can see there it is, right in the middle, a date converter.  Simple enough to use but what does a converter “really” do.  It converts data right, well what does it convert it from and to and why does it need to convert it.  So in the example above its converting the data between the HTML markup and the JSF component tree.  In the component tree the data is stored as a Notes DateTime object that when written out using its toString method writes out the date and time in a very long format.  This converter formats it for the html that gets sent to the page so it looks however the end user wants it.  However that is not all that it does, it also does the reverse when the form is submitted on the page it has to convert it back from the format the developer picked to a NotesDateTime object.

So that’s cool and all, but Isn’t this just really a formatter for different types of data, dates, currency and such.  Well the answer is not really is actually a lot more powerful then that when you think about it.  Yes that is most of what XPages comes with out of the box, but a developer can write their own converters and that is where the you see the power of converters.

Let me give you an example of how you can use converters in a way that’s not just formatting.  Let’s say you have some data in your database that you would like to be encrypted for all users except for a certain role, Its very easy to write 2 methods getAsString and getAsObject inside your custom converter so that this happens.  The data inside your database is always encrypted, but then if the user has the correct role the getAsString method could convert the data into plaintext, when they submit it the possibly new value gets encrypted again before it goes back into the database.

Using a converter this way helps separate the conversion of any field to an encrypted field into a single manageable module that can be applied easily.  Another fun way to use converters is to help convert an id that is stored in a document to a lookup value stored in a lookup document. So you could have “USA” stored in each of your main documents but then display “United States of America” from your lookup document and convert it back to ensure the correct thing is stored in the database.  It is really easily to write a custom converter.  There are 2 methods you must implement when you implement the javax.faces.convert.Converter interface.

1.  public Object getAsObject(FacesContext facesContext, UIComponent component, String value) :

This method is called after a form is submitted from the xpage it is passed in the current facesContext object, the component the component is setup on and the value of that component as a String.  This is where you would take the unencrypted value and encrypt it before it gets saved to the database in our example.

2.  public String getAsString(FacesContext facesContext, UIComponent component, Object value):

This method is just the reverse, it builds out the object that is coming from the component tree and gets it ready for the html markup.  In our example this is the method that would check the role of the end user and then either decrypt the data or return back a value to alert the user that they don’t access to the encrypted field.

So once you have this class built you need to do 2 additional steps.

1.  Add the class to the faces-config as a converter, similar to a managed bean this simple declaration just gives the converter a unique id to use on the component where you wish to convert the value.

<faces-config><converter> <description>A Converter for encrypting fields</description><converter-id>customConverter</converter-id> <converter-class> com.tobysamples.converters.EncryptionConverter </converter-class> </converter></faces-config>

2.  You must apply the converter to the component that needs conversion.

<xp:inputText id=”inputText1″>
<xp:this.converter>
<xp:converter converterId=”customConverter”></xp:converter>
</xp:this.converter>
</xp:inputText>

you notice the converterId attribute on the component matches the faces-config value as well.

Thats really it, pretty easy to use and use on all your xpages.  If stored inside of an OSGi plugin you could use it on all of your applications.

I think this feature of XPages speaks to a larger point inside of the environment.  XPages is broken into many pieces for a good reason, it helps us as developers separate our code out in a way that’s reusable and inheritable.  Over time, this ideology will save you time as you won’t be rewriting the same functionality or even copy and pasting it.

No State No Problem

A while back I ran into this problem while using Xagents, these are pseudo Lotus Notes Web Agents that are created by changing the <xp:view> tag’s rendered attribute to false and writing to the outputstream directly.  I had an application that had a view where an end user could select several rows in a table and then perform an action on each of the selected items.  Each item’s id was sent to an XAgent and then processed.  In most cases it would work fine but occasionally I would run into this issue where after performing the action on some of the items, the xpage would stop working in some places, some of the partial refreshes would stop working and data that had been entered on the page would disappear.   It took a while to track down, but what was happening made sense once I figured it out.  The page stored several variables in viewScope and used the component tree extensively.  Every time the xagent was being triggered a new tree was getting generated and the state would get saved to memory, XPages has a limit on how many of these trees it will keep in memory or on disk, these settings are found in the xsp.properties.  The default limit for memory is 4 trees and 16 trees for disk per user session.  This was a problem, It was very easy for an end user to take up all of the memory allotted for component tree state.  This would override the original xpage that the user is looking at in memory and then xpages would have to rebuild it from scratch when its requested so anything loaded into the viewScope or into the component tree after the initialization would be lost.

There are a few solutions to this problem.

1.  Up the limit in the xsp.properties file.  This will increase the amount of ram/disk that your end users use and still might not solve the problem if they stay on the page continually performing the offensive action.

2.  Change the xagent to some other type of component where state isn’t a problem such as a json-rpc control or an extension library custom rest control (since 8.5.3), or Domino Servlet

3.  Write a Custom State Manager to override exactly when state is serialized and when its not, this was the road that I went down at first, one I plan on expounding upon later in my series on the XSP Starter Kit library.

4.  The fourth option is the one that is the easiest and I have to thank my colleague Troy Reimer for pointing out the “viewState” attribute on the <xp:view> tag, if you set this attribute to “nostate”  the xpage will be transient and its state will not be kept and the xagent will be rebuilt every time you load the page.  This is exactly what I needed as I wasn’t storing anything in viewScope or using the component tree in this xagent, so turning off the state made perfect sense.

 

This is a fairly easy problem to solve and probably not one that comes up too often but when it does it come up if you don’t know what’s happening it might take a while to figure it out.  I hope this post keeps someone in the future from dealing with the erratic behavior I was seeing in this app.  The moral of the story is when you are writing an xagent or really any xpage related object think about state and the trees that could be loaded into memory.

 

 

XSP Libraries

Since version 8.5.2, Domino Developers have an amazing tool that I feel has been underused due to the massive mindset shift of developing Domino Apps to developing Java Apps.  The Domino Server now has the capability of consuming OSGi Libraries.  These libraries can provide any amount of Java Code and provide it to all the apps on your server or domain via replication.  Part of the complexity has to do with the way these libraries created and deployed.  They aren’t NSFs, they are a different type of project that can be used to deploy many of the pieces of JSF functionality that I mentioned in my previous post.  Many of the OSGi libraries created for XPages contain XSP Libraries or “Extension Libraries”, a somewhat confusing name since we tend to call IBM’s extension to the core set of functionality in XPages “The Extension Library”.  These XSP Libraries are really just wrappers for some of the core JSF functionality to allow the developer to add it into a specific NSF via an entry in the XSP.properties file or globally to every app in a server.

Now that we have an idea of what an XSP Library is, let’s think about some ways we can use it.  We have a perfect example of how the XSP Library works in “The Extension Library” from IBM.  This Library contains all kinds of functionality for all the apps that specify it in their xsp.properties file.  It has Datasources, Components, Renderers, Managed Beans.  Another example of this kind of library is the bootstrap4Xpages library, it provides themes and custom renderers for already existing components.

All of these example are specific to NSFs where they are specified in the xsp.properties file, however XSP Libraries can be declared “Global” in which case the library is provided automatically to all the NSFs on the server in question.  One interesting example of this would be to provide functionality onto every page of an app, maybe a menu, or a new option every ViewPanel.  This could be done with change to the server, never touching any specific app.

XSP Libraries provide us awesome power to change things globally and re-use the code we write and make us more efficient as developers.

So, How do I write one, Actually the XSP Library is fairly simple, it only 1 class that you have to implement and 4 methods.

getPluginID returns the id of the OSGi plugin

getLibraryID returns the id of the Library, (This is what you see as an option in the XSP Properties.

getXspConfigFiles returns a String array of files in the plugin that specify any designer preferences.  This can return null if you are not specifying any.

getFacesConfigFiles returns a String array of files in the plugin that specify any faces-config files that will specify or override any functionality in the NSF.  This can return null as well.

Below is an example of one that you can find here:

https://github.com/tsamples/pdfjs

abstractLibrary

Another small thing you have to do inside your OSGi plugin when declaring an XSP Library is specify the extension point in the plugin.xml

Its really simple xml that just specifies the type of extension and what class specifies it.  The below example actually specifies two different types of extensions, the first <extension> tag specifies the XSP Library.

pluginxml

That’s really it, 2 files and you have an xsp library, the problem is an xsp library without anything in it is pretty useless, however as we go about this series we will add things into it that will make the library very powerful.  One thing to note is that this post was about XSP libraries and not so much about OSGi plugins,  There have been quite a bit written about these, very recently John Cooper wrote a post over at his blog that describes this process in good detail.

XPages extension points

XPages has some amazing features that we in the Domino community use to develop amazing apps, it also has some features that aren’t used as often.  Many of these features have to do with the JSF framework and the lifecycle inside of JSF.  Many people in the community have blogged and talked about lot of these features to try to gain awareness of them.  One of the best examples of many of these features is the XSP Starter kit, which includes examples rolled together into an Eclipse Plugin.  As an amazing resource as it is, There is some complexity involved in getting it installed and understanding all of the individual pieces.  I am starting a blog series where I will be breaking down each individual piece, explaining why and how you would use it and posting a small single example of that functionality to my github account for download.  These examples will include but are not limited to:

  • Custom ApplicationFactory
  • Custom FacesContextFactory (including custom ExternalContext)
  • Custom Lifecycle
  • Custom Component & Renderer (HTML5 Canvas)
  • Custom Expression Language Bindings
  • PhaseListeners
    ApplicationListeners
  • SessionListeners
  • FacesContextListeners
  • ValueChangeListeners
    ActionListeners
  • Custom PropertyResolver
  • Custom VariableResolver
  • Custom ViewHandler
  • NavigationHandlers
  • Custom StateManager
  • Resources and ResourceProviders
  • SSJS Library Provider
  • ManagedBeans for all 4 scopes (Application, Session, View, Request)
  • Implicit globals for SSJS

A few of these (like Managed Beans) have been discussed at length on many places, so I will not touch on them very briefly, My goal is to show off some of the other functionality that can make your life as a developer easier.  Expect the first installment within a couple of days.