Create a Java Plug-in

"Plug-ins" give Logi Info developers the ability to programmatically extend the functionality of their Logi applications. This topic discusses the development of Logi plug-ins using Java.

IMPORTANT: If you are using Info v12.7 SP1-9 and you wish to upgrade to JDK 8 release build 261 (1.8.0_261), or any later build of JDK 8, you will need to replace the mscorlib.jar file in the application folder with the new one and restart your server. The mscorlib.jar file can be found on our Product Download page. Please contact Support for additional assistance.

 If you haven't done so already, you should read Logi Plug-ins for important supporting information before proceeding. If you're developing a .NET plug-in, see Create .NET Plug-in instead of this one.

 

Writing Your Plug-in

Plug-ins written for Logi applications on Java platforms are included as either standalone .class files, in the Logi application's WEB-INF/classes folder, or as a class file within a .jar file in the Logi application's WEB-INF/lib folder.

 Many copies of the files that define the LogiPluginObjects and LogiPluginObjects10 classes, LogiPluginObjects.java and LogiPluginObjects10.java, may exist on your hard drive if you're working with multiple Logi applications. To ensure version compatibility, be sure to use the file found in the folders of the Logi application that will use the plug-in you're creating.

Logi definitions and data are handled as XML streams during processing by the web server and therefore by your plug-in, too. Much of your code will be concerned with searching, parsing, and modifying this XML. If you're familiar with XPath notation, you'll find that to be very helpful as well.
 

Create your plug-in project in Eclipse

Here's an example of the steps needed to create a plug-in using the popular Eclipse IDE:

  1. Create a standard Java Project. The Project Name is inconsequential if you're compiling to a single class file. The version of the JDK used in the plug-in project should match the JDK version used to run the Logi application on your web server.



  2. Add the necessary source code files and library references to your project. For example, to create our Plug-in (Java) sample application, we added the files shown above. You must include these two Logi files:
     
    1. yourLogiApp/WEB-INF/lib/PluginCaller.jar
      yourLogiApp/WEB-INF/lib/rdPlugin.jar
    We also had to include the other references to several .jar files to satisfy the requirements of our sample code.
  1. Eclipse requires that the project output be placed within the project folder. Once created, you'll need to copy it to either:
      1. yourLogiApp/WEB-INF/classes  (.class file)    - or -
        yourLogiApp/WEB-INF/lib (.jar file)
  2. Write your plug-in code, starting with this prototype:
     
 
import org.w3c.dom.*;
import org.w3c.dom.Document;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.util.Hashtable;

import com.logixml.plugins.LogiPluginObjects10;


public class myPlugin
{
   public void yourMethodName(LogiPluginObjects10 rdObjects)
   {
      /* your method code goes here */
   }
}
 

    Add the methods and code you need to get the plug-in to do whatever it's supposed to do.

Back to top

Example: Change the Application Caption

The following are code examples for a plug-in that alters the caption of the Logi application at runtime:

 
import org.w3c.dom.*;
import org.w3c.dom.Document;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.util.Hashtable;
import com.logixml.plugins.LogiPluginObjects10;
  import java.io.*;
import java.io.File;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.OutputKeys;
import com.sun.net.httpserver.HttpContext;
public class myPlugin
{
   public void SetApplicationCaption(LogiPluginObjects10 rdObjects)
   {
      try
      {
         DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
         DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder);
         byte b[] = rdObjects.getCurrentDefinition().getBytes();
         java.io.ByteArrayInputStream input = new java.io.ByteArrayInputStream(b);
         Document xmlSettings = docBuilder.parse(input);
         NodeList nl = xmlSettings.getElementsByTagName("Application");
         if (nl.getLength() > 0)
         {
            Node nodApp = nl.item(0);
            Element eleApp = (Element)nodApp;
            eleApp.setAttribute("Caption", "Greetings from the Sample Plugin!");
            rdObjects.setCurrentDefinition(getOuterXml(xmlSettings));
         }
      }
      catch (Exception ex)
      {
         ex.printStackTrace();
         System.out.println("SetApplicationCaption Error " + ex.getMessage());
      }
   }
}

Back to top

Example: Modify a SQL Query with Request Variable

The following are code examples for a plug-in that customizes a SQL query based on a request variable:

 
import org.w3c.dom.*;
import org.w3c.dom.Document;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.util.Hashtable;
import com.logixml.plugins.LogiPluginObjects10;
 import java.io.*;
import java.io.File;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.OutputKeys;
import com.sun.net.httpserver.HttpContext;
public class myPlugin
{
   public void SetCustomerQuery(LogiPluginObjects10 rdObjects)
   {
      try
      {
         DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
         DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
         byte b[] = rdObjects.getCurrentDefinition().getBytes();
         java.io.ByteArrayInputStream input = new java.io.ByteArrayInputStream(b);
         Document xmlDefinition = docBuilder.parse(input);
         NodeList nl = xmlDefinition.getElementsByTagName("DataLayer");
         if (nl.getLength() == 0)
         {
            throw new Exception("The report is missing the DataLayer element.");
         }
         //Use a Request variable to set set the SELECT query.
         int iPos = rdObjects.getRequestParameterNames().indexOf((Object)"Continent");
         if (iPos < 0)
         {
            throw new Exception("Continent Parameter name not found in SetCustomerQuery ");
         }
         String sContinent = (String)rdObjects.getRequestParameterValues().get(iPos);
         String sSelect = new String();
         if (sContinent == null)
         {
            sSelect = "SELECT * FROM Customers";
         }
         else
         {
            if (sContinent.equals("NA"))
            {
               sSelect = "SELECT * FROM Customers WHERE Country IN('USA','Mexico','Canada')";
            }
            else
            {
               if (sContinent.equals("SA"))
               {
                  sSelect = "SELECT * FROM Customers WHERE Country IN                              ('Argentina','Brazil','Venezuela')";
               }
               else
               {
               if (sContinent.equals("EU"))
               {
                   sSelect = "SELECT * FROM Customers WHERE Country IN                         ('UK','Sweden','France','Spain','Switzerland','Austria',
                        'Portugal','Ireland','Belgium','Germany','Finland','Poland','Denmark')";
               }
               else
               {
                  sSelect = "SELECT * FROM Customers";
               }
            }
         }
      }
      Node nodApp = nl.item(0);
      Element eleDataLayer = (Element)nodApp;
      eleDataLayer.setAttribute("Source", sSelect);
      rdObjects.setCurrentDefinition(getOuterXml(xmlDefinition));
   }
   catch (Exception ex)
   {
      ex.printStackTrace();
      System.out.println("SetCustomerQuery Error " + ex.getMessage());
   }
}

Back to top

Implementing Your Plug-in

When your plug-in has been written and compiled, add the element(s) you need to call it in your Logi application. The elements used to do this are described in Logi Plug-ins.

The first time you run your Logi application, your web server may load the plug-in into memory and cache it there. If you make coding changes to the plug-in and want to rebuild it, you may need to stop and restart your web server first, in order to be able to replace the previous build.   Back to the top  

Debugging Example: Eclipse and Tomcat

You can debug your plug-in as it runs in your Logi app. Due to the variety of Java tools and web servers available, it's not possible to provide comprehensive debugging guidance here. However, the following example, using the Eclipse IDE and the Apache Tomcat web server should be helpful.

Generally speaking, Java application servers support a Debug mode, which can be enabled when starting the application server. This creates a debugging server, which is typically available on port 8000. You connect your Eclipse project to this port to start debugging your application.

If you're developing and testing on your desktop platform, to enable Debug mode navigate to the {catalina_home}/bin folder and execute the following commands:

    set JPDA_ADDRESS=8000
    set JPDA_TRANSPORT=dt_socket
    catalina.bat jpda start

If Tomcat is on a remote machine, you may instead add this to your JAVA_OPTS:

    -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n

Tomcat should start, with its secondary debugging server running. If you have difficulty with this, consult your web server documentation.
 


     

Next, in Eclipse, open your plug-in project, and then click the little options arrow beside the Debug icon on the toolbar, as shown above. Select the Debug Configurations... option in the pop-up menu that appears.
 


Double-click the Remote Java Application item in the left menu to create a new debug profile, as shown above. Then,

  1. Provide an arbitrary profile Name.
  2. Browse for and select your plug-in Project.
  3. Ensure that the Connection Properties are correct. The Host is the base address of your Tomcat server; if it's running on your development machine, then it will be localhost. The Port is the one configured when starting Tomcat (default: 8000).
  4. Click Debug to begin your debugging session.

Eclipse will now connect to the debugging server loaded in Tomcat and is then ready for you to browse your Logi application. Interacting with your Logi app will eventually run your plug-in; proper debugging can begin in Eclipse at that point, with the use of watches, breakpoints, etc. These techniques are beyond the scope of this topic; see your Eclipse User Guide for more information.
 

To end your debugging session, click the Disconnect icon in the Debug view toolbar, as shown above.

 If you haven't done so already, you should read Logi Plug-ins for important supporting information before proceeding.

 If you're developing a .NET plug-in, see Create .NET Plug-in instead of this one.

 

Plug-in Class Methods and Properties

Logi plug-ins for Java are written in Eclipse or a similar development tool, using the LogiPluginObjects10 class. The class files are:

    yourLogiApp/WEB-INF/classes/com/logixml/plugins/LogiPluginObjects10.java  - or -
    yourLogiApp/WEB-INF/classes/LogiPluginObjects.java

You instantiate this class in your code and it provides access to the Logi application and its data. The class object is defined in your code as: 

    public class LogiPluginObjects10 (or LogiPluginObjects)
    extends java.lang.Object


Once instantiated, the object provides the following properties and methods for use with your custom code.
 

   


Here are the object's methods and parameters:
 

addDebugMessage
Inserts an entry into the Debugging Trace page.void addDebugMessage(java.lang.String currentEvent)
void addDebugMessage(java.lang.String currentEvent, java.lang.String programObject)
void addDebugMessage(java.lang.String currentEvent, java.lang.String programObject, java.lang.String      objectValue)
void addDebugMessage(java.lang.String currentEvent, java.lang.String programObject, java.lang.String      objectValue, java.lang.Object More Info)
Parameters:
   currentEvent - text to the inserted in the Trace page's Event column
   programObject - text to the inserted in the Trace page's Object column
   objectValue - text to the inserted in the Trace page's Value column
   More Info - object, such as XML data or XSL code, that is displayed via link inserted in the Trace page's Value column
The time value for the entry is automatically provided. Note that if an error occurs within the plug-in, a fresh Trace page is generated, so any earlier messages placed with addDebugMessage are lost.

Back to top

getCurrentData / setCurrentData  
Gets/sets an XML Document object containing the data in all of the datalayers. public org.w3c.dom.Document getCurrentData()
public void setCurrentData(org.w3c.dom.Document curdata)

Back to top


getCurrentDataFile / setCurrentDataFile
Gets/sets a string object containing of the fully-qualified path and filename for the cache file containing the XML data retrieved by the datalayer. public java.lang.String getCurrentDataFile()
public void setCurrentDataFile(java.lang.String currentDataFile)


Back to top

getCurrentDefinition / setCurrentDefinition
Gets/sets a string object containing the XML source code of the current report definition. public java.lang.String getCurrentDefinition()
public void setCurrentDefinition(java.lang.String curdef)


Back to top

getCurrentElement / setCurrentElement
Gets/sets a string object containing the XML source code of the current report definition. public org.w3c.dom.Element getCurrentElement()
public void setCurrentElement(org.w3c.dom.Element ele)


Back to top

getCurrentHttpContext / setCurrentHttpContext
Gets/sets an XmlDocument object containing all HTTP-specific information, including Application, Session, Server, Request, and Response objects public javax.servlet.ServletContext getCurrentHttpContext()
public void setCurrentHttpContext(javax.servlet.ServletContext currHttpContext)


Back to top

getPluginParameters / setPluginParameters
Gets/sets a Hashtable object containing the parameters, if any, passed to the plug-in. public java.util.Hashtable getPluginParameters()
public void setPluginParameters(java.util.Hashtable plugPar)

Back to top

replaceTokens
Returns a string object containing the sTokens parameter with some or all of its tokens replaced with their current values, and with other optional effects applied. replaceTokens(java.lang.String sTokens)
replaceTokens(java.lang.String sTokens, boolean bDuplicateSingleQuotes)
replaceTokens(java.lang.String sTokens, boolean bDuplicateSingleQuotes, org.w3c.dom.Element    eleDataLayerRow)
replaceTokens(java.lang.String sTokens, boolean bDuplicateSingleQuotes, org.w3c.dom.Element    eleDataLayerRow, boolean bDuplicateBracketedQuotes)
replaceTokens(java.lang.String sTokens, boolean bDuplicateSingleQuotes, org.w3c.dom.Element    eleDataLayerRow, boolean bDuplicateBracketedQuotes, boolean bAssumeNonQuotedAsNumeric)
replaceTokens(java.lang.String sTokens, boolean bDuplicateSingleQuotes, org.w3c.dom.Element   eleDataLayerRow, boolean bDuplicateBracketedQuotes, boolean bAssumeNonQuotedAsNumeric, java.lang.String[]   tokenList)
replaceTokens(java.lang.String sTokens, boolean bDuplicateSingleQuotes, org.w3c.dom.Element   eleDataLayerRow, boolean bDuplicateBracketedQuotes, boolean bAssumeNonQuotedAsNumeric, java.lang.String[]   tokenList, boolean bSqlInjectionGuard)
Parameters:
   sTokens - string containing Logi tokens, such as @Data.LastName~, to be replaced with current values.
   bDuplicateSingleQuotes - if True, causes any single-quotes in sTokens to be doubled in return string.
   eleDataLayerRow - XmlElement containing the data that will be used to replace the @Data tokens in sTokens.
   bDuplicateBracketedQuotes - if True, double-quotes embedded in a token value will be included in return string.
   bAssumeNonQuotedAsNumeric - if True, replacement processing will handle unquoted, numeric token values as numbers.
   TokenList - comma-separated list of token types, indicating the types to be replaced; other types will be skipped.
   bSqlInjectionGuard - if True, replacement processing checks all token values for potentially dangerous SQL strings.
Throws:
   javax.xml.parsers.TranformerConfigurationException
   java.lang.Exception
 

Back to top

setRequest
Sets an HttpServletRequest object and passes it as an argument to the servlet's service methods. public void setRequest(javax.servlet.http.HttpServletRequest req)
 

Back to top

getRequestParameterNames
Gets an array of the HTTP Request names sent by the client to a Logi application. public java.util.Vector getRequestParameterNames()

Back to top

getRequestParameterValues
Gets an array of the HTTP Request values sent by the client to a Logi application. public java.util.Vector getRequestParameterValues()

Back to top

getResponse / setResponse
Gets/sets an HttpServletResponse object containing the rendered HTML response page; available when the FinishHtml event completes. public javax.servlet.http.HttpServletResponse getResponse()
public void setResponse(javax.servlet.http.HttpServletResponse res)


Back to top

getResponseHtml / setResponseHtml
Gets/sets a String object containing the rendered HTML response page, available when the FinishHtml event completes. public java.lang.String getResponseHtml()
public void setResponseHtml(java.lang.String resp)


Back to top

getReturnedDataFile / setReturnedDataFile
Gets/sets a String object containing the fully-qualified path and filename for the cache file which contains the manipulated XML data after processing. public java.lang.String getReturnedDataFile()
public void setReturnedDataFile(java.lang.String returnedDataFile)


Back to top

getSession / setSession
Gets/sets an HttpSession object, which is used to access Session values for the current Logi application session. public javax.servlet.http.HttpSession getSession()
public void setSession(javax.servlet.http.HttpSession ses)

Note that most session variables are replicated back and forth between the Logi Engine and the web server with every plug-in call.

Back to top

getSettingsDefinition
Gets an XML Document object representation of the _Settings definition. public org.w3c.dom.Document getSettingsDefinition()

Throws:
   javax.xml.parsers.ParserConfigurationException
   org.xml.sax.SAXException
   java.lang.Exception
 

Back to top

Keywords: plugin, plugins