Blog Objective

This is a blog that attempts to make life easier by noting down the author's accrued knowledge and experiences.
The author has dealt with several IT projects (in Java EE and .NET) and is a specialist in system development.

16 November 2006

Web Services Interoperability - .NET & Java

For those who are attempting to write web services in .NET to be consumed in Java.
The following are things to note or watch out for:

  1. Note the WS-I guideline found here
  2. Run the WS-I tests first to ensure that the web services comply with Basic Profile 1.0. Download the "Interoperability Testing Tools 1.1" from here
  3. Refrain from having the same name for operation and parameter type (this causes Axis 1.4 to fail as it attempts to generate classes for service and parameter type. Axis will try to generate the same class for both. For example: a complex type named search will "clash" with an operation with the same name. In the WSDL: <s:complexType name="search"> will "clash" with <s:operation name="search">)
  4. Refrain from incorporating non-ASCII characters directly into the content of a string property (which finally gets serialized into XML). Use character encoding instead. E.g., do not use “smart quotes” directly; use &#8220; and &#8221;
  5. If you expect the returned content to be transformed by XSLT (common in content publishing), consider returning the content as xs:string. E.g. use string getDocument(...) instead of Document getDocument(...).
Point (5) requires further explanation. The rationale is that most developers will make use of the framework proxy generator (wsdl2Java or wsdl.exe) in Java or even .NET to generate proxy classes. Most proxy generator will automatically convert the return type (if it isn't string) to schema-based data classes. As such getDocument(...) : Document will cause the Document class to be generated.
At runtime when the web service is called, an instance of the Document class will be returned to the caller of the operation. Behind the scenes, the XML gets deserialized into the Document object.
In order to have the original XML, the Document has to be serialized back into the XML. A total waste of computation!

14 November 2006

Software Technical Documentation (Overview)

Software technical documentation is an expected deliverable for software systems.

The expected audience will typically be the customer's IT or MIS department who may end up maintaining or even hosting the software system.

The technical documentation may be written in the following format:

  • verbose description using natural language

  • pictorial representation using modelling language

The level of detail may be:

  • business level (for end-user)
  • implementation level (for developer)

The following diagram depicts the above:


Examples of each are as follows (clock-wise order):

  • Descriptive - Business Level documentation: use cases, process flow description
  • Pictorial - Business Level documentation: screen flow, process flow diagram

  • Pictorial - Implementation Level documentation: interaction & class diagrams depicting implementation classes

  • Descriptive - Implementation Level documentation: code, data dictionary

Given that there are many ways to view the software system (logical, physical, etc), I recommend the 4+1 view by Kruchten.


The views are shown as follows:



  • Use case view - Describes the architecturally significant use cases (functionality) and a high level view of the requirements of the software system.

  • Logical view - Describes the design of the software system in terms of objects, modules and /or subsystems. Describes the most important classes, their organization in service packages and subsystems, and the organization of these subsystems into layers. Also describes the most important use-case realizations.

  • Implementation view - Describes the physical components used to assemble the system.

  • Process view - Describes the tasks (processes and threads) involved in the system's execution, their interactions and configurations. Also describes the allocation of objects and classes to tasks.

  • Deployment view - Describes the various physical nodes deployed for the software system. Describes the topology and mode of communication used. Also describes the allocation of tasks (from the Process View) to the physical nodes.

Not all systems require every view above. For example: single processor projects will not need the deployment view, single process projects will not need the process view. For small projects, the implementation view may be eliminated.

The above views are not exhaustive. Other views may be required. For example: data view, security view, etc.

In the next few installments, I'll explain the artifacts to look for in each view.

13 November 2006

XSL for XML with namespaces

This started off as a problem with writing a single XSL for RSS and ATOM feeds.

To be fair, producing separate XSL files for RSS and ATOM feeds should not be a huge problem.
Attempting to merge them is probably not trivial.

Thankfully, writing a XSL file for RSS is pretty trivial. It uses regular XSL know-how.
However, writing one for ATOM seemed very different!

The reason is that the ATOM XML comes with namespaces.
I've encountered these two namespaces in use in different feeds:
<feed version="0.3" xmlns="http://purl.org/atom/ns#">
and
<feed xmlns="http://www.w3.org/2005/Atom">

As such, a regular template match will not match the content of the document.
<xsl:template match="feed">

I'll need to write the XSL such that both gets matched.

In order to match the first feed, I'll need the template to be:
<xsl:template match="{http://purl.org/atom/ns#}feed">

To shortcut this, you'll need to have a prefix in your XSLT stylesheet that is associated with the namespace.
E.g.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:atom="http://purl.org/atom/ns#"
xmlns:atom1="http://www.w3.org/2005/Atom">


The template match will now be:
<xsl:template match="atom:feed">

As well as this:
<xsl:template match="atom1:feed">

And both together:
<xsl:template match="atom:feed atom1:feed">

This is definitely painful since I'll always be matching against two different namespaces for ATOM feeds!


A better solution is to have the template match ignore the namespace in the source XML.

The following will match the ATOM root element regardless of the namespace:
<xsl:template match="*[local-name()='feed']">

Therefore, the following will match the RSS and ATOM's base elements:
<xsl:template match="channel *[local-name()='feed']">

Problem has largely been solved!

The following is an experimental XSL (PS: I only handle single channels for RSS)



<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template match="text()" priority="-1">
</xsl:template>

<!-- matches both rss and atom -->
<xsl:template match="channel *[local-name()='feed']">
<html>
<body>
<h3>
<xsl:choose>
<xsl:when test="name(.) = 'channel'">
<a href="{link}" target="_blank"><xsl:value-of select="title"/></a>
</xsl:when>
<xsl:otherwise>
<a href="{*[local-name()='link']/@href}" target="_blank"><xsl:value-of
select="*[local-name()='title']"/></a>
</xsl:otherwise>
</xsl:choose>
</h3>
<table cellpadding="1" cellspacing="1" width="95%">
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>

<!-- matches both rss and atom -->
<xsl:template match="item *[local-name()='entry']">
<xsl:apply-templates/>
</xsl:template>

<!-- matches rss -->
<xsl:template match="item/title">
<tr>
<td bgcolor="#AAAAAA">
<xsl:number count="item"/>. <a
href="{../link}" target="_blank"><xsl:value-of select="."/></a>
</td>
</tr>
</xsl:template>

<!-- matches atom -->
<xsl:template match="*[local-name()='entry']/*[local-name()='title']">
<tr>
<td bgcolor="#AAAAAA">
<xsl:number count="*[local-name()='entry']"/>. <a
href="{../*[local-name() = 'link']/@href}" target="_blank"><xsl:value-of select="."/></a>
</td>
</tr>
</xsl:template>

<!-- matches rss -->
<xsl:template match="item/description">
<tr>
<td bgcolor="#EEEEEE">
<xsl:value-of select="." disable-output-escaping="no"/>
<br/><br/>
</td>
</tr>
</xsl:template>

<!-- matches atom -->
<xsl:template match="*[local-name()='entry']/*[local-name()='content']">
<tr>
<td bgcolor="#EEEEEE">
<xsl:value-of select="." disable-output-escaping="no"/>
<br/><br/>
</td>
</tr>
</xsl:template>

</xsl:stylesheet>

09 November 2006

Son of ....... SmartPart; Sharepoint & ASP.NET 2.0

Admittedly, I don't really know much about Sharepoint Services (WSS): My experience has been mainly in the area of ASP.NET.

All I really wanted to do was to write user controls for deployment in a Sharepoint site.

However, setting up the development environment was a real torture!

My setup is to be:

  • Windows 2003 Std. Ed.
  • SQL 2000
  • WSS 2.0 SP2
  • ASP.NET 2.0
  • SonOfSmartPart (to run user controls as webparts [http://www.smartpart.info])

For the most part, the installation of the operating system, database server and Sharepoint Services was a breeze. Hell began with ASP.NET 2.0...

Upgrading the Sharepoint website to use ASP.NET 2.0 causes all the webparts to show "Web Part Error"!

After ploughing through several posts, this was resolved by changing the trust level of the website.

Web.config:
<trust level="Full" originurl=""/>

(Note that this is probably not appropriate for a "live" site; but heck, I'm only setting up a development site...)

Whew! No more "Web Part Error"!

Next thing that happened was that all postback events generated errors (including adding new webparts, moving webparts, etc)

After ploughing through many more posts, this got resolved by disabling event validation for the website.

Web.config:
<pages EnableEventValidation="false"/>


Finally! Time to install SonOfSmartPart.....

Installation was a breeze (deja vu). The included examples worked well!

What a milestone! Major problems cleared! Hallelujah!

Started to develop my own user controls and deploy in WSS.

Oops! Another hitch! Postback with validation failed with javascript error!

Going back to the SonOfSmartPart website tells me that the WebResource.axd was "intercepted" by ISAPI filter of WSS.

To resolve this, I'll need to "add a new path" to be ignored by that filter.

  1. Login to SharePoint Central Administration site.
  2. Configure virtual server settings
  3. Define managed paths
  4. As follows:









To date, I've gone through hell with WSS but things are looking a lot brighter now :)