Monday, September 7, 2009

Portlet Edit View with a single dropdown menu

Getting edit view (when you select "Edit" in the portlet title bar) to display dynamically calculated information can be done via a taglib. I'm going to create a tag called snmphosts using a manual method. There is probably a way to define this in Netbeans using a standard template.

First, create a taglib.tld (it's got to be called this I think).

<?xml version="1.0" encoding="ISO-8859-1"?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
  <tlib-version>1.0</tlib-version>
  <short-name>snmp-hosts</short-name>
  <description>
    A tag to display a set of snmp-reachable hosts as a dropdown menu.
  </description>
  <!-- display a set of reachable hosts as a HTML select element -->
  <tag>
   <name>snmphosts</name>
   <tag-class>examples.taglibs.SNMPHostList</tag-class>
    <attribute>
     <name>intf</name>
     <required>yes</required>
    </attribute>
   <body-content>empty</body-content>
  </tag>
</taglib>

What this specifies is the name of the tag, "snmphosts" and associates it with a Java class in the package examples.tablibs. I also declared an attribute, which is an argument to the tag that is required whenever we use it in HTML: the name of the interface to probe. In simple cases though, you may not need to define an attribute. Here is the SNMPHostList.java file that does the work:

package examples.taglibs;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
public class SNMPHostList extends TagSupport
{
 private static final long serialVersionUID = 1L;
 String intf;
 public int doStartTag() throws JspException
 {
  JspWriter out = pageContext.getOut();
  try
  {
   out.println( "<select>" );
   String[] hosts = inetaddr.getSubnetHosts( intf );
   for ( int i=0;i<hosts.length;i++ )
   {
    out.print("<option>");
    out.println( hosts[i] );
    out.print("</option>");
   }
   out.println("</select>");
  }
  catch ( Exception ioe )
  {
   throw new JspException( ioe );
  }
  return SKIP_BODY;
 }
 public int doEndTag() throws JspException
 {
  return EVAL_PAGE;
 }
 /**
  * Get the interface name
  * @return intf the name of the interface
  */
 public String getIntf()
 {
  return intf;
 }
 /**
  * Set the interface name
  * @param intf the name of the interface in the scenario, 
  * e.g. "eth1"
  */
 public void setIntf( String intf )
 {
  this.intf = intf;
 }
}

This is mostly boilerplate stuff from the TagSupport class (check the Java API documentation). By providing the setIntf and getIntf methods the JSP engine will automatically set the intf instance var for you when it is provided via an attribute. You could equally call them setBanana and getBanana if you had a instance var called "banana". For empty tags as in this case you just do the start tag and "skip" the body. That's what the return values are for. doEndTag hence does nothing. In doStartTag all we do is write out a HTML <select> element with embedded <option>s. We get the options from the inetaddr class which computes a list of available snmp (or pingable) hosts on the network.

To build the library all you do is compile the SNMPHostList.java file using appropriate libraries on the classpath, which you can get from Pluto: I used servlet-api.jar, jsp-api.jar and portlet-api_2.0_spec-1.0.jar. Then place the .class file in a folder called anything, e.g. "hello". Also in that folder create a META-INF directory and copy the taglib.tld file into it. Then cd into hello and make a jar out of it:

jar cf ../hello.jar .

Just drop the taglib into the lib folder inside a WEB-INF folder inside a web application (like a portlet) and the tag should now be available.

Using the tag

You should already have an edit.jsp file inside your portlet. Change it so that it calls the tag:

<%@ taglib uri="/WEB-INF/lib/hello.jar" prefix="mytag" %>
<html>
<body>
<mytag:snmphosts>
 <jsp:attribute name="intf">eth1</jsp:attribute>
</mytag:snmphosts>
</body>
</html>

"mytag" is just a namespece abbreviation and can be anything. The key is that we define mytag to BE hello.jar so when we invoke it using <mytag:snmphosts> the java class file gets called to produce its output. The attribute is passed in using the ugly XSLT-type syntax because it is more flexible, but you can also use a direct attribute in simple cases.

When you select Edit mode now in the portlet you should get a dropdown list of computed hosts.

No comments:

Post a Comment