Clover coverage report - Code Coverage for hivemind release 1.1-alpha-1
Coverage timestamp: Tue Jan 18 2005 07:55:08 EST
file stats: LOC: 269   Methods: 11
NCLOC: 159   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
SchemaElement.java 100% 100% 100% 100%
coverage
 1   
 // Copyright 2004, 2005 The Apache Software Foundation
 2   
 //
 3   
 // Licensed under the Apache License, Version 2.0 (the "License");
 4   
 // you may not use this file except in compliance with the License.
 5   
 // You may obtain a copy of the License at
 6   
 //
 7   
 //     http://www.apache.org/licenses/LICENSE-2.0
 8   
 //
 9   
 // Unless required by applicable law or agreed to in writing, software
 10   
 // distributed under the License is distributed on an "AS IS" BASIS,
 11   
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12   
 // See the License for the specific language governing permissions and
 13   
 // limitations under the License.
 14   
 
 15   
 package org.apache.hivemind.impl;
 16   
 
 17   
 import java.util.ArrayList;
 18   
 import java.util.HashMap;
 19   
 import java.util.HashSet;
 20   
 import java.util.Iterator;
 21   
 import java.util.List;
 22   
 import java.util.Map;
 23   
 import java.util.Set;
 24   
 
 25   
 import org.apache.hivemind.ApplicationRuntimeException;
 26   
 import org.apache.hivemind.Attribute;
 27   
 import org.apache.hivemind.Element;
 28   
 import org.apache.hivemind.Location;
 29   
 import org.apache.hivemind.schema.AttributeModel;
 30   
 import org.apache.hivemind.schema.ElementModel;
 31   
 import org.apache.hivemind.schema.Rule;
 32   
 import org.apache.hivemind.schema.SchemaProcessor;
 33   
 import org.apache.hivemind.schema.Translator;
 34   
 import org.apache.hivemind.schema.rules.NullTranslator;
 35   
 
 36   
 /**
 37   
  * A wrapper around {@link org.apache.hivemind.schema.ElementModel}used by
 38   
  * {@link org.apache.hivemind.impl.SchemaProcessorImpl}.
 39   
  * 
 40   
  * @author Howard Lewis Ship
 41   
  */
 42   
 final class SchemaElement
 43   
 {
 44   
     private SchemaProcessor _processor;
 45   
 
 46   
     private ElementModel _model;
 47   
 
 48   
     private List _requiredAttributes = new ArrayList();
 49   
 
 50   
     private Set _knownAttributes = new HashSet();
 51   
 
 52   
     private String _keyAttribute;
 53   
 
 54   
     private Map _nestedElements;
 55   
 
 56   
     /**
 57   
      * Keyed on attribute name, value is string (possibly null) used to access a translator.
 58   
      */
 59   
     private Map _attributeTranslators = new HashMap();
 60   
 
 61   
     /**
 62   
      * Map of Maps. The outer key is an attribute name string, this indicates that the attribute
 63   
      * values should be unique. Inner map is keyed on attribute value (as a string), the value is
 64   
      * the {@link org.apache.hivemind.Location}defining that value.
 65   
      */
 66   
     private Map _attributeValues = new HashMap();
 67   
 
 68  8618
     SchemaElement(SchemaProcessor processor, ElementModel model)
 69   
     {
 70  8618
         _processor = processor;
 71  8618
         _model = model;
 72  8618
         _keyAttribute = model.getKeyAttribute();
 73   
 
 74  8618
         List attributeModels = model.getAttributeModels();
 75  8618
         int count = attributeModels.size();
 76   
 
 77  8618
         for (int i = 0; i < count; i++)
 78   
         {
 79  8846
             AttributeModel am = (AttributeModel) attributeModels.get(i);
 80   
 
 81  8846
             String name = am.getName();
 82   
 
 83  8846
             _knownAttributes.add(name);
 84   
 
 85  8846
             if (am.isRequired())
 86  4826
                 _requiredAttributes.add(name);
 87   
 
 88   
             // If the attribute should be unique, add a map for that attribute
 89   
             // to track unique values for that attribute.
 90   
 
 91  8846
             if (am.isUnique())
 92  105
                 _attributeValues.put(name, new HashMap());
 93   
 
 94  8846
             if (name.equals(_keyAttribute))
 95   
             {
 96  104
                 _requiredAttributes.add(name);
 97  104
                 _attributeValues.put(name, new HashMap());
 98   
             }
 99   
 
 100  8846
             _attributeTranslators.put(name, am.getTranslator());
 101   
         }
 102   
     }
 103   
 
 104   
     /**
 105   
      * Returns a {@link SchemaElement}for a nested element, or null if no such element exists.
 106   
      */
 107  395
     SchemaElement getNestedElement(String elementName)
 108   
     {
 109  395
         if (_nestedElements == null)
 110  373
             buildNestedElements();
 111   
 
 112  395
         return (SchemaElement) _nestedElements.get(elementName);
 113   
     }
 114   
 
 115  373
     private void buildNestedElements()
 116   
     {
 117  373
         _nestedElements = new HashMap();
 118   
 
 119  373
         List l = _model.getElementModel();
 120  373
         int count = l.size();
 121   
 
 122  373
         for (int i = 0; i < count; i++)
 123   
         {
 124  7755
             ElementModel nested = (ElementModel) l.get(i);
 125   
 
 126  7755
             SchemaElement nestedElement = new SchemaElement(_processor, nested);
 127   
 
 128   
             // TODO: Check for duplicates here, or at parse!
 129   
 
 130  7755
             _nestedElements.put(nested.getElementName(), nestedElement);
 131   
         }
 132   
 
 133   
     }
 134   
 
 135   
     /**
 136   
      * Validates the attributes of the element; checks that all required attributes are present and
 137   
      * that all attributes are defined. Validation errors result in logged error messages.
 138   
      */
 139  2901
     void validateAttributes(Element element)
 140   
     {
 141  2901
         List l = element.getAttributes();
 142  2901
         int count = l.size();
 143  2901
         Set required = new HashSet(_requiredAttributes);
 144  2901
         List errors = new ArrayList();
 145   
 
 146  2901
         for (int i = 0; i < count; i++)
 147   
         {
 148  5210
             Attribute a = (Attribute) l.get(i);
 149  5210
             String name = a.getName();
 150   
 
 151  5210
             if (!_knownAttributes.contains(name))
 152  1
                 errors.add(ImplMessages.unknownAttribute(name));
 153   
 
 154  5210
             checkUniquness(name, a.getValue(), element.getLocation(), errors);
 155   
 
 156  5210
             required.remove(name);
 157   
         }
 158   
 
 159  2901
         Iterator it = required.iterator();
 160   
 
 161  2901
         while (it.hasNext())
 162   
         {
 163  1
             String name = (String) it.next();
 164  1
             errors.add(ImplMessages.missingAttribute(name));
 165   
         }
 166   
 
 167  2901
         count = errors.size();
 168   
 
 169  2901
         if (count == 0)
 170  2899
             return;
 171   
 
 172  2
         StringBuffer buffer = new StringBuffer();
 173   
 
 174  2
         buffer.append(ImplMessages.elementErrors(_processor, element));
 175   
 
 176  2
         for (int i = 0; i < count; i++)
 177   
         {
 178  3
             buffer.append(' ');
 179  3
             buffer.append(errors.get(i).toString());
 180   
         }
 181   
 
 182   
         // TODO: refactor to use the ErrorHandler rather than throw an exception
 183   
         // (these errors are somewhat recoverable).
 184   
 
 185  2
         throw new ApplicationRuntimeException(buffer.toString(), element.getLocation(), null);
 186   
     }
 187   
 
 188  5210
     private void checkUniquness(String name, String value, Location location, List errors)
 189   
     {
 190  5210
         Map valuesMap = (Map) _attributeValues.get(name);
 191   
 
 192   
         // If null, then not checking on uniqueness.
 193   
 
 194  5210
         if (valuesMap == null)
 195  4385
             return;
 196   
 
 197  825
         Location prior = (Location) valuesMap.get(value);
 198   
 
 199  825
         if (prior == null)
 200   
         {
 201  824
             valuesMap.put(value, location);
 202  824
             return;
 203   
         }
 204   
 
 205   
         // A conflict.
 206   
 
 207  1
         errors.add(ImplMessages.uniqueAttributeConstraintBroken(name, value, prior));
 208   
     }
 209   
 
 210  2899
     void fireBegin(Element element)
 211   
     {
 212  2899
         List rules = _model.getRules();
 213  2899
         int count = rules.size();
 214   
 
 215  2899
         for (int i = 0; i < count; i++)
 216   
         {
 217  13551
             Rule r = (Rule) rules.get(i);
 218   
 
 219  13551
             r.begin(_processor, element);
 220   
 
 221   
         }
 222   
     }
 223   
 
 224  2898
     void fireEnd(Element element)
 225   
     {
 226  2898
         List rules = _model.getRules();
 227  2898
         int count = rules.size();
 228   
 
 229  2898
         for (int i = count - 1; i >= 0; i--)
 230   
         {
 231  13547
             Rule r = (Rule) rules.get(i);
 232   
 
 233  13547
             r.end(_processor, element);
 234   
 
 235   
         }
 236   
     }
 237   
 
 238   
     private Translator _nullTranslator = new NullTranslator();
 239   
 
 240   
     private Translator _contentTranslator;
 241   
 
 242  21
     public Translator getContentTranslator()
 243   
     {
 244  21
         if (_contentTranslator == null)
 245  16
             _contentTranslator = getTranslator(_model.getContentTranslator());
 246   
 
 247  21
         return _contentTranslator;
 248   
     }
 249   
 
 250  5203
     private Translator getTranslator(String translator)
 251   
     {
 252  5203
         if (translator == null)
 253  13
             return _nullTranslator;
 254   
 
 255  5190
         return _processor.getTranslator(translator);
 256   
     }
 257   
 
 258  5187
     public Translator getAttributeTranslator(String attributeName)
 259   
     {
 260  5187
         String translator = (String) _attributeTranslators.get(attributeName);
 261   
 
 262  5187
         return getTranslator(translator);
 263   
     }
 264   
 
 265  411
     public String getKeyAttribute()
 266   
     {
 267  411
         return _keyAttribute;
 268   
     }
 269   
 }