Saturday, July 18, 2015

How To Develop And Test Custom Xpath Function For Xalan.

Introduction
  XSLT 2.0 offers a rich set of transformation tools for xml transformation. But still in some cases we may encounter very specific business data transformations which can not be handled by generic transformation function. To handle those cases we may have to use the extension capability of the underling processing engine.

Problem
 Lets imagine a legacy backend system responding with following xml payload.
 It follows the upper camel case format to construct the xml payload.

 And the mobile client which consumes the system payload expects lower camel case format to process the payload.


Solution
  We are going to implement extension function using Xalan XSLT processor. Let's divide the solution in to few steps.

   1.Create the Java implementation of the logic.

       Google guvava api has a rich set of string manipulation tools. We are going to reuse one of those for converting UpperCamelCase string to lowerCamelCase string.

   2. Plug the custom function to XSLT.
       
       We have define new namespace with following pattern.
       xmlns: prefix ="xalan:// packagename.classname "

       In our example we have 
          xmlns:custom = "xalan://custom.xpath.CustomXpath"

       And we can call the function as follows
         {custom:toLowerCamelCase(local-name())}


    3. Test the custom Xpath function.

       As the final step we are creating a Junit test for test the custom Xpath function. One thing to note here is we are not using the default xslt processor instead we set the transformerfactory as "org.apache.xalan.processor.TransformerFactoryImpl" so that transformation will be done using Xalan apis.


Conclusion
Developing a custom Xpath function and plugin it to your code is not that hard but always look for existing Xpath function or existing extension function set like EXSLT. After all its good old Java , open for you to play with.  
You can find the eclipse project with the sample code at  https://github.com/KalpaD/xalan_custom_xpath_sample


Saturday, February 28, 2015

Mocking java.net.URL


Introduction.

Mocking is a crucial part of the unit testing. It gives power to the developer to push the limits of the logic without pleasing the dependencies of the logic. Mocking has it's own forms for different testing paradigms and also limitations. Recently I have used mockito mock library to develop some unit test cases. Even though Mokito is grate tool for mocking it has few limitations ,by design Mokito can not mock/spy final classes, anonymous classes or primitive types. Here I will explain how I have found a workaround for final class problem.

Problem
Have a look of "public String getContent(URL url) throws IOException" method which takes java.net.URL as an argument and read the input stream from the http connection. Here I need to mock java.net.URL is a final class we often see in our codes , because of above limitation we discussed above I can not get HttpURLConnection form mocked URL instance.


     public class WebContentManager {

    private final String USER_AGENT = "Mozilla/5.0";
   
    public String getContent(URL url) throws IOException {
   
     HttpURLConnection httpConnection = null;
     BufferedReader in = null;
     StringBuffer response = new StringBuffer();
   
     try {
      httpConnection = (HttpURLConnection) url.openConnection();
      httpConnection.setRequestMethod("GET");
      httpConnection.setRequestProperty("User-Agent", USER_AGENT);
   
      // int responseCode = httpConnection.getResponseCode();
   
      in = new BufferedReader(new InputStreamReader(
        httpConnection.getInputStream()));
      String inputLine;
   
      while ((inputLine = in.readLine()) != null) {
       response.append(inputLine);
      }
     } finally {
   
      try {
       in.close();
      } catch (IOException ex) {
   
      }
      if (httpConnection != null) {
       httpConnection.disconnect();
      }
     }
   
     return response.toString();
    }
    
   }
   
Solution
So I started to dig in to other ways to create mock URL instance with injected mock HttpURLConnection. java.net.URL class has constructor which takes java.net.URLStreamHandler as an argument. java.net.URLStreamHandler is an interface with the method  protected URLConnection openConnection(URL u ) throws IOException.So if I can inject the mocked HttpURLConnection in to URLStreamHandler openConnection() method.
Here goes the unit test implementation.
   public class WebContentManagerTest {

    String response;
    
    @Before
    public void setUp(){
     response = "";
    }
    
    @Test
    public void testGetContent() throws IOException {
     
          final HttpURLConnection mockCon = mock(HttpURLConnection. class);
          InputStream inputStrm = IOUtils.toInputStream( response);       
          when(mockCon.getLastModified()).thenReturn((Long)10L, (Long)11L);
          when(mockCon.getInputStream()).thenReturn( inputStrm);
          
           //mocking httpconnection by URLStreamHandler since we can not mock URL class.
          URLStreamHandler stubURLStreamHandler = new URLStreamHandler() {
              @Override
               protected URLConnection openConnection(URL u ) throws IOException {
                  return mockCon ;
               }           
          };
          
          WebContentManager wcm = new WebContentManager();
       URL url = new URL(null,"https://www.google.com",stubURLStreamHandler);
          String actual = wcm.getContent(url);
          assertEquals(response, actual);
   
    }

    }
   

Conclusion
When you find final class that can not mock , try to find alternative ways to create the object and inject what you wanted in to that.