Tuesday, April 28, 2009

Geographic Translator

The interesting challenge with Geographic Translator has nothing to do with portlet technologies. This application is in dire need of someone with Graphical User Interface skills.

There are very cryptic parameter strings that have to be composed and passed in to the service to produce the desired transformation. Wanting to provide a capability to support transformations between 36 different coordinate systems and 230 different datums, while leaving the SOAP parameters as close as possible to the parameters of the underlying legacy application, has led to a very confusing set of instructions.

It was much easier to use the code completion feature of NetBeans after building the web service client to figure out exactly what data was needed by each of the service options. But then, not being very adept at designing web page forms, I was left to struggle with figuring out the best way to present the instructions to users for the many different use cases.

I was starting to get the hang of using the HTML div tag and the onClick javascript function to dynamically present the user with the form fields needed for input based on which type of transformation was being performed. Then suddenly the WSDL was no longer accessible over the network. So what was going on this time?

After a number of email exchanges (what exactly does "they changed something on the external firewall to prevent me natting" mean?) I found out that the IP address of the 6 WSDLs I was using in the NetBeans project that has the 6 SOAP Web Service clients had been changed. So now, how difficult is it to get the code working again?

I remembered the little trick of doing a "Refresh Client" to point the services to the new WSDL location. I also did a clean and build. The build was now working but if I tried to run the project and access one of the services I would continue to get an exception stating that the WSDL could not be found because it was looking at the old IP address. The solution was to delete each of the web service clients and then recreate them with the new WSDL. Not really that time consuming once I knew what had to be done, but, of course, the whole day was wasted trying to figure out what was going on.

The developer of the SOAP Web Services was kind enough to provide me with his code solution that uses a configuration file to make a Web Service client configurable after deployment. That will definitely bear looking into since this environment is proving to be somewhat less than stable.

Wednesday, April 22, 2009

Geonames Service Portlet is done

I contacted the developer of the Web Service to see if he could help troubleshoot the com.sun.xml.internal.ws.server.UnsupportedMediaException that I was getting. At first he said he wasn't getting the exception but when I sent him the code of the simple Java client I had built he reproduced the error.

It appeared that my code was sending a blank string for one of the query parameters and rather than sending XML the service was generating an HTML error page--something a SOAP service is not supposed to do. The developer determined that the problem was with the Saxon9 library file built into the Web service projects. The Saxon library is needed for XSLT 2.0 transformations but, apparently, there are problems using Saxon9 with Glassfish. Once the library was moved out of the projects and into the system lib for Glassfish, the service began returning the correct error messages. From there, it was up to me to do my usual fumbling around with trial and error and using the NetBeans debugger to get the portlet working.

Meanwhile, I had the opportunity to do some reading in the book "JBoss Portal Server Development" by Ramanujam Rao. The sample code accompanying the book gave me an idea on how to restructure the geonames portlet. Instead of having one form on the view page with a pulldown to select the four different service options I created 5 different view pages. The initial page is a table with links and descriptions of the 4 services. Behind the links I use the renderURL to load the view page for the selected service. This made it much easier to break out the slight differences in input parameters for each of the 4. It took me awhile to grasp the correct logic flow to make sure the right page is displayed at the right time and that the data is there for dispaly when it's supposed to be.

That exercise gave me a better understanding of when to use renderURL versus actionURL and the difference between parameters and attributes. Since the Portlet Specification is modeled after the Servlet Specification I would probably have an easier time grasping the concepts if I were more familiar with the Servlet spec.

On to the next one--Geographic Translator service. Looks complicated.

Wednesday, April 15, 2009

Geonames Service Portlet

I thought I had settled on a good process for building the SOAP Service client portlets. Development was just getting to the point of being routine--dump the WSDL URL into the NetBeans Web Service Client wizard, adjust the sample HTML query form to make it a dynamic JSP page for the portlet view mode, and then use NetBeans code completion to figure out what parameters the web service calls required. Coordinate Parse, Country Names and Geoid Height (single and multiple) were finished and posted to the virtual server to be viewable over the Internet. That brought me approximately to the place I had been when the services were hosted on a different server and I had first built the portlets.

But then I tackled Geonames Service, which had not been available the first time I was on this task. It appeared to be straighforward like the others. There was a WSDL and a sample HTML query form. The query form had 4 different submit buttons for 4 different cases so I had to make a decision on whether or not to break out the 4 into separate portlets like I had done with the 2 different Geoid Height input forms. I opted instead to use one portlet with one form, but added to the form a pulldown for the 4 different options. There are a couple of extra fields required for 2 of the 4 queries so at some point I will need to figure out how to dynamically change the HTML so that it displays the extra fields when the user selects one of the pulldown options where those fields are required.

To get something up and running quickly I decided to use the defaults for entry parameters and just make sure I could return and display the same thing as the sample query form. I then realized that even the sample was not returning data in a couple of the cases. Contacting the developor gave the explanation that the backend database of the web service had only a small sampling of data loaded. He gave some guidance on which query parameters would be most likely to yield data. Unfortunately, when I finally got to the point of being ready to do the initial basic query through the portlet I ran into a new snag.

The client was returning an exception:
com.sun.xml.internal.ws.server.UnsupportedMediaException: Unsupported Content-Type: text/html;charset=utf-8 Supported ones are: [text/xml]

Putting the client in Debug mode showed that the service and port calls were successful and the input parameter was being loaded with all the necessary data. But then the call to the actual operation itself caused the exception. And it was the same exception regardless of which of the 4 operations were used.

I googled the text of the exception but it didn't help me figure out the source of the problem or how to solve it. Some suggestions were to examine the server log, but that isn't an option since I have no access to the server that's hosting the service. Someone suggested using SOAPUI to see what is being returned by the server, but I'm not sure how to do that. I don't understand enough about the flow of the messages between the browser and the service to know where to look into what's going on. I even tried to simplify things by leaving the portlet, portlet container, servlet container, etc out of the picture and just building a basic Java application client to make the query. But the same thing happens--the service returns the exception as soon as the call to the operation is made. And I don't know how to use the debugger to dig any further into what happens during the call.

Thursday, April 9, 2009

Geoid Height Calculator Portlet

Taking the portlets that were built originally to make SOAP Web Service calls and modifying them so that they would directly call the servlets that use the RESTful interface turned out not to be worth the effort. I decided to stick with just making the changes that would be needed to match the changes in the Web Services.

The first one that I started with was the geoid height calculator. It took awhile to figure out the new service calls and parameters and how to correctly set them up to get the results back from the server. The code completion feature of NetBeans was a big help with that.

Then I decided that I had not really designed the original portlet correctly in how it was interacting with the user to get the input data and display the output data. Plus I had not figured out in the first go-round how I should give the portlets a default input setting. I looked at more sample portlets, reread some of the documentation on the Portlet API and learned more about render parameters, RenderRequest, ActionRequest, ActionResponse, and how the portal, the portlet container, and the portlets all interact with each other and with the user.

I'm still not where I need to be. I can't decide the best approach for presenting the data input form to the user and then presenting the results from the Web Service call. Currently, I have not made use of the EDIT mode. I'm doing everything in the VIEW mode, checking in doView() to see if there's a calculated result to display. If not, the doView displays a JSP page that has the input form. If there are results to display, a different JSP page is displayed. On that page I have a "Back" link that takes the user back to the JSP page with the form after the results data has been viewed.

The problem I'm seeing is that when I'm in the same browser and I rerun the portlet after making some change to the code the view that comes up is the view that I had previously. I'm setting the ActionResponse render parameters in the processAction so they are available when the results are rendered. I would have expected that when the portal makes the first render request to the portlet that it would have no attribute data yet because the user has not yet entered anything in the form. But whatever information was in the render parameters from the previous use of the form, including the calculated result, is still available when doView() is first called. This causes the JSP page with the results from the last calculation to be displayed, instead of the JSP page with the form, as I would have expected. My thinking now is that instead of using two different pages in the VIEW mode to accomplish the gathering of data and displaying of results, what I may want to do is use the EDIT mode to display the page with the form and the VIEW mode to display the results and/or the blank starting page. But, again, I may run into the difficulty of not knowing the difference between the state of when there is data to display and when it's the starting state where the user has not yet submitted a request.

The Geoid Height Web Service offers two separate service queries. The one that the current portlet uses is the case where the user can input a single coordinate pair from which to calculate Geoid Height. I have the correct (I think) code inside the processAction method to handle the other case where the user can input a list of coordinate pairs and get the Geoid Height for each pair. But I couldn't decide the best way to display a second option in the form for that case. I decided to make these two cases into 2 separate portlets. As I begin to build the portlet for the case of multiple pairs I think I will use that one as the test case to see if it works better if I use the EDIT mode as the place to gather the user input.

Monday, April 6, 2009

New Direction

For now, the portlets with the Open Layers map and the problems with deploying portlets to the Web Space Server instance on our virtual server are going to be put on the back burner. Our new direction is to more fully develop the half-dozen Geospatial SOAP Service Client portlets we prototyped several months ago. These portlets provide a user interface to the Geospatial SOAP Web Services that are running on one of our team's virtual services.







Sample services include a geoid height calculator, a map-based distance and bearing calculator, country names service and coordinate parse service.

As I investigated the changes made to the services on the virtual server I noticed that each of the services now has a RESTFul interface. Looking at the example Query Form and RESTful calls that are provided it appears that it should be much easier to create portlet clients that make RESTful calls. That is something I've not done before.

Apparently, when I build the NetBeans project I leave off the part where the wizard is used with the WDSL to create the code that looks up the web service. I can just mimic the sample Query Form in the view.jsp of the portlet and directly make a call to the servlet that is providing the RESTful interface.

Let's go create a new NetBeans project and see what happens.

Wednesday, April 1, 2009

Didn't pass

I didn't pass the exam for the Sun Certified Programmer for Java 6 Platform SE6. The training class taught me a lot and gave me the motivation to continue my studies.. There's another class that I can take in September at no cost. I've already signed up for that class and will continue my studies.

It would be nice to have a job where the basics of Java programming would be put to use and that would help fill in the missing pieces in my knowledge of the basics. Instead, I get to go back to seeing what kind of GIS portlets I can dream up.

I was successful this week in getting the portlet to work that makes a WFS call for World Port Index data that's loaded on one of our team's virtual servers. The feature data is displayed on an Open Layers map. I resurrected another portlet that queried a local instance of a Geonames.org lookup service compiled from code written by a developer on the team. That query returns KML data and displays it on an OpenLayers map.

The KML portlet could only work on my local machine because the service was running locally. I thought I would make an attempt to get the same service running on the virtual server. Not a trivial task, given the lapse in time from when I had been working on this before. I needed some way to get the WAR file to the remote server. At first I thought I could just use the GlassFish admin console through a browser and upload the file. But then I realized the virtual server was not letting that port be accessed remotely. I recalled that when this issue came up months ago the process was to use VNC to get to the server, bring up a browser locally on the server and get to the Admin console from there.

When I tried VNC it wouldn't let me in. I figured out that since this office had recently changed their network setup it was likely that I was now getting out of here with a different IP address. Sure enough, that was the case. It took several email exchanges with the admin person on the other end but we finally managed to get VNC working again from here to there.

Next problem--When you upload a WAR file from the GlassFish Admin console the browse option only lets you look for something on the local machine. Now I was back to square one. How to get the WAR file from here to the remote server? The solution that I finally came up with was to use GEOINT Online. Who would ever have imagined that the GEOINT Online SharePoint site would be useful for anything technical? Turns out the Document Sharing feature in one of my communities allows me to upload a file. So I upload the file from here to the community, go to the browser on the remote server, log in to GEOINT Online, find the Shared Document on my community and download it. Pretty cool.

After all of that, the GeonamesDotOrgLookupService actually does work on the virtual server. Now I can retrieve the KML file across the network and not just from my local machine. Next step is to think about what wonderful things that will allow me to demonstrate in my GIS portlets.