Coverage Report - org.simpleframework.xml.core.CompositeUnion
 
Classes in this File Line Coverage Branch Coverage Complexity
CompositeUnion
56%
17/30
0%
0/2
1.333
 
 1  
 /*
 2  
  * CompositeUnion.java March 2011
 3  
  *
 4  
  * Copyright (C) 2011, Niall Gallagher <niallg@users.sf.net>
 5  
  *
 6  
  * Licensed under the Apache License, Version 2.0 (the "License");
 7  
  * you may not use this file except in compliance with the License.
 8  
  * You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
 15  
  * implied. See the License for the specific language governing 
 16  
  * permissions and limitations under the License.
 17  
  */
 18  
 
 19  
 package org.simpleframework.xml.core;
 20  
 
 21  
 import org.simpleframework.xml.strategy.Type;
 22  
 import org.simpleframework.xml.stream.InputNode;
 23  
 import org.simpleframework.xml.stream.OutputNode;
 24  
 
 25  
 /**
 26  
  * The <code>CompositeUnion</code> object is used to act as a mediator
 27  
  * for multiple converters associated with a particular union group.
 28  
  * This will basically determine which <code>Converter</code> should be
 29  
  * delegated to based on either the XML element name being read or the
 30  
  * type of the instance object being written. Selection of the converter
 31  
  * is done by consulting the <code>Group</code> of labels representing
 32  
  * the union declaration.
 33  
  * 
 34  
  * @author Niall Gallagher
 35  
  */
 36  
 class CompositeUnion implements Converter {
 37  
    
 38  
    /**
 39  
     * This contains the labels in the union group keyed by name.
 40  
     */
 41  
    private final LabelMap elements;
 42  
    
 43  
    /**
 44  
     * This is the path expression used to represent this union.
 45  
     */
 46  
    private final Expression path;
 47  
    
 48  
    /**
 49  
     * This is the current context used for the serialization.
 50  
     */
 51  
    private final Context context;
 52  
    
 53  
    /**
 54  
     * This contains the group of labels associated with the union.
 55  
     */
 56  
    private final Group group;
 57  
    
 58  
    /**
 59  
     * This is the type field or method annotated as a union.
 60  
     */
 61  
    private final Type type;
 62  
    
 63  
    /**
 64  
     * Constructor for the <code>CompositeUnion</code> object. This
 65  
     * is used to create a converter that delegates to other associated
 66  
     * converters within the union group depending on the XML element
 67  
     * name being read or the instance type that is being written.
 68  
     * 
 69  
     * @param context this is the context used for the serialization
 70  
     * @param group this is the union group used for delegation
 71  
     * @param path this is the path expression representing this union
 72  
     * @param type this is the annotated field or method to be used
 73  
     */
 74  109
    public CompositeUnion(Context context, Group group, Expression path, Type type) throws Exception {
 75  109
       this.elements = group.getElements();
 76  109
       this.context = context;
 77  109
       this.group = group;
 78  109
       this.type = type;
 79  109
       this.path = path;
 80  109
    }
 81  
 
 82  
    /**
 83  
     * The <code>read</code> method uses the name of the XML element to
 84  
     * select a converter to be used to read the instance. Selection of
 85  
     * the converter is done by looking up the associated label from
 86  
     * the union group using the element name. Once the converter has
 87  
     * been selected it is used to read the instance.
 88  
     * 
 89  
     * @param node this is the XML element used to read the instance
 90  
     * 
 91  
     * @return this is the instance that has been read by this
 92  
     */
 93  
    public Object read(InputNode node) throws Exception {
 94  86
       String name = node.getName();
 95  86
       String element = path.getElement(name);
 96  86
       Label label = elements.get(element);
 97  86
       Converter converter = label.getConverter(context);
 98  
       
 99  86
       return converter.read(node);
 100  
    }
 101  
 
 102  
    /**
 103  
     * The <code>read</code> method uses the name of the XML element to
 104  
     * select a converter to be used to read the instance. Selection of
 105  
     * the converter is done by looking up the associated label from
 106  
     * the union group using the element name. Once the converter has
 107  
     * been selected it is used to read the instance.
 108  
     * 
 109  
     * @param node this is the XML element used to read the instance
 110  
     * @param value this is the value that is to be repeated
 111  
     * 
 112  
     * @return this is the instance that has been read by this
 113  
     */
 114  
    public Object read(InputNode node, Object value) throws Exception {
 115  0
       String name = node.getName();
 116  0
       String element = path.getElement(name);
 117  0
       Label label = elements.get(element);
 118  0
       Converter converter = label.getConverter(context);
 119  
       
 120  0
       return converter.read(node, value);
 121  
    }
 122  
    
 123  
    /**
 124  
     * The <code>validate</code> method is used to validate the XML
 125  
     * element provided using an associated class schema. The schema
 126  
     * is selected using the name of the XML element to acquire
 127  
     * the associated converter. Once the converter has been acquired
 128  
     * it is delegated to and validated against it.
 129  
     * 
 130  
     * @param node this is the input XML element to be validated
 131  
     * 
 132  
     * @return this returns true if the node validates 
 133  
     */
 134  
    public boolean validate(InputNode node) throws Exception {
 135  22
       String name = node.getName();
 136  22
       String element = path.getElement(name);
 137  22
       Label label = elements.get(element);
 138  22
       Converter converter = label.getConverter(context);
 139  
       
 140  22
       return converter.validate(node);
 141  
    }
 142  
 
 143  
    /**
 144  
     * The <code>write</code> method uses the name of the XML element to
 145  
     * select a converter to be used to write the instance. Selection of
 146  
     * the converter is done by looking up the associated label from
 147  
     * the union group using the instance type. Once the converter has
 148  
     * been selected it is used to write the instance.
 149  
     * 
 150  
     * @param node this is the XML element used to write the instance
 151  
     * @param object this is the value that is to be written
 152  
     */
 153  
    public void write(OutputNode node, Object object) throws Exception {
 154  0
       Class real = object.getClass();
 155  0
       Label label = group.getLabel(real);
 156  
 
 157  0
       if(label == null) {               
 158  0
          throw new UnionException("Value of %s not declared in %s with annotation %s", real, type, group);
 159  
       }
 160  0
       write(node, object, label);     
 161  0
    }
 162  
    
 163  
    /**
 164  
     * The <code>write</code> method uses the name of the XML element to
 165  
     * select a converter to be used to write the instance. Selection of
 166  
     * the converter is done by looking up the associated label from
 167  
     * the union group using the instance type. Once the converter has
 168  
     * been selected it is used to write the instance.
 169  
     * 
 170  
     * @param node this is the XML element used to write the instance
 171  
     * @param object this is the value that is to be written    
 172  
     * @param label this is the label to used to acquire the converter
 173  
     */
 174  
    private void write(OutputNode node, Object object, Label label) throws Exception {
 175  0
       label.getConverter(context).write(node, object);
 176  0
    }
 177  
 
 178  
 }