Coverage Report - org.simpleframework.xml.load.CompositeKey
 
Classes in this File Line Coverage Branch Coverage Complexity
CompositeKey
92%
36/39
100%
11/11
4
 
 1  
 /*
 2  
  * CompositeKey.java July 2007
 3  
  *
 4  
  * Copyright (C) 2007, Niall Gallagher <niallg@users.sf.net>
 5  
  *
 6  
  * This library is free software; you can redistribute it and/or
 7  
  * modify it under the terms of the GNU Lesser General Public
 8  
  * License as published by the Free Software Foundation.
 9  
  *
 10  
  * This library is distributed in the hope that it will be useful,
 11  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13  
  * GNU Lesser General Public License for more details.
 14  
  *
 15  
  * You should have received a copy of the GNU Lesser General 
 16  
  * Public License along with this library; if not, write to the 
 17  
  * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
 18  
  * Boston, MA  02111-1307  USA
 19  
  */
 20  
 
 21  
 package org.simpleframework.xml.load;
 22  
 
 23  
 import org.simpleframework.xml.stream.InputNode;
 24  
 import org.simpleframework.xml.stream.OutputNode;
 25  
 import org.simpleframework.xml.stream.Position;
 26  
 
 27  
 /**
 28  
  * The <code>CompositeKey</code> object is used to convert an object
 29  
  * to an from an XML element. This accepts only composite objects and
 30  
  * will throw an exception if the <code>ElementMap</code> annotation
 31  
  * is configured to have an attribute key. If a key name is given for
 32  
  * the annotation then this will act as a parent element to the 
 33  
  * resulting XML element for the composite object. 
 34  
  * 
 35  
  * @author Niall Gallagher
 36  
  * 
 37  
  * @see org.simpleframework.xml.ElementMap
 38  
  */
 39  
 class CompositeKey implements Converter {
 40  
    
 41  
    /**
 42  
     * This is the traverser used to read and write the composite key.
 43  
     */
 44  
    private final Traverser root;
 45  
    
 46  
    /**
 47  
     * This is the entry object used to provide configuration details.
 48  
     */
 49  
    private final Entry entry;
 50  
    
 51  
    /**
 52  
     * This represents the type of object the key is written as.
 53  
     */
 54  
    private final Class type;
 55  
       
 56  
    /**
 57  
     * Constructor for the <code>CompositeKey</code> object. This will
 58  
     * create an object capable of reading an writing composite keys
 59  
     * from an XML element. This also allows a parent element to be
 60  
     * created to wrap the key object if desired.
 61  
     * 
 62  
     * @param root this is the root context for the serialization
 63  
     * @param entry this is the entry object used for configuration
 64  
     * @param type this is the type of object the key represents
 65  
     */
 66  32
    public CompositeKey(Source root, Entry entry, Class type) throws Exception {
 67  32
       this.root = new Traverser(root);
 68  32
       this.entry = entry;
 69  32
       this.type = type;
 70  32
    }
 71  
    
 72  
    /**
 73  
     * This method is used to read the key value from the node. The 
 74  
     * value read from the node is resolved using the template filter.
 75  
     * If the key value can not be found according to the annotation
 76  
     * attributes then null is assumed and returned.
 77  
     * 
 78  
     * @param node this is the node to read the key value from
 79  
     * 
 80  
     * @return this returns the value deserialized from the node
 81  
     */ 
 82  
    public Object read(InputNode node) throws Exception { 
 83  20
       Position line = node.getPosition();
 84  20
       String name = entry.getKey();
 85  
       
 86  20
       if(name == null) {
 87  16
          name = Factory.getName(type);
 88  
       }
 89  20
       if(entry.isAttribute()) {
 90  0
          throw new ElementException("Can not have %s as an attribute at %s", type, line);
 91  
       }
 92  20
       return read(node, name);
 93  
    }
 94  
    
 95  
    /**
 96  
     * This method is used to read the key value from the node. The 
 97  
     * value read from the node is resolved using the template filter.
 98  
     * If the key value can not be found according to the annotation
 99  
     * attributes then null is assumed and returned.
 100  
     * 
 101  
     * @param node this is the node to read the key value from
 102  
     * @param name this is the name of the key wrapper XML element
 103  
     * 
 104  
     * @return this returns the value deserialized from the node
 105  
     */ 
 106  
    private Object read(InputNode node, String name) throws Exception {      
 107  20
       if(name != null) {
 108  20
          node = node.getNext(name);
 109  
       }    
 110  20
       if(node == null) {
 111  2
          return null;
 112  
       }   
 113  18
       if(node.isEmpty()) {
 114  1
          return null;
 115  
       }
 116  17
       return root.read(node, type);
 117  
    }
 118  
    
 119  
    /**
 120  
     * This method is used to read the key value from the node. The 
 121  
     * value read from the node is resolved using the template filter.
 122  
     * If the key value can not be found according to the annotation
 123  
     * attributes then null is assumed and the node is valid.
 124  
     * 
 125  
     * @param node this is the node to read the key value from
 126  
     * 
 127  
     * @return this returns the value deserialized from the node
 128  
     */ 
 129  
    public boolean validate(InputNode node) throws Exception { 
 130  31
       Position line = node.getPosition();
 131  31
       String name = entry.getKey();
 132  
       
 133  31
       if(name == null) {
 134  27
          name = Factory.getName(type);
 135  
       }
 136  31
       if(entry.isAttribute()) {
 137  0
          throw new ElementException("Can not have %s as an attribute at %s", type, line);
 138  
       }
 139  31
       return validate(node, name);
 140  
    }
 141  
    
 142  
    /**
 143  
     * This method is used to read the key value from the node. The 
 144  
     * value read from the node is resolved using the template filter.
 145  
     * If the key value can not be found according to the annotation
 146  
     * attributes then null is assumed and the node is valid.
 147  
     * 
 148  
     * @param node this is the node to read the key value from
 149  
     * @param name this is the name of the key wrapper XML element
 150  
     * 
 151  
     * @return this returns the value deserialized from the node
 152  
     */ 
 153  
    private boolean validate(InputNode node, String name) throws Exception {      
 154  31
       InputNode next = node.getNext(name);
 155  
       
 156  31
       if(next == null) {
 157  1
          return true;
 158  
       }
 159  30
       if(next.isEmpty()) {
 160  6
          return true;
 161  
       }
 162  24
       return root.validate(next, type);
 163  
    }
 164  
    
 165  
    /**
 166  
     * This method is used to write the value to the specified node.
 167  
     * The value written to the node must be a composite object and if
 168  
     * the element map annotation is configured to have a key attribute
 169  
     * then this method will throw an exception.
 170  
     * 
 171  
     * @param node this is the node that the value is written to
 172  
     * @param item this is the item that is to be written
 173  
     */
 174  
    public void write(OutputNode node, Object item) throws Exception {
 175  27
       String name = entry.getKey();
 176  
       
 177  27
       if(entry.isAttribute()) {
 178  0
          throw new ElementException("Can not have %s as an attribute", type);
 179  
       }
 180  27
       if(name == null) {
 181  23
          name = Factory.getName(type);
 182  
       }      
 183  27
       root.write(node, item, type, name);      
 184  27
    }
 185  
 }