HierarchicalMap Tutorial - Intermediate Level

HierarchicalMap is an interface. So anyone can implement it. This tutorial is based on BasicHierarchicalmap, a reference implementation of HierarchicalMap.

Following subjects are covered in this tutorial:

    Basic Level
  1. Getting Started
  2. Creating Structure
  3. Recovering the Data
  4. Interacting with Collections
  5. Restructuring the Map

  6. Intermediate Level
  7. Working with Stream
  8. Working with XML
  9. Handling Large XML
  10. Accessing Data Base
  11. Accessing Preferences

  12. Advanced Level
  13. Template Filling
  14. .NET Interoperability
  15. Runtime schema validation
  16. Writing Application

  17. Planned for Future
  18. IDE's plugin for coding-time schema validation and code completion

(Javascript must be enabled to allow syntax highlighting for source code snippets in this tutorial)

Advanced Level

12. .NET Interoperability

Working with HierarchicalMap in .Net is very simple, thanks to Jeroen Frijters with his IKVM project! Basically, all HierarchicalMap java classes were converted to .Net classes using ikvmc, a tool that compiles JVM's byte-code into CLR's byte-code. Some new classes were written in .Net to have more Microsoft fashioned behavior like ICollection, IDictionary, DictionaryEntry, Item Property and so on.

Following assemblies must be referenced to start using HierarchicalMap in .Net projects:

  • dhmp.dll: HierarchicalMap's original java classes converted to .Net using ikvmc
  • xercesImpl.dll: Apache's Xerces classes converted to .Net using ikvmc
  • dhmpms.dll: Wrapper classes to provide .Net interfaces for HierarchicalMap
  • dhmpdefaultcvt.dll: Converter classes for .Net objects to/from java objects
  • IKVM.GNU.Classpath.dll: GNU Classpath converted to .Net classes, plus some additional IKVM.NET specific code. This is part of IKVM distribution. GNU Classpath is Free Software Foundation's implementation of the Java class libraries
  • IKVM.Runtime.dll: The VM runtime and all supporting code. Only required during runtime
  • Note that there is no need of jar files during .Net execution. IKVM solution is not a wrapper for java classes. All the algorithms implemented in java is converted to CLR's byte-code and actually run as it was written in .Net native compiler.

    Although converted classes can be used inside .Net project, like

    org.dhmp.util.HierarchicalMap =
    	new org.dhmp.util.BasicHierarchicalMap()

    It is preferable to use .Net wrapper classes. Some of the differences between java implementation and .Net are listed below:

    Original (dhmp.dll) .Net (dhmpms.dll) Description
    org.dhmp.util Dhmp.Util package org.dhmp is wrapped using namespace Dhmp
    HierarchicalMap IHierarchicalMap IHierarchicalMap implements IDictionary
    entrySet() GetEnumerator() .Net Enumerator is slightly different from java Iterator
    MapInputStream MapStreamReader InputStream was converted to StreamReader
    MapOutputStream MapStreamWriter OutputStream was converted to StreamWriter
    BasicHierarchicalMap BasicHierarchicalMap Some classes name was unchanged

    The following snippet of code in C#, will create a data structure as in "2. Creating Structure" earlier presented in this tutorial. "using Dhmp.Util" must be declared in the source code:

    Note that method name begins with capital letter and Item Property, as in address2["City"] = "São Paulo";, is equivalent to address2.Put("City", "São Paulo");.

    Iteration with map is also different from java.

    IEnumerator is used instead of Iterator which is based on MoveNext() method and Current property

    In .Net, there is a simpler way to iterate with entrySet:

    Streaming HierarchicalMap from .Net to Java

    Now, the most interesting part. Streaming HierarchicalMap between Java application and .Net application. Prepare the following code at java side:

    Step1. Writing Server in Java

    First, write a code for filling a HierarchicalMap:

    Write a Main method to start a socket server:

    Then, write a thread for processing accepted socket. This part is quite large and written as a single code just for showing how to stream HierarchicalMap.

    The constructor of this class keeps the socket and fills a catalog, actually a HierarchicalMap, invoking the method "fillCatalog()" shown before. Then denormalize it using the algorithm presented at "5. Restructuring the Map".

    The "run()" method implements the following algorithm:

    1. First, creates a MapInputStream and MapOutputStream from socket. The compression must be deactivated due to the flushing problem with Deflater.
    2. Then, reads in a HierarchicalMap containing the request, which must contain the "model" and the "qty" (future version will provide a schema checker to validate against XSD)
    3. The model spec is fetched from catalog.
    4. The total amount is calculated multiplying the qty against price.
    5. Special discount is applied if the amount is over 5000.
    6. The total amount and spec are added to the response.
    7. Finally, the response is sent back to the caller.

    Step2. Writing Client in .Net

    Following snippet of code must be written in C#:

    Now, start the server side and then run the client. The result will be:

    Quoting 5 "Aspire 5672WLMi"
    TotalAmount: $6,299.96
    Spec:
    model: Aspire 5672WLMi
    brand: Acer
    processor: Intel Core Duo T2300
    price: 1399.99
    Special discount: 10%
    
    Quoting 3 "iBook G4"
    TotalAmount: $2,999.97
    Spec:
    model: iBook G4
    brand: Apple
    processor: PowerPC G4
    price: 999.99

    Converting .Net object to and from Java

    Some objects like string and byte are automatically converted inside IKVM but other objects like DateTime, Decimal and even an integer (represented using System.Int32) must be converted to corresponding java object before streaming it. The assembly "dhmpdefaultcvt.dll" contains default conversor for most of primitive data types.

    .Net class java class
    bool (System.Boolean) java.lang.Boolean
    byte (System.Byte) java.lang.Byte
    char (System.Char) java.lang.Character
    int (System.Int32) java.lang.Integer
    long (System.Int64) java.lang.Long
    float (System.Single) java.lang.Float
    double (System.Double) java.lang.Double
    System.Decimal java.math.BigDecimal
    System.DateTime java.util.Date

    Writing custom converter is simple. Just implement the Dhmp.Util.IConverter interface under Dhmp.Util.Converter namespace. See below an example:

    Note that class name must be the full Type name replacing "." by "_" with a literal "Cvt" as suffix. The resulting assembly name must finish with "cvt" like "myconvertercvt.dll" and must be placed within same directory where "dhmpdefaultcvt.dll" is located. The default converter is loaded as last converter inside internal cache. So any custom converter can override the converter class inside "dhmpdefaultcvt.dll". Though we do not encourage doing so nor writing complex object converter. Instead just exchange primitive types among different systems.

    Continue to Advanced Level - Runtime schema validation