Author Archive: Venkata Adidam

LC Designer: Single Web Service with Many Services

One side-effect of using Web Services in LC Designer is that you create a lot of data connections; in LC Designer and other IDEs consuming Web Services is not a big deal. For Form Desingers in particular, they seem to be consuming a lot more than the other development groups like: Java, AJAX, etc. And what amounts to is a tens of unique Web Services called within a single form. The problem is keeping up with all the WSDL and server changes. I’ve watched a developer change twenty forms because a single webservice was changed. I’ll show you a simple technique that can solve these problems.

What I do instead of creating many web services is that I create a single web service: invoke(Stirng in, String out)

This web service does nothing else but take a String as input parameter and write a String out as an output parameter. For the format of the String I use JSON. So the web service is more like: invoke(JSON in, JSON out).

Within the JSON in my object has the following:

jsonInputObject:{

       serviceID, //Says which service to invoke.

       messageObject:  {

              //Message specific stuff here

        }

}

I like JSON since its natively represented in JavaScript and I can represent what ever I want. Since most of the web service calls from LC Designer are stateless, I don’t worry about the overhead of using a stateful mechanism which adds bloat. 

Using a single web service that makes a call for you on the server side has the following advantages:

  • Don’t have to stub out a unique service call for every service
  • All services are available to you during design time.
  • Unit testing is easier because you can test your JavaScript on the form against a fixed JSON test object.
  • Adding an optional input parameter or adding a additional return parameters doesn’t require regeneration of your stubbed code.

So below is an example of what my LC Worflow process looks like:

 

ExampleService.png

In this implementation, there are only two services. One to retreive group information and other for office information. Instead of creating two web services, I just have one. For this project I’ll keep adding services to this process. I’ve had projects where are twenty service calls are represented with a single web service call.

 

LiveCycle Development Techniques

Whenever I start development on a LiveCycle project, which usually involves LC Forms, LC Reader Extensions, LC Output, and LC PDF Generator. I utilize Acrobat for most of my prototyping and debugging. I’ll list the frequently used techniques:

  1. LC Reader Extensions – For those beginning to build forms with LC Designer know their form will be Reader Extended before going into production. I’ve seen cases where they will modify a form, manually Reader Extend, and then test their change. To save time, get a copy of Acrobat installed on your machine and use that to test changes. The other way is just too
    masochistic.
  2. LC Forms – Most likely you will be exporting data from a PDF or importing data into a PDF. You need to test a form or a generated XML that binds to a form. A quick way is to open the pdf in Acrobat then to -
    • Export Data from a form: Acrobat menu -> Forms -> Manage Form Data -> Export Data
    • Import Data into a form:  Acrobat menu ->  Forms -> Manage Form Data -> Import Data
  3. LC PDF Generator – You run into a problem where LC PDF Generator gives you an error while converting a non-PDF file. Open the non-PDF file in its native application and print as a PDF. The most common error is permission not to export data or print.
  4. LC Output – Here I prefer to use a unit test case, in most cases flattening a PDF will work file in Acrobat but making an API call reveals more details.

Hope this helps.

Acrobat JavaScript Extensions – Hello World

When we think "adding a button to the Acrobat Toolbar or Menu Item" we think: C++ Plugin; There is a far easier and less known alternative via JavaScript. That’s what I’d like to write about today. I’ve finished a project using JavaScript extensions for Acrobat, the customer is very happy because he can and did modify the extension himself. The one caveat is that not all the C++ functions are available in JavaScript but nonetheless still powerful.

I like the traditional "Hello World" examples, that’s what I look for when ever I start coding in a new language, framework or library; so I’ll give the reader a "Hello World" example.

Check the JavaScript for Acrobat Documentation for the exact use of each library call.

So open up your favorite text editor and the following self-explanatory code to HelloWorld.js

function helloWorld()
{
     //Say Hello World
     app.alert("Hello World");
}

app.addToolButton({
       cName: "helloWorldBtn", // A name for your button
       cExec: "helloWorld()", //Function to Call
       cLabel: "Hello World", //The Text on the Button
       cTooltext: "Say Hello World" //The Help Text
});

Drop the HelloWorld.js to:

  • Mac – /Users/<user id>/Library/Application Support/Adobe/Acrobat/9.0_x86/ JavaScripts
  • Vista – C:\Users\<user id>\AppData\Roaming\Adobe\Acrobat\9.0\JavaScripts

Restart Acrobat and open-up any PDF and you should see the following button added to the tool-bar.

 

Clicking on the button you should see your Hello World alert.

 

Conway’s Law and Code Ownership

Conway’s Law is one observation we can use as a guide on the initial stages of a Software project, it basically states that development modules organize themselves around the communication structure of an organization. So simply put, if you get three guys in a room that want to quickly roll-out a compiler and not interfere with each other’s work, you will have a three part compiler. Why? because each person does not want to know what the other is doing as long as each has stuck to an agreed interface, everyone is happy.

So, an architectural decision has been made, not by a best practice but by social communication. If the same three developers collaborated on a high-level architecture, a good design, and worked closely on its implementation, my guess is that they would have better results. Not only in the quality of work produced but also other intangibles.

Ever have one developer that is over-worked while the other ten developers wished they could help? Well, not paying attention to Conway’s law is probably the culprit. It is easy to fall into the the argument that: by giving each module an owner we have one throat to choke.

This type of thinking forgets some important items:

  1. People work on projects, someone will take unforeseen time-off.
  2. Dividing up modules does not necessarily divide work equally. Ever have a developer that had a super-easy module and wanders around like the floor like he’s the only one that has his act together?
  3. Unforeseen work presents a challenge on which module it belongs as each module owner will attempt to push the new work onto another. For example, where should certain validations be placed: front-end, middle tier, or at the persistence layer? I bet you the group that with the least political leverage will get this extra work.

So what can we do to break down the social communication barrier? One technique is to implement review practices. Requirements Reviews, Design Reviews, or even Pair Programming, just as long as people are talking.

Remember, a majority of Software Engineering problems can be boiled down to a lack of communication, so don’t avoid communication. The days of the unsociable introvert coder hiding in a dark basement as to avoid human contact is over.

Jar Jar to the rescue

I think we have all seen a JAR conflict on an application server, I still use JDOM and usually run into a conflict with an older version of the JAR installed somewhere on the system that I usually can’t touch.

So, what I did was to use an Ant task called Jar Jar that is available at: http://code.google.com/p/jarjar/

Jar Jar will take a Jar file or (a group of Jar files), change the package names, and repackage the result in a new Jar File. The idea is that you can create your own Jar file with your dependencies packaged in.

I use the BeanShell scripting language (www.beanshell.org) which is what the LiveCycle ES Workbench Script Object is based on. There is no JAR file that I deploy but a script, therefore no compiled code to deploy. So, I use Jar Jar a little differently then what is documented on Jar Jar’s Wiki. I create my own package for JDOM and one of its dependencies Jaxen and I place the new Jar file in the classpath.

My, Ant file looks like the following:

<project name="CustomJDOM" default="jar" basedir=".">

     <taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="./jarjar-1.0rc7.jar"/>

     <target name="jar">

        <jarjar jarfile="jdom_custom.jar">

               <zipfileset src="lib/jaxen-core.jar"/>

              <zipfileset src="lib/jaxen-jdom.jar"/>

             <zipfileset src="lib/jdom.jar"/>

             <rule pattern="org.jaxen.**" result="org.jdom_1_1.jaxen.@1"/>

             <rule pattern="org.jdom.**" result="org.jdom_1_1.@1"/>

        </jarjar>

     </target>

</project>

 

Taking it a line by line:

<project name="CustomJDOM" default="jar" basedir=".">

Standard Ant project tag, the default target is "jar" which kicks of the Jar Jar task.

<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="./jarjar-1.0rc7.jar"/>

This is how you declare a new Ant task (or one of the ways), make sure you update the "classpath" variable to where ever you installed the "Jar Jar" Jar file.

<target name="jar">

I’m declaring a task to be run.

<jarjar jarfile="jdom_custom.jar">

This line kicks-off the Jar Jar task and writes the result to a file called: jdom_custom.jar

<zipfileset src="lib/jaxen-core.jar"/>

<zipfileset src="lib/jaxen-jdom.jar"/>

<zipfileset src="lib/jdom.jar"/>

The list of Jar files that will be repackaged in the new Jar file with a new package name.

<rule pattern="org.jaxen.**" result="org.jdom_1_1.jaxen.@1"/>

<rule pattern="org.jdom.**" result="org.jdom_1_1.@1"/>

I’m changing the package name from org.jaxen to org.jdom_1_1.jaxen and org.jdom to org.jdom_1_1.

To use the new Jar File. Include "jdom_custom.jar" in your classpath and use the new package names. So instead of using the package name: org.jdom in your code use: org.jdom_1_1. You never have to worry about a Jar file conflict again.

Zen and the Art of Offline Data Capture

Whenever, I meet with developers on how to use LiveCycle technologies (or PDF in general), I usually run into: the user fills out the data here … and the PDF is generated here. Generating a PDF for printer friendly output is good, but that’s not all a PDF can do. A PDF can capture data and save you a lot of time and overhead.

So take a traditional web-based application where a user needs to fill-out a form. Look at the over-head that is behind the web form: User Management for the user to save/retrieve a form, Load Balancing during peak-usage, complexity if the user wants to forward the form to another user, and Availability if you want to add a second form to your web-application without down-time.

Enter the world of off-line submission, provide the end user a fillable PDF; this will allow an anonymous user to fill, save, and forward the PDF to another individual (via e-mail or USB drive). When the user is done, have the user e-mail the filled PDF back to your server. The e-mail might take a few hours before reaching your server, but who cares? The end-user isn’t waiting on a spinning hourglass to stop. If you need another form, then create a new PDF and publish it. A new PDF doesn’t necessarily have to be created by the developer of your Web Application team. Another group can create the PDF as long as both of you agree to an XML Schema. See, a nice decoupled system, when was the last time you can leverage a User Interface from another team?

Not all clients implement this solution in exactly the same way as above, some have the need to submit a 200 Megabyte PDF. In this case e-mail would not work and would have to revert back to an HTTP submission, they will loose some benefits but also gain some as well. Hopefully, the reader gets some new ideas in solving some old problems.

So, if you want to prototype the solution, then the LiveCycle products you would need: LiveCycle Forms to pre-populate and extract data, LiveCycle Reader Extensions, this will allow (amongst other things) a PDF to be saved locally with Adobe Reader. And finally LiveCycle Designer that helps you create your PDF.

Adobe Consulting, Public Sector – Genesis

Hello everyone, the Adobe Consulting Public Sector group has been around for a number of years mainly working on LiveCycle and Flex projects. We decided that it was time to start communicating to the world the experiences we are gaining from working out at the field.

A little bit about our selves, we are not an Engineering, Marketing, or a Sales team, we are simply humble souls that need to get projects working at our customer’s site. So what will we blog about? Anything that we run into(or have) in our current or past projects that the world might gain from. We are Computer Scientists by nature and education, so anything within the field should be expected.

So let the blogging begin….