Coverage Report - org.simpleframework.xml.core.ModelSection
 
Classes in this File Line Coverage Branch Coverage Complexity
ModelSection
91%
33/36
77%
14/18
1.846
 
 1  
 /*
 2  
  * ModelSection.java November 2010
 3  
  *
 4  
  * Copyright (C) 2010, 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 java.util.ArrayList;
 22  
 import java.util.Iterator;
 23  
 import java.util.List;
 24  
 
 25  
 /**
 26  
  * The <code>ModelSection</code> represents a section that is backed
 27  
  * by a <code>Model</code> instance. This is used to expose the XML
 28  
  * structure of a schema class. In addition to wrapping the model
 29  
  * this will also apply a <code>Style</code> to the names of the
 30  
  * attributes and elements of the class schema. 
 31  
  * 
 32  
  * @author Niall Gallagher
 33  
  */
 34  
 class ModelSection implements Section { 
 35  
 
 36  
    /**
 37  
     * Represents a mapping between styled names and attributes.
 38  
     */
 39  
    private LabelMap attributes;
 40  
    
 41  
    /**
 42  
     * Represents a mapping between styled names and elements.
 43  
     */
 44  
    private LabelMap elements;
 45  
    
 46  
    /**
 47  
     * Represents a mapping between styled names and models.
 48  
     */
 49  
    private ModelMap models;
 50  
    
 51  
    /**
 52  
     * This is the model that contains the elements and attributes.
 53  
     */
 54  
    private Model model;
 55  
    
 56  
    /**
 57  
     * Constructor for the <code>ModelSection</code> object. This is
 58  
     * used to wrap a <code>Model</code> in such a way that it can
 59  
     * not be modified. This allows it to be used concurrently.
 60  
     * 
 61  
     * @param model this is the model this section will wrap
 62  
     */
 63  932964
    public ModelSection(Model model) {
 64  932964
       this.model = model;
 65  932964
    }
 66  
    
 67  
    /**
 68  
     * This is used to return the name of the section. The name is 
 69  
     * must be a valid XML element name. It is used when a style
 70  
     * is applied to a path as the section name must be styled.
 71  
     * 
 72  
     * @return this returns the name of this section instance
 73  
     */
 74  
    public String getName() {
 75  0
       return model.getName();
 76  
    }
 77  
    
 78  
    /**
 79  
     * This is used to acquire the path prefix for the section. The
 80  
     * path prefix is used when the section is transformed in to an
 81  
     * XML structure. This ensures that the XML element created to
 82  
     * represent the section contains the optional prefix.
 83  
     * 
 84  
     * @return this returns the prefix for this section
 85  
     */
 86  
    public String getPrefix() {
 87  217738
       return model.getPrefix();
 88  
    }
 89  
    
 90  
    /**
 91  
     * This is used to acquire the full element path for this
 92  
     * section. The element path is simply the fully qualified
 93  
     * path for this expression with the provided name appended.
 94  
     * If this is an empty path, the provided name is returned.
 95  
     * 
 96  
     * @param name this is the name of the element to be used
 97  
     * 
 98  
     * @return a fully qualified path for the specified name
 99  
     */
 100  
    public String getPath(String name) throws Exception {
 101  1786831
       Expression path = model.getExpression();
 102  
       
 103  1786831
       if(path == null) {
 104  2
          return name;
 105  
       }
 106  1786829
       return path.getElement(name);
 107  
    }
 108  
    
 109  
    /**
 110  
     * This is used to acquire the full attribute path for this 
 111  
     * section. The attribute path is simply the fully qualified
 112  
     * path for this expression with the provided name appended.
 113  
     * If this is an empty path, the provided name is returned.
 114  
     * 
 115  
     * @param name this is the name of the attribute to be used
 116  
     * 
 117  
     * @return a fully qualified path for the specified name
 118  
     */
 119  
    public String getAttribute(String name) throws Exception {
 120  707735
       Expression path = model.getExpression();
 121  
       
 122  707735
       if(path == null) {
 123  0
          return name;
 124  
       }
 125  707735
       return path.getAttribute(name);
 126  
    }
 127  
    
 128  
    /**
 129  
     * This will return the names of all elements contained within
 130  
     * the model. This includes the names of all XML elements that
 131  
     * have been registered as well as any other models that have
 132  
     * been added. Iteration is done in an ordered manner, according
 133  
     * to the registration of elements and models.
 134  
     * 
 135  
     * @return an ordered and styled list of elements and models
 136  
     */
 137  
    public Iterator<String> iterator() {
 138  217742
       List<String> list = new ArrayList<String>();
 139  
       
 140  217742
       for(String element : model) {
 141  421394
          list.add(element);
 142  
       }
 143  217742
       return list.iterator();
 144  
    }
 145  
    
 146  
    /**
 147  
     * To differentiate between a section and an element this can be
 148  
     * used. When iterating over the elements within the section the
 149  
     * names of both elements and sections are provided. So in order
 150  
     * to determine how to interpret the structure this can be used.
 151  
     * 
 152  
     * @param name this is the name of the element to be determined
 153  
     * 
 154  
     * @return this returns true if the name represents a section
 155  
     */   
 156  
    public boolean isSection(String name) throws Exception {      
 157  0
       return getModels().get(name) != null;
 158  
    }
 159  
    
 160  
    /**
 161  
     * Returns a <code>LabelMap</code> that contains the details for
 162  
     * all fields and methods marked with XML annotations. All of the
 163  
     * attribute annotations are considered and gathered by name in 
 164  
     * this map. Also, if there is an associated <code>Style</code> 
 165  
     * for serialization the attribute names are renamed with this.
 166  
     * 
 167  
     * @return returns the attributes associated with this section
 168  
     */
 169  
    public ModelMap getModels() throws Exception {
 170  1787624
       if(models == null) {
 171  930837
          models = model.getModels();
 172  
       }
 173  1787624
       return models;
 174  
    }
 175  
 
 176  
    /**
 177  
     * This is used to acquire the text label for this section if 
 178  
     * one has been specified. A text label can only exist in a
 179  
     * section if there are no elements associated with the section
 180  
     * and the section is not composite, as in it does not contain
 181  
     * any further sections.
 182  
     * 
 183  
     * @return this returns the text label for this section
 184  
     */
 185  
    public Label getText() throws Exception {
 186  930944
       return model.getText();
 187  
    }
 188  
 
 189  
    /**
 190  
     * Returns a <code>LabelMap</code> that contains the details for
 191  
     * all fields and methods marked with XML annotations. All of the
 192  
     * attribute annotations are considered and gathered by name in 
 193  
     * this map. Also, if there is an associated <code>Style</code> 
 194  
     * for serialization the attribute names are renamed with this.
 195  
     * 
 196  
     * @return returns the attributes associated with this section
 197  
     */
 198  
    public LabelMap getAttributes() throws Exception {
 199  932930
       if(attributes == null) {
 200  932930
          attributes = model.getAttributes();
 201  
       }
 202  932930
       return attributes;
 203  
    }
 204  
 
 205  
    /**
 206  
     * Returns a <code>LabelMap</code> that contains the details for
 207  
     * all fields and methods marked with XML annotations. All of the
 208  
     * element annotations are considered and gathered by name in 
 209  
     * this map. Also, if there is an associated <code>Style</code> 
 210  
     * for serialization the element names are renamed with this.
 211  
     * 
 212  
     * @return returns the elements associated with this section
 213  
     */
 214  
    public LabelMap getElements() throws Exception {
 215  1136071
       if(elements == null) {
 216  931420
          elements = model.getElements();
 217  
       }
 218  1136071
       return elements;
 219  
    }
 220  
    
 221  
    /**
 222  
     * Returns the named element as a <code>Label</code> object.
 223  
     * For convenience this method is provided so that when iterating
 224  
     * over the names of the elements in the section a specific one
 225  
     * of interest can be acquired. 
 226  
     * <p>
 227  
     * To ensure that elements of the same name are not referenced
 228  
     * more than once this will remove the element once acquired. 
 229  
     * This ensures that they are visited only once in serialization.
 230  
     * 
 231  
     * @param name the name of the element that is to be acquired
 232  
     * 
 233  
     * @return this returns the label associated with the name
 234  
     */
 235  
    public Label getElement(String name) throws Exception {
 236  420887
       return getElements().getLabel(name);
 237  
    }
 238  
 
 239  
    /**
 240  
     * Returns the named section as a <code>Section</code> object.
 241  
     * For convenience this method is provided so that when iterating
 242  
     * over the names of the elements in the section a specific one
 243  
     * of interest can be acquired. 
 244  
     * <p>
 245  
     * To ensure that models of the same name are not referenced
 246  
     * more than once this will remove the model once acquired. 
 247  
     * This ensures that they are visited only once in serialization.
 248  
     * 
 249  
     * @param name the name of the element that is to be acquired
 250  
     * 
 251  
     * @return this returns the section associated with the name
 252  
     */
 253  
    public Section getSection(String name) throws Exception {
 254  1787624
       ModelMap map = getModels();
 255  1787624
       ModelList list = map.get(name);      
 256  
       
 257  1787624
       if(list != null) {
 258  1015
          Model model = list.take();
 259  
          
 260  1015
          if(model != null){
 261  793
             return new ModelSection(model);
 262  
          }
 263  
       }
 264  1786831
       return null;
 265  
    }
 266  
 }