Clover coverage report - Code Coverage for hivemind release 1.1-alpha-3
Coverage timestamp: Tue Mar 22 2005 09:10:26 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  9215
     SchemaElement(SchemaProcessor processor, ElementModel model)
 69   
     {
 70  9215
         _processor = processor;
 71  9215
         _model = model;
 72  9215
         _keyAttribute = model.getKeyAttribute();
 73   
 
 74  9215
         List attributeModels = model.getAttributeModels();
 75  9215
         int count = attributeModels.size();
 76   
 
 77  9215
         for (int i = 0; i < count; i++)
 78   
         {
 79  9449
             AttributeModel am = (AttributeModel) attributeModels.get(i);
 80   
 
 81  9449
             String name = am.getName();
 82   
 
 83  9449
             _knownAttributes.add(name);
 84   
 
 85  9449
             if (am.isRequired())
 86  5157
                 _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  9449
             if (am.isUnique())
 92  111
                 _attributeValues.put(name, new HashMap());
 93   
 
 94  9449
             if (name.equals(_keyAttribute))
 95   
             {
 96  110
                 _requiredAttributes.add(name);
 97  110
                 _attributeValues.put(name, new HashMap());
 98   
             }
 99   
 
 100  9449
             _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  421
     SchemaElement getNestedElement(String elementName)
 108   
     {
 109  421
         if (_nestedElements == null)
 110  399
             buildNestedElements();
 111   
 
 112  421
         return (SchemaElement) _nestedElements.get(elementName);
 113   
     }
 114   
 
 115  399
     private void buildNestedElements()
 116   
     {
 117  399
         _nestedElements = new HashMap();
 118   
 
 119  399
         List l = _model.getElementModel();
 120  399
         int count = l.size();
 121   
 
 122  399
         for (int i = 0; i < count; i++)
 123   
         {
 124  8301
             ElementModel nested = (ElementModel) l.get(i);
 125   
 
 126  8301
             SchemaElement nestedElement = new SchemaElement(_processor, nested);
 127   
 
 128   
             // TODO: Check for duplicates here, or at parse!
 129   
 
 130  8301
             _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  3182
     void validateAttributes(Element element)
 140   
     {
 141  3182
         List l = element.getAttributes();
 142  3182
         int count = l.size();
 143  3182
         Set required = new HashSet(_requiredAttributes);
 144  3182
         List errors = new ArrayList();
 145   
 
 146  3182
         for (int i = 0; i < count; i++)
 147   
         {
 148  5731
             Attribute a = (Attribute) l.get(i);
 149  5731
             String name = a.getName();
 150   
 
 151  5731
             if (!_knownAttributes.contains(name))
 152  1
                 errors.add(ImplMessages.unknownAttribute(name));
 153   
 
 154  5731
             checkUniquness(name, a.getValue(), element.getLocation(), errors);
 155   
 
 156  5731
             required.remove(name);
 157   
         }
 158   
 
 159  3182
         Iterator it = required.iterator();
 160   
 
 161  3182
         while (it.hasNext())
 162   
         {
 163  1
             String name = (String) it.next();
 164  1
             errors.add(ImplMessages.missingAttribute(name));
 165   
         }
 166   
 
 167  3182
         count = errors.size();
 168   
 
 169  3182
         if (count == 0)
 170  3180
             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  5731
     private void checkUniquness(String name, String value, Location location, List errors)
 189   
     {
 190  5731
         Map valuesMap = (Map) _attributeValues.get(name);
 191   
 
 192   
         // If null, then not checking on uniqueness.
 193   
 
 194  5731
         if (valuesMap == null)
 195  4750
             return;
 196   
 
 197  981
         Location prior = (Location) valuesMap.get(value);
 198   
 
 199  981
         if (prior == null)
 200   
         {
 201  980
             valuesMap.put(value, location);
 202  980
             return;
 203   
         }
 204   
 
 205   
         // A conflict.
 206   
 
 207  1
         errors.add(ImplMessages.uniqueAttributeConstraintBroken(name, value, prior));
 208   
     }
 209   
 
 210  3180
     void fireBegin(Element element)
 211   
     {
 212  3180
         List rules = _model.getRules();
 213  3180
         int count = rules.size();
 214   
 
 215  3180
         for (int i = 0; i < count; i++)
 216   
         {
 217  14654
             Rule r = (Rule) rules.get(i);
 218   
 
 219  14654
             r.begin(_processor, element);
 220   
 
 221   
         }
 222   
     }
 223   
 
 224  3179
     void fireEnd(Element element)
 225   
     {
 226  3179
         List rules = _model.getRules();
 227  3179
         int count = rules.size();
 228   
 
 229  3179
         for (int i = count - 1; i >= 0; i--)
 230   
         {
 231  14650
             Rule r = (Rule) rules.get(i);
 232   
 
 233  14650
             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  6162
     private Translator getTranslator(String translator)
 251   
     {
 252  6162
         if (translator == null)
 253  13
             return _nullTranslator;
 254   
 
 255  6149
         return _processor.getTranslator(translator);
 256   
     }
 257   
 
 258  6146
     public Translator getAttributeTranslator(String attributeName)
 259   
     {
 260  6146
         String translator = (String) _attributeTranslators.get(attributeName);
 261   
 
 262  6146
         return getTranslator(translator);
 263   
     }
 264   
 
 265  543
     public String getKeyAttribute()
 266   
     {
 267  543
         return _keyAttribute;
 268   
     }
 269   
 }