Tuesday, April 23, 2013

Extend interface implementation (proxy/delegation pattern)


Extend interface implementation (proxy/delegation pattern)
Yes this is not a type mistake, I want to extend the implementation of an interface. How many times do we have access to an interface but not the implementation? In the case that we have the implementation we can usually inherit the class and override the public/protected functionality. But what do you do when there is a factory builder that returns an instantiated object with an interface and you do not know or what to know the implementation (since it can always change), and you still want to override some of the functionality.

Let’s take a simple example. To write an xml file you can use the following code:

Object request;
JAXBContext jc = JAXBContext.newInstance(classesToBeBound);
Marshaller m = jc.createMarshaller();
XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
ByteArrayOutputStream ba = new ByteArrayOutputStream();
XMLStreamWriter writer = xmlOutputFactory.createXMLStreamWriter(ba);  
m.marshal(request, writer);
 
This code takes a buffer array and marshals it to an xml document using the XMLStreamWriter.
The XMLStreamWriter is an interface:
public abstract interface javax.xml.stream.XMLStreamWriter

with function for writing xml documents like: writeStartElement, writeEndElement.
As we know there are characters in xml that cannot be written to the string document since they are used by the xml format. The characters are: [&<>'\”].  To overcome this when writing the xml for example, the > will be changed to &gt;. There are some systems that do not know how to read this string. For these systems there is the CDATA format (see http://xml.silmaril.ie/specials.html). A CDATA section is a string that starts with <![CDATA[ and ends with ]]>. Within this string you can write any text you want, for example:
<![CDATA[<sender>John Smith</sender>]]>

This is a legal text that will not be read as a xml mockup, but will be read as: &lt;sender&gt;John Smith&lt;/sender&gt;

Back to our case. Let’s say that we want to convert some of the text to CDATA but the XMLStreamWriter does not support this. We would like to override the function of writeCharacters. So how do we override an interface implementation? There are two way that are more or less the same, but one is more explicit and the other generic.
We will start with the specific solution. An interface is a contract that specifies an api without the implementation. The factory builder returns the interface with a specific implementation behind it. What we do is create a new class that holds a reference to the current instance and implements the interface. The all methods are delegated to the internal reference, and those methods that we want to override we can. For example (not a full class implementation):

public class DelegatingXMLStreamWriter implements XMLStreamWriter {
    XMLStreamWriter delegate;
   
    public DelegatingXMLStreamWriter(XMLStreamWriter del) {
        delegate = del;
    }
   
    public void close() throws XMLStreamException {
        delegate.close();
    }

    public void flush() throws XMLStreamException {
        delegate.flush();
    }

    public void writeCharacters(char[] arg0, int arg1, int arg2) throws XMLStreamException {
        delegate.writeCharacters(arg0, arg1, arg2);
    }
}

As you can see all that the class does is to delegate all functionally to the instance that was created by the factory, and specific implementations can be override (This class is a helper class that can be found at http://java.net/projects/stax-utils/pages/Home).

The second way to do this is not to explicitly write a class that delegates all the methods (they can be tens of methods), but to create a proxy object and the catch only the one method that needs to be overridden:
XMLStreamWriter proxyXMLStreamWriter = (XMLStreamWriter)Proxy.newProxyInstance(XMLStreamWriter.class.getClassLoader(),new Class[] { XMLStreamWriter.class },new InvocationHandler() {
      
@Override
public Object invoke(Object arg0, Method arg1, Object[] arg2) {
if(method.getName().equals("writeCharacters") {
              // override specific method with functionality

}
});
}
Summary:
As you can see it is fairly easy to add functionality even to a class that you do not have the source code for. This is done using the proxy/delegation pattern.



Monday, April 8, 2013

Soap Model Duplication / Mitigation


Soap Model Duplication / Mitigation
When creating a soap interface (or any other external api) after you already have a very big internal model base can be very difficult.
The optimal architectural design is to have two model bases one internal and one external. The reason for this is to decouple internal code from external. Usually the external interface does not change much and refactoring is not an option (since the clients are already using this interface). On the other hand internal structures are always being refactored to meet new requirements. If the subset functionality needed to be exported is well defined, then the decision is usually strait forward, since the external api by requirement will be different from the internal.
The problem is that if your model is very big and the requirement are to export all internal functionally then we have the problem of duplicating the full model (which can be tens if not hundreds of classes).
In any case when having a dto we need a simple way to covert from the external api to the internal and vice versa.
When looking from above there are two major options (in the case of xml based protocols). In the case of soap the protocol is based on xml documents. So any request is converted from xml to an object and then the result is converted from the object back to xml.
So if we need to transform the request from the external api to the internal api, we can either do it on the object level or on the xml level.
The object level is the more known way to do conversions since it is not protocol specific, and can be done on the external level in code. The disadvantage is that the transformations are not always easy and need an external framework to help (see http://dozer.sourceforge.net/). Another disadvantage is that the code becomes very “dirty” with a lot of lines just for the transformation.
Another option that I want to expand on is the option for transformation on the xml level. Since the protocol of soap is based on xml and xsd schemes, there is an option of transforming the incoming and outgoing xml using xslt. Xslt is widely known and has a lot of transformation capabilities (http://www.w3schools.com/XSL/).
In this solution you have only one model base and do the transformations on the xml level and not on the object level.
Using a framework like CXF (http://cxf.apache.org/) for soap, it is very easy to add xslt files for your soap requests.
The way CXF works, is that for every incoming and outgoing request there is a list of interceptors that are called. The message is sent to each interceptor (order can be set) in the chain before and after. So the soap request will pass through the interceptors, and one of them will do the transformations.
CXF supports two types of transformations: StaxTransformFeature, XSLTFeature.
The difference between the two, I copied from the site of CXF (http://cxf.apache.org/docs/xslt-feature.html):

When should I use Transformation Feature and when XSLT Feature?

If only trivial transformations must be done, it is recommended to use lightweight and fast Transformation Feature. It covers the most use cases as:

·          dropping the namespace of the outbound messages;

·          qualifying the incoming message;

·          changing namespaces;

·          appending or dropping elements;

·          converting attributes to elements.

Transformation Feature is completely stream oriented and work fast especially for large messages.

If you should apply non-trivial transformation, not supported by Transformation Feature - it is use case for XSLT Feature. Here you can write any custom XSL Transformation and apply it to inbound and/or outbound messages.
As far as Xalan XSLT engine is actually not completely stream oriented, XSLT Feature breaks streaming. However it uses high-performance DTM (Document Table Model) instead complete DOM model.
Performance can be improved in the future by using further versions of Xalan or other XSLT engines (like Saxon or STX oriented Joost).


I will describe how to use the XSLTFeature since we need a full xsl file to transform the requests.

In the application context of the CXF where you define your endpoints you need to define the following:
<bean id="xsltFeatureSoapTestService" class="org.apache.cxf.feature.transform.XSLTFeature">
       <property name="inXSLTPath" value="soapTransformers/requestTransformation.xsl" />
       <property name="outXSLTPath" value="soapTransformers/responseTransformation.xsl" />
</bean>
<jaxws:endpoint implementor="#soapTestService" address="/ws/SoapTestService">
       <jaxws:features>
              <ref bean="xsltFeatureSoapTestService" />
       </jaxws:features>
</jaxws:endpoint>

The first bean is what the interceptor will use. You need to create one per endpoint, since this bean will hold the in and out xls. Then on your endpoint you add the jaxws:features with a reference to your bean.
This will cause the CXF to run the transformers on the incoming message and the outgoing message.
To start testing this you can use a simple xsl that actually just copies the original xsl:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       xmlns:sapiens="http://soap.interfaces.internal.foundation.alis.sapiens.com/">
       <!-- Identity Template # Copy everything -->
       <xsl:template match="@*|node()">
              <xsl:copy>
                     <xsl:apply-templates select="@*|node()" />
              </xsl:copy>
       </xsl:template>
</xsl:stylesheet>

Then to easily remove a specific property from the xml you can write:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       xmlns:sapiens="http://soap.interfaces.internal.foundation.alis.sapiens.com/">
       <!-- Identity Template # Copy everything -->
       <xsl:template match="@*|node()">
              <xsl:copy>
                     <xsl:apply-templates select="@*|node()" />
              </xsl:copy>
       </xsl:template>
      
       <!-- remove text -->
       <xsl:template match="msgText">
       </xsl:template>

</xsl:stylesheet>

This will remove the xml element of msgText from the xml.

As you can see it is very easy to remove attributes or nodes from the soap xml model, or to do any transformation that you need on the xml level, and not on the object level.