commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rahul Akolkar <rahul.akol...@gmail.com>
Subject Re: [digester] Trouble adding a list to a hash map
Date Sat, 02 Oct 2010 02:09:21 GMT
Please note that its important to post the smallest piece of code that
fully demonstrates the problem at hand -- vast majority of the code
below is quite unrelated and it takes time to read through each line
that you add to your post.

In any case, I did find atleast a couple of needles in the haystack.
Given the length of the email, I've added markers to my inline
comments, search for the string "RA:" in this email to get to my
comments below.

On Fri, Oct 1, 2010 at 4:37 PM, Philip A Grim II <pgrim@data-tactics.com> wrote:
> Apologies...wasn't thinking straight.
>
> Here's the code.
>
> import java.io.ByteArrayInputStream;
> import java.io.IOException;
> import java.util.ArrayList;
> import java.util.HashMap;
> import java.util.Map;
>
> import org.apache.commons.digester.Digester;
> import org.apache.commons.digester.xmlrules.DigesterLoader;
> import org.xml.sax.InputSource;
> import org.xml.sax.SAXException;
>
> public class DigestTester
> {
>  private static String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
>                              "<Envelope>" +
>                              "  <Person>" +
>                              "    <Locations>" +
>                              "      <Location>" +
>                              "
> <Id>3eca4cd1-a07a-4013-b4a3-1d6a6530f7e3</Id>" +
>                              "        <DateAsOf>201007132112</DateAsOf>"
+
>                              "
> <DateLastModified>20100803203509203</DateLastModified>" +
>                              "        <Name>Most Recent Location</Name>"
+
>                              "        <WKT>POINT (69.568583399873617
> 33.86775960347174 0)</WKT>" +
>                              "      </Location>" +
>                              "      <Location>" +
>                              "
> <Id>3e2462d1-a0c7-4013-4523-1345a3b8f7e3</Id>" +
>                              "        <DateAsOf>201007100814</DateAsOf>"
+
>                              "
> <DateLastModified>20100803203509203</DateLastModified>" +
>                              "        <Name>Previous Location</Name>"
+
>                              "        <WKT>POINT (66.53455434533617
> 32.863453455537174 0)</WKT>" +
>                              "      </Location>" +
>                              "    </Locations>" +
>                              "  </Person>" +
>                              "</Envelope>";
>
>
>  private static String test2 = "<?xml version=\"1.0\"?>" +
>                                   "<digester-rules>" +
<snip/>

RA: Meta point is that when using XML rules its best to use an XML
editor, reference the DTD and inspect / validate the rules before
trying to use them. When used as a Java string such as above, it can
hide problems as I'll point out below.



>                                   "<pattern value=\"Envelope/Person\">"
+
>                                   "<object-create-rule
> pattern=\"Locations\" classname=\"java.util.ArrayList\"/>" +
>                                   "<object-create-rule
> pattern=\"Locations/Location\" classname=\"java.util.HashMap\"/>" +
>                                   "<call-method-rule
> pattern=\"Locations/Location/Id\" targetoffset=\"0\" methodname=\"put\"
> paramcount=\"2\"" +
>                                   "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                   "<object-param-rule
> pattern=\"Locations/Location/Id\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"id\"/>" +
>                                   "<call-param-rule
> pattern=\"Locations/Location/Id\" paramnumber=\"1\"/>" +
>                                   "<call-method-rule
> pattern=\"Locations/Location/DateAsOf\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                   "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                   "<object-param-rule
> pattern=\"Locations/Location/DateAsOf\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"date_as_of\"/>" +
>                                   "<call-param-rule
> pattern=\"Locations/Location/DateAsOf\" paramnumber=\"1\"/>" +
>                                   "<call-method-rule
> pattern=\"Locations/Location/DateLastModified\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                   "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                   "<object-param-rule
> pattern=\"Locations/Location/DateLastModified\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"date_last_modified\"/>" +
>                                   "<call-param-rule
> pattern=\"Locations/Location/DateLastModified\" paramnumber=\"1\"/>" +
>                                   "<call-method-rule
> pattern=\"Locations/Location/Name\" targetoffset=\"0\" methodname=\"put\"
> paramcount=\"2\"" +
>                                   "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                   "<object-param-rule
> pattern=\"Locations/Location/Name\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"name\"/>" +
>                                   "<call-param-rule
> pattern=\"Locations/Location/Name\" paramnumber=\"1\"/>" +
>                                   "<call-method-rule
> pattern=\"Locations/Location/WKT\" targetoffset=\"0\" methodname=\"put\"
> paramcount=\"2\"" +
>                                   "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                   "<object-param-rule
> pattern=\"Locations/Location/WKT\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"wkt\"/>" +
>                                   "<call-param-rule
> pattern=\"Locations/Location/WKT\" paramnumber=\"1\"/>" +
>                                   "<set-next-rule
> pattern=\"Locations/Location\" methodname=\"add\"/>" +
>                                   "</pattern>" +
>                                   "</digester-rules>";
>
>
>  private static String test3 = "<?xml version=\"1.0\"?>" +
>                                    "<digester-rules>" +
>                                    "<pattern value=\"Envelope/Person\">"
+
>                                    "<object-create-rule
> pattern=\"Locations\" classname=\"java.util.ArrayList\"/>" +
>                                    "<object-create-rule
> pattern=\"Locations/Location\" classname=\"java.util.HashMap\"/>" +
>                                    "<call-method-rule
> pattern=\"Locations/Location/Id\" targetoffset=\"0\" methodname=\"put\"
> paramcount=\"2\"" +
>                                    "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                    "<object-param-rule
> pattern=\"Locations/Location/Id\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"id\"/>" +
>                                    "<call-param-rule
> pattern=\"Locations/Location/Id\" paramnumber=\"1\"/>" +
>                                    "<call-method-rule
> pattern=\"Locations/Location/DateAsOf\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                    "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                    "<object-param-rule
> pattern=\"Locations/Location/DateAsOf\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"date_as_of\"/>" +
>                                    "<call-param-rule
> pattern=\"Locations/Location/DateAsOf\" paramnumber=\"1\"/>" +
>                                    "<call-method-rule
> pattern=\"Locations/Location/DateLastModified\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                    "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                    "<object-param-rule
> pattern=\"Locations/Location/DateLastModified\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"date_last_modified\"/>" +
>                                    "<call-param-rule
> pattern=\"Locations/Location/DateLastModified\" paramnumber=\"1\"/>" +
>                                    "<call-method-rule
> pattern=\"Locations/Location/Name\" targetoffset=\"0\" methodname=\"put\"
> paramcount=\"2\"" +
>                                    "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                    "<call-method-rule
> pattern=\"Locations/Location/Name\" targetoffset=\"0\" methodname=\"put\"
> paramcount=\"2\"" +
>                                    "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                    "<object-param-rule
> pattern=\"Locations/Location/Name\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"name\"/>" +
>                                    "<call-param-rule
> pattern=\"Locations/Location/Name\" paramnumber=\"1\"/>" +
>                                    "<call-method-rule
> pattern=\"Locations/Location/WKT\" targetoffset=\"0\" methodname=\"put\"
> paramcount=\"2\"" +
>                                    "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                    "<object-param-rule
> pattern=\"Locations/Location/WKT\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"wkt\"/>" +
>                                    "<call-param-rule
> pattern=\"Locations/Location/WKT\" paramnumber=\"1\"/>" +
>                                    "<set-next-rule
> pattern=\"Locations/Location\" methodname=\"add\"/>" +
>                                    "<call-method-rule pattern=\"Locations\"
> targetoffset=\"1\" methodname=\"put\" paramcount=\"2\"" +
>                                    "
> paramtypes=\"java.lang.String,java.util.ArrayList\"/>" +
>                                    "<object-param-rule
> pattern=\"Locations\" paramnumber=\"0\" type=\"java.lang.String\"
> value=\"locations\"/>" +
>                                    "<object-param-rule
> pattern=\"Locations\" paramnumber=\"1\" type=\"java.util.ArrayList\"
> fromstack=\"true\"/>" +
<snap/>

RA: Above line should contain:

<call-param-rule pattern=\"Locations\" paramnumber=\"1\"
type=\"java.util.ArrayList\" from-stack=\"true\"/>

i.e. use <call-param-rule> and use correct attribute name "from-stack".



>                                    "</pattern>" +
>                                    "</digester-rules>";
>
>  private static String test4 = "<?xml version=\"1.0\"?>" +
>                                "<digester-rules>" +
>                                "<pattern value=\"Envelope\">" +
>                                "<object-create-rule pattern=\"Person\"
> classname=\"java.util.HashMap\"/>" +
>                                "<object-create-rule
> pattern=\"Person/Locations\" classname=\"java.util.ArrayList\"/>" +
>                                "<object-create-rule
> pattern=\"Person/Locations/Location\" classname=\"java.util.HashMap\"/>" +
>                                "<call-method-rule
> pattern=\"Person/Locations/Location/Id\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                "<object-param-rule
> pattern=\"Person/Locations/Location/Id\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"id\"/>" +
>                                "<call-param-rule
> pattern=\"Person/Locations/Location/Id\" paramnumber=\"1\"/>" +
>                                "<call-method-rule
> pattern=\"Person/Locations/Location/DateAsOf\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                "<object-param-rule
> pattern=\"Person/Locations/Location/DateAsOf\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"date_as_of\"/>" +
>                                "<call-param-rule
> pattern=\"Person/Locations/Location/DateAsOf\" paramnumber=\"1\"/>" +
>                                "<call-method-rule
> pattern=\"Person/Locations/Location/DateLastModified\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                "<object-param-rule
> pattern=\"Person/Locations/Location/DateLastModified\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"date_last_modified\"/>" +
>                                "<call-param-rule
> pattern=\"Person/Locations/Location/DateLastModified\" paramnumber=\"1\"/>"
> +
>                                "<call-method-rule
> pattern=\"Person/Locations/Location/Name\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                "<call-method-rule
> pattern=\"Person/Locations/Location/Name\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                "<object-param-rule
> pattern=\"Person/Locations/Location/Name\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"name\"/>" +
>                                "<call-param-rule
> pattern=\"Person/Locations/Location/Name\" paramnumber=\"1\"/>" +
>                                "<call-method-rule
> pattern=\"Person/Locations/Location/WKT\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                "<object-param-rule
> pattern=\"Person/Locations/Location/WKT\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"wkt\"/>" +
>                                "<call-param-rule
> pattern=\"Person/Locations/Location/WKT\" paramnumber=\"1\"/>" +
>                                "<set-next-rule
> pattern=\"Person/Locations/Location\" methodname=\"add\"/>" +
>                                "<call-method-rule
> pattern=\"Person/Locations\" targetoffset=\"1\" methodname=\"put\"
> paramcount=\"2\"" +
>                                "
> paramtypes=\"java.lang.String,java.util.ArrayList\"/>" +
>                                "<object-param-rule
> pattern=\"Person/Locations\" paramnumber=\"0\" type=\"java.lang.String\"
> value=\"locations\"/>" +
>                                "<object-param-rule
> pattern=\"Person/Locations\" paramnumber=\"1\" type=\"java.util.ArrayList\"
> fromstack=\"true\"/>" +
<snip/>

RA: Above line should contain:

<call-param-rule pattern=\"Person/Locations\" paramnumber=\"1\"
type=\"java.util.ArrayList\" from-stack=\"true\"/>

i.e. use <call-param-rule> and use correct attribute name "from-stack".

-Rahul



>                                "</pattern>" +
>                                "</digester-rules>";
>
>
>  @SuppressWarnings("unchecked")
>  public static void main(String[] args)
>  {
>    // First version, just make a list that contains a hash map.
>    // This works, and values show up.
>    System.out.println("----------------------- First Test
> ---------------------------");
>    ByteArrayInputStream stream = new ByteArrayInputStream(xml.getBytes());
>    Digester digester = new Digester();
>    digester.setValidating(false);
>
>    digester.addObjectCreate("Envelope/Person/Locations",
> "java.util.ArrayList");
>    digester.addObjectCreate("Envelope/Person/Locations/Location",
> "java.util.HashMap");
>
>    digester.addCallMethod("Envelope/Person/Locations/Location/Id", "put",
> 2, new String[] { "java.lang.String", "java.lang.Object" });
>    digester.addObjectParam("Envelope/Person/Locations/Location/Id", 0,
> "id");
>    digester.addCallParam("Envelope/Person/Locations/Location/Id", 1);
>
>    digester.addCallMethod("Envelope/Person/Locations/Location/DateAsOf",
> "put", 2, new String[] { "java.lang.String", "java.lang.Object" });
>    digester.addObjectParam("Envelope/Person/Locations/Location/DateAsOf",
> 0, "date_as_of");
>    digester.addCallParam("Envelope/Person/Locations/Location/DateAsOf", 1);
>
>
> digester.addCallMethod("Envelope/Person/Locations/Location/DateLastModified"
> , "put", 2, new String[] { "java.lang.String", "java.lang.Object" });
>
> digester.addObjectParam("Envelope/Person/Locations/Location/DateLastModified
> ", 0, "date_last_modified");
>
> digester.addCallParam("Envelope/Person/Locations/Location/DateLastModified",
> 1);
>
>    digester.addCallMethod("Envelope/Person/Locations/Location/Name", "put",
> 2, new String[] { "java.lang.String", "java.lang.Object" });
>    digester.addObjectParam("Envelope/Person/Locations/Location/Name", 0,
> "name");
>    digester.addCallParam("Envelope/Person/Locations/Location/Name", 1);
>
>    digester.addCallMethod("Envelope/Person/Locations/Location/WKT", "put",
> 2, new String[] { "java.lang.String", "java.lang.Object" });
>    digester.addObjectParam("Envelope/Person/Locations/Location/WKT", 0,
> "wkt");
>    digester.addCallParam("Envelope/Person/Locations/Location/WKT", 1);
>
>    digester.addSetNext("Envelope/Person/Locations/Location", "add");
>
>    try
>    {
>      ArrayList results = (ArrayList)digester.parse(stream);
>
>      System.out.println("Results:");
>
>      for (Object item : results)
>      {
>        if (item instanceof Map)
>        {
>          System.out.println("    Item:");
>          for(Object tag : ((Map)item).keySet())
>          {
>            System.out.println("      " + tag + ": " +
> ((Map)item).get(tag));
>          }
>        }
>        else
>        {
>          System.err.println("Item was not a map: " + item);
>        }
>      }
>
>    }
>    catch (IOException e)
>    {
>      e.printStackTrace();
>    }
>    catch (SAXException e)
>    {
>      e.printStackTrace();
>    }
>
>    // Second version, just make a list that contains a hash map, using
> xmlrules.
>    // This works, and values show up.
>    System.out.println("----------------------- Second Test
> ---------------------------");
>    stream = new ByteArrayInputStream(xml.getBytes());
>    digester = DigesterLoader.createDigester(new InputSource(new
> ByteArrayInputStream(test2.getBytes())));
>    digester.setValidating(false);
>    try
>    {
>      ArrayList results = (ArrayList)digester.parse(stream);
>
>      System.out.println("Results:");
>
>      for (Object item : results)
>      {
>        if (item instanceof Map)
>        {
>          System.out.println("    Item:");
>          for(Object tag : ((Map)item).keySet())
>          {
>            System.out.println("      " + tag + ": " +
> ((Map)item).get(tag));
>          }
>        }
>        else
>        {
>          System.err.println("Item was not a map: " + item);
>        }
>      }
>
>    }
>    catch (IOException e)
>    {
>      e.printStackTrace();
>    }
>    catch (SAXException e)
>    {
>      e.printStackTrace();
>    }
>
>
>    // Third version, try to add the list as a value in a hash map.
>    // Doesn't work, array list is empty
>    System.out.println("----------------------- Third Test
> ---------------------------");
>    stream = new ByteArrayInputStream(xml.getBytes());
>    digester = DigesterLoader.createDigester(new InputSource(new
> ByteArrayInputStream(test3.getBytes())));
>    digester.setValidating(false);
>
>    HashMap testMap = new HashMap();
>    digester.push(testMap);
>
>    try
>    {
>     digester.parse(stream);
>
>      System.out.println("Results:");
>
>      for (Object key : testMap.keySet())
>      {
>        System.out.println("Map key: " + key);
>        ArrayList results = (ArrayList)testMap.get(key);
>
>        for (Object item : results)
>        {
>          if (item instanceof Map)
>          {
>            System.out.println("    Item:");
>            for(Object tag : ((Map)item).keySet())
>            {
>              System.out.println("      " + tag + ": " +
> ((Map)item).get(tag));
>            }
>          }
>          else
>          {
>            System.err.println("Item was not a map: " + item);
>          }
>        }
>      }
>    }
>    catch (IOException e)
>    {
>      e.printStackTrace();
>    }
>    catch (SAXException e)
>    {
>      e.printStackTrace();
>    }
>
>    // Fourth version, try to add the list as a value in a hash map. Create
> the hash map in the rule
>    // Still doesn't work, array list is empty.
>    System.out.println("----------------------- Fourth Test
> ---------------------------");
>    stream = new ByteArrayInputStream(xml.getBytes());
>    digester = DigesterLoader.createDigester(new InputSource(new
> ByteArrayInputStream(test4.getBytes())));
>    digester.setValidating(false);
>
>    try
>    {
>      testMap = (HashMap)digester.parse(stream);
>
>      System.out.println("Results:");
>
>      for (Object key : testMap.keySet())
>      {
>        System.out.println("Map key: " + key);
>        ArrayList results = (ArrayList)testMap.get(key);
>
>        for (Object item : results)
>        {
>          if (item instanceof Map)
>          {
>            System.out.println("    Item:");
>            for(Object tag : ((Map)item).keySet())
>            {
>              System.out.println("      " + tag + ": " +
> ((Map)item).get(tag));
>            }
>          }
>          else
>          {
>            System.err.println("Item was not a map: " + item);
>          }
>        }
>      }
>    }
>    catch (IOException e)
>    {
>      e.printStackTrace();
>    }
>    catch (SAXException e)
>    {
>      e.printStackTrace();
>    }
>  }
> }
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org


Mime
View raw message