1 15 package org.apache.hivemind.impl; 16 17 import java.util.ArrayList ; 18 import java.util.HashMap ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 import java.util.Map ; 22 23 import org.apache.hivemind.ApplicationRuntimeException; 24 import org.apache.hivemind.Element; 25 import org.apache.hivemind.ErrorLog; 26 import org.apache.hivemind.SymbolExpander; 27 import org.apache.hivemind.TranslatorManager; 28 import org.apache.hivemind.internal.Module; 29 import org.apache.hivemind.schema.AttributeModel; 30 import org.apache.hivemind.schema.ElementModel; 31 import org.apache.hivemind.schema.Schema; 32 import org.apache.hivemind.schema.SchemaProcessor; 33 import org.apache.hivemind.schema.Translator; 34 import org.apache.hivemind.util.Defense; 35 36 43 public final class SchemaProcessorImpl implements SchemaProcessor 44 { 45 private ErrorLog _errorLog; 46 47 private Schema _schema; 48 49 private List _stack = new ArrayList (); 50 51 private Module _contributingModule; 52 53 private TranslatorManager _translatorManager; 54 55 private SymbolExpander _symbolExpander; 56 57 60 private Map _elementMap = new HashMap (); 61 62 private boolean _canElementsBeMapped; 63 64 67 private List _elementStack = new ArrayList (); 68 69 public SchemaProcessorImpl(ErrorLog errorLog, Schema schema) 70 { 71 _errorLog = errorLog; 72 _schema = schema; 73 74 if (_schema != null) 75 { 76 List l = _schema.getElementModel(); 77 78 int count = l.size(); 79 for (int i = 0; i < count; i++) 80 { 81 ElementModel model = (ElementModel) l.get(i); 82 _elementMap.put(model.getElementName(), new SchemaElement(this, model)); 83 } 84 85 _canElementsBeMapped = schema.canInstancesBeKeyed(); 87 } 88 } 89 90 private Element peekElement() 91 { 92 return (Element) _elementStack.get(_elementStack.size() - 1); 93 } 94 95 100 public void addKeyedElement(Object element) 101 { 102 if (_canElementsBeMapped) 103 { 104 Element currentElement = peekElement(); 105 String keyAttribute = _activeElement.getModel().getKeyAttribute(); 106 107 if (keyAttribute == null) { 108 for (Iterator j = _activeElement.getModel().getAttributeModels().iterator(); j.hasNext();) 110 { 111 AttributeModel attributeModel = (AttributeModel) j.next(); 112 113 if (attributeModel.isUnique()) 114 keyAttribute = attributeModel.getName(); 115 } 116 } 117 118 String expandedKey = getSymbolExpander().expandSymbols( 119 currentElement.getAttributeValue(keyAttribute), 120 currentElement.getLocation()); 121 122 Translator t = getAttributeTranslator(keyAttribute); 123 124 Object finalValue = t.translate( 125 getContributingModule(), 126 Object .class, 127 expandedKey, 128 currentElement.getLocation()); 129 130 Map container = (Map ) _stack.get(0); 131 container.put(finalValue, element); 132 133 } 134 } 135 136 139 public boolean isInBackwardCompatibilityModeForMaps() 140 { 141 return _canElementsBeMapped; 142 } 143 144 public void push(Object object) 145 { 146 _stack.add(object); 147 } 148 149 public Object pop() 150 { 151 if (_stack.isEmpty()) 152 throw new ArrayIndexOutOfBoundsException (XmlImplMessages.schemaStackViolation(this)); 153 154 return _stack.remove(_stack.size() - 1); 155 } 156 157 public Object peek() 158 { 159 return peek(0); 160 } 161 162 public Object peek(int depth) 163 { 164 int count = _stack.size(); 165 166 int position = count - 1 - depth; 167 168 if (position < 0) 169 throw new ArrayIndexOutOfBoundsException (XmlImplMessages.schemaStackViolation(this)); 170 171 return _stack.get(count - 1 - depth); 172 } 173 174 public Module getContributingModule() 175 { 176 return _contributingModule; 177 } 178 179 180 181 public String getDefiningModuleId() 182 { 183 return _schema.getDefiningModuleId(); 184 } 185 186 public Module getDefiningModule() 187 { 188 Module definingModule = getContributingModule().getRegistry().getModule(_schema.getDefiningModuleId()); 189 Defense.notNull(definingModule, "Defining module"); 190 return definingModule; 191 } 192 193 public String getElementPath() 194 { 195 StringBuffer buffer = new StringBuffer (); 196 int count = _elementStack.size(); 197 198 for (int i = 0; i < count; i++) 199 { 200 if (i > 0) 201 buffer.append('/'); 202 203 buffer.append(((Element) _elementStack.get(i)).getElementName()); 204 } 205 206 return buffer.toString(); 207 } 208 209 private void pushElement(Element element) 210 { 211 _elementStack.add(element); 212 } 213 214 private void popElement() 215 { 216 _elementStack.remove(_elementStack.size() - 1); 217 } 218 219 223 public void process(Object container, List elements, Module contributingModule) 224 { 225 if (elements == null) 226 return; 227 228 if (_schema == null) 229 { 230 return; 231 } 232 Defense.notNull(contributingModule, "Contributing module"); 233 234 if (_canElementsBeMapped && !(container instanceof Map )) { 235 throw new ApplicationRuntimeException("Schema root class is expected to be assignable to " + 236 "'java.util.Map' because key-attribute or unique attribute is used in the schema. "); 237 } 238 239 push(container); 241 242 _contributingModule = contributingModule; 243 244 int count = elements.size(); 245 246 for (int i = 0; i < count; i++) 247 { 248 Element e = (Element) elements.get(i); 249 250 processRootElement(e); 251 } 252 253 _contributingModule = null; 254 } 255 256 private void processRootElement(Element element) 257 { 258 String name = element.getElementName(); 259 260 SchemaElement schemaElement = (SchemaElement) _elementMap.get(name); 261 262 processElement(element, schemaElement); 263 } 264 265 private SchemaElement _activeElement; 266 267 private void processElement(Element element, SchemaElement schemaElement) 268 { 269 pushElement(element); 270 271 if (schemaElement == null) 272 _errorLog 273 .error(XmlImplMessages.unknownElement(this, element), element.getLocation(), null); 274 else 275 { 276 SchemaElement prior = _activeElement; 277 278 schemaElement.validateAttributes(element); 279 280 _activeElement = schemaElement; 281 282 schemaElement.fireBegin(element); 283 284 processNestedElements(element, schemaElement); 285 286 schemaElement.fireEnd(element); 287 288 _activeElement = prior; 289 } 290 291 popElement(); 292 } 293 294 private void processNestedElements(Element element, SchemaElement schemaElement) 295 { 296 List l = element.getElements(); 297 int count = l.size(); 298 299 for (int i = 0; i < count; i++) 300 { 301 Element nested = (Element) l.get(i); 302 String name = nested.getElementName(); 303 304 processElement(nested, schemaElement.getNestedElement(name)); 305 } 306 } 307 308 public Translator getContentTranslator() 309 { 310 return _activeElement.getContentTranslator(); 311 } 312 313 public String getAttributeDefault(String attributeName) 314 { 315 return _activeElement.getAttributeDefault(attributeName); 316 } 317 318 public Translator getAttributeTranslator(String attributeName) 319 { 320 return _activeElement.getAttributeTranslator(attributeName); 321 } 322 323 public Translator getTranslator(String translator) 324 { 325 if (_translatorManager == null) { 326 _translatorManager = (TranslatorManager) _contributingModule.getService(TranslatorManager.class); 327 } 328 329 return _translatorManager.getTranslator(translator); 330 } 331 332 public SymbolExpander getSymbolExpander() 333 { 334 if (_symbolExpander == null) { 335 _symbolExpander = (SymbolExpander) _contributingModule.getService(SymbolExpander.class); 336 } 337 return _symbolExpander; 338 } 339 } | Popular Tags |