Monday, May 25, 2015

JSON Jackson custom deserializer to return empty String instead of null

Needed a way to deserialize null values in a JSON as emptry strings (""). This is the shortest I could come with.
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;

public class NullHandlerDeserializer extends UntypedObjectDeserializer {

  private static final long serialVersionUID = 1L;

  @Override
  public Object deserialize(JsonParser jp, DeserializationContext ctxt)
    throws IOException {
    switch (jp.getCurrentToken()) {
     case VALUE_NULL:      
      return "";
     default: 
      return super.deserialize(jp, ctxt);
    }   
  }
 }

The class extends from an existing deserializer implementation to avoid having to code the handling of all JSON tokens. I needed to worry only about VALUE_NULL token.

And to configure the custom deserializer in the ObjectMapper:

ObjectMapper om = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Object.class, new NullHandlerDeserializer());
om.registerModule(module);

Wednesday, May 20, 2015

XSLT Learnings

Just listing some XSLT learnings from a recent project where I had to learn from scratch.

Basic shelling:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" encoding="utf-8" indent="no"/> 
<xsl:template match="/">
    <!-- XSL stuff -->
</xsl:template>
</xsl:stylesheet>

Converting a list of states from XML to HTML select input options:

Given an input like this:

<states>
    <AL>Alabama</AL>
    <AK>Alaska</AK>
    <AR>Arkansas</AR>
    <CA>California</CA>
    <CO>Colorado</CO>
</states>

Use XSL like this:

<select name="states">
    <xsl:for-each select="states/*">
        <option>
             <xsl:attribute name="value"><xsl:value-of select="name(.)"/></xsl:attribute>
        </option>
        <xsl:value-of select="string(.)"/>
    </xsl:for-each>
</select>

To get this:

<select>
        <option value="AL">Alabama</option>
        <option value="AK">Alaska</option>
        <option value="AR">Arkansas</option>
        <option value="CA">California</option>
        <option value="CO">Colorado</option>
</select>

Some few things to note:

  • "name(.)" gives you the element (tag) name.
  • "string(.)" gives you the element value (what is between opening and closong tags).


Checking element has children or content

<xsl:if test="some/element-tag/text() != ''">
...
</xsl:if>

Friday, December 12, 2014

Spring Web: Get current request and generate base URL

Just a simple way to generate application's base URL according to the environment context using current request:


protected static String getBaseEnvLinkURL() {

   String baseEnvLinkURL=null;
   HttpServletRequest currentRequest =
      ((ServletRequestAttributes)RequestContextHolder.
       currentRequestAttributes()).getRequest();
   // lazy about determining protocol but can be done too
   baseEnvLinkURL = "http://" + currentRequest.getLocalName();
   if(currentRequest.getLocalPort() != 80) {
      baseEnvLinkURL += ":" + currentRequest.getLocalPort();
   }
   if(!StringUtils.isEmpty(currentRequest.getContextPath())) {
      baseEnvLinkURL += currentRequest.getContextPath();
   }            
   return baseEnvLinkURL;
}

Tuesday, November 4, 2014

DOS: List files recursively

To list files recursively in Windows you don't need a complex script as I thought. For example to list all .html inside subfolders you can just run simple DOS command:

dir /s/b *.html > results.txt

Wednesday, October 15, 2014

Ant: adding additional JARs to classpath

I was working in a custom ATG module in which I required to extend a core ATG class. When I ran the build ant command I got compile errors because of "cannot find symbol", in other words, my dear reference class was not being recognized. It was missing! In my Eclipse project I got no errors because I had the right library included in the project's classpath.

I started looking on how to add additional JAR files to the classpath, but after digging a little bit more in the compile target referenced in the build.xml:

<target name="build" depends="echo-build-message,clean,compile,jar-classes,jar-configs,copy-to-install" />

I saw how could I add additional classpath entries using the reference id "classpath.additions". In the included common.xml file we had this:


 
<target name="compile">
     <mkdir dir="${java.output.dir}"/>
        <mkdir dir="${java.src.dir}"/>
        <copy todir="${java.output.dir}">
            <fileset dir="${java.src.dir}">
                <include name="**/*.properties" />
                <include name="**/*.xml" />
            </fileset>
        </copy>
     <if>
      <isreference refid="classpath.additions" />
      <then>
       <path id="fullClasspath">
        <path refid="classpath" />
        <path refid="classpath.additions" />
       </path>
      </then>
      <else>
       <path id="fullClasspath">
        <path refid="classpath" />
       </path>
       </else>
     </if>
        
     <echo message="java.src.dir: ${java.src.dir}, java.output.dir: ${java.output.dir}" />
     <javac srcdir="${java.src.dir}" destdir="${java.output.dir}" classpathref="fullClasspath" debug="on" includeAntRuntime="false" />
</target>

So I just added this in the build.xml:
<path id="classpath.additions"> 
  <fileset dir="${dynamo.home}/../REST/lib"><include name="**/*.jar" /></fileset>  
</path> 
This seems like an elegant generic way for configuring classpaths in a multi module environment like ATG.