<?xml version="1.0" encoding="ISO-8859-1"?>
<document url="http://castor.org/howto/how-to-map-a-map.xml">
  <properties>
    <title>How to map a map of elements</title>
    <abstract/>
    <status>Final</status>
  </properties>
  <body>
    <title>How to map a map/hashtable of elements</title>
    <header/>

    <section title="Intended Audience">

        <p>Anyone who wants to map a Map/Hashtable of elements.</p>
        
        <p>This document helps people to get familiar with the basic concepts
           of mapping and shows an example.</p>

    </section>
    
    <section title="Prerequisites">

        <p>None.</p>

    </section>
    
    <section title="Simple Maps">
        
        <section title="Basic concept">
            
            <p>Assume you have two classes Items and Item, where an Items instance holds a Map/Hashtable
               of Item instances.</p>
               
            <code-panel>
    public class Items {
    
        <b>private Map itemlist;</b>
        
        public Map getItemlist() {
            return itemlist;
        }
        
        public void setItemlist(Map itemlist) {
            this.itemlist = itemlist;
        }
    }
    
    public class Item {
    
        private String id;
        private String description;
        private String supplier;
        private String contact;
        
        public String getContact() {
            return contact;
        }
        public void setContact(String contact) {
            this.contact = contact;
        }
        public String getSupplier() {
            return supplier;
        }
        public void setSupplier(String supplier) {
            this.supplier = supplier;
        }
        public String getDescription() {
            return description;
        }
        public void setDescription(String description) {
            this.description = description;
        }
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
    }</code-panel>
               
            <p>As shown above, the Items instance has a field 'itemList' to hold a Map
               of <tt>Item</tt> instances.</p>
               
        </section>

        <section title="Mapping file">
    
            <p>Here's the mapping file to instruct Castor XML about the relation of those two 
               classes, <tt>Items</tt> and <tt>Item</tt> respectively:</p>
    
            <code-panel>
    &lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
    &lt;mapping&gt;
      &lt;class name="nl.vodafone.castorbinding.demo.Items"&gt;
          &lt;map-to xml="Items"/&gt;
          &lt;field name="Itemlist" <b>collection="hashtable"&gt;</b>
              &lt;bind-xml name="MyItem"&gt;
                  <b>&lt;class name="org.exolab.castor.mapping.MapItem"&gt;</b>
                      &lt;field name="key" type="java.lang.String"&gt;
                          &lt;bind-xml name="id" node="attribute"/&gt;
                      &lt;/field&gt;
                      &lt;field name="value" type="nl.vodafone.castorbinding.demo.Item"&gt;
                          &lt;bind-xml name="Item"/&gt;
                      &lt;/field&gt;	  
                  <b>&lt;/class&gt;</b>
              &lt;/bind-xml&gt;		  
          &lt;/field&gt;  	  	  
      &lt;/class&gt;	
      &lt;class name="nl.vodafone.castorbinding.demo.Item"&gt;
          &lt;map-to xml="Item"/&gt;
          &lt;field name="Id" type="java.lang.String"&gt;
              &lt;bind-xml name="id" node="element"/&gt;
          &lt;/field&gt;
          &lt;field name="Description" type="java.lang.String"&gt;
              &lt;bind-xml name="description" node="element"/&gt;
          &lt;/field&gt;
          &lt;field name="Supplier" type="java.lang.String"&gt;
              &lt;bind-xml name="supplier" node="element"/&gt;
          &lt;/field&gt;
          &lt;field name="Contact" type="java.lang.String"&gt;
              &lt;bind-xml name="contact" node="element"/&gt;
          &lt;/field&gt;	  	  	  
      &lt;/class&gt;	
    &lt;/mapping&gt;</code-panel>
    
            <p>Please note the use of the <b>org.exolab.castor.mapping.MapItem</b> definition within the 
               &lt;bind-xml&gt; element in above mapping to map the elements contained in the 
               Map/Hashtable.</p>
        
        </section>

        <section title="XML output">
            
            <p>Using the Castor XML marshaller with the mapping file shown above, the XML 
               generated by Castor XML might look as follows:</p>
    
            <code-panel><![CDATA[
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Items>
       <MyItem id="1">
          <Item>
            <id>1</id>		
            <description>desc1</description>
            <supplier>supp1</supplier>
            <contact>cont1</contact>			
          </Item>
       </MyItem>
       <MyItem id="2">
          <Item>
             <id>2</id>		
             <description>desc2</description>
             <supplier>supp2</supplier>
             <contact>cont2</contact>			
          </Item>
       </MyItem>
       <MyItem id="3">
          <Item>
             <id>3</id>		
             <description>desc3</description>
             <supplier>supp3</supplier>
             <contact>cont3</contact>			
          </Item>
       </MyItem>
    </Items>]]></code-panel>
    
        </section>

    </section>

    
    <section title="Nested Maps">
        
        <p>It is equally possible to nest Collections/Arrays within Maps, incl. Maps within 
           Maps. The following Java class has a member 'map' of type <tt>java.util.Map</tt>.</p>
           
        <code-panel>
public class MapOfArrays {

    private Map map;

    public Map getMap() {
        return this.map;
    }

    public void setMap(Map map) {
        this.map = map;
    }

}</code-panel>   

        <p>The following code shows how this <tt>Map</tt> instance is filled with 
           <tt>String</tt> arrays before marshalling.</p>
           
        <code-panel>
this.map.put("key1", new String[] { "key1_value1", "key1_Value2" });
this.map.put("key2", new String[] { "key2_value1", "key2_Value2" });</code-panel>
        
        <p>Based upon the following mapping file, ...</p>
        
        <code-panel><![CDATA[
<class name="MapOfArrays">
    <field name="map" collection="map">
        <bind-xml name="map">
            <class name="org.exolab.castor.mapping.MapItem">
                <field name="key" type="java.lang.String">
                    <bind-xml name="string1" node="attribute" />
                </field>
                <field name="value" collection="array" type="java.lang.String">
                    <bind-xml name="nested" />
                </field>
            </class>
        </bind-xml>
    </field>
</class>]]></code-panel>

        <p>the following XML will be generated during marshalling.</p>
        
        <code-panel><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<map-of-arrays>
  <map string1="key1">
    <nested>key1_value1</nested>
    <nested>key1_Value2</nested>
  </map>
  <map string1="key2">
    <nested>key2_value1</nested>
    <nested>key2_Value2</nested>
  </map>
</map-of-arrays>]]></code-panel>
    
    </section>

    <section title="References">

        <ul>
            <li><a href="xml-mapping.html">XML mapping</a></li>
        </ul>
        
    </section>


  </body>
</document>
