1 28 29 package org.jibx.binding.model; 30 31 import java.util.ArrayList ; 32 import java.util.HashSet ; 33 34 import org.jibx.binding.util.ObjectStack; 35 36 44 45 public class TreeContext 46 { 47 48 private DefinitionContext m_globalContext; 49 50 52 private BindingElement m_bindingRoot; 53 54 55 private ObjectStack m_treeHierarchy; 56 57 58 private IClassLocator m_locator; 59 60 61 private HashSet m_skipSet; 62 63 66 public TreeContext(IClassLocator iloc) { 67 m_locator = iloc; 68 m_treeHierarchy = new ObjectStack(); 69 m_skipSet = new HashSet (); 70 } 71 72 79 public void setGlobalDefinitions(DefinitionContext dctx) { 80 m_globalContext = dctx; 81 } 82 83 93 public void tourTree(BindingElement root, ModelVisitor visitor) { 94 95 BindingElement hold = m_bindingRoot; 97 m_bindingRoot = root; 98 99 tourTree((ElementBase)root, visitor); 101 102 m_bindingRoot = hold; 104 } 105 106 115 public void tourTree(ElementBase root, ModelVisitor visitor) { 116 117 if (m_skipSet.contains(root)) { 119 return; 120 } 121 122 boolean expand = false; 124 m_treeHierarchy.push(root); 125 switch (root.type()) { 126 127 case ElementBase.BINDING_ELEMENT: 128 expand = visitor.visit((BindingElement)root); 129 break; 130 131 case ElementBase.COLLECTION_ELEMENT: 132 expand = visitor.visit((CollectionElement)root); 133 break; 134 135 case ElementBase.FORMAT_ELEMENT: 136 visitor.visit((FormatElement)root); 137 break; 138 139 case ElementBase.INCLUDE_ELEMENT: 140 expand = visitor.visit((IncludeElement)root); 141 break; 142 143 case ElementBase.INPUT_ELEMENT: 144 expand = visitor.visit((InputElement)root); 145 break; 146 147 case ElementBase.MAPPING_ELEMENT: 148 expand = visitor.visit((MappingElement)root); 149 break; 150 151 case ElementBase.NAMESPACE_ELEMENT: 152 visitor.visit((NamespaceElement)root); 153 break; 154 155 case ElementBase.OUTPUT_ELEMENT: 156 expand = visitor.visit((OutputElement)root); 157 break; 158 159 case ElementBase.SPLIT_ELEMENT: 160 expand = visitor.visit((SplitElement)root); 161 break; 162 163 case ElementBase.STRUCTURE_ELEMENT: 164 expand = visitor.visit((StructureElement)root); 165 break; 166 167 case ElementBase.TEMPLATE_ELEMENT: 168 expand = visitor.visit((TemplateElement)root); 169 break; 170 171 case ElementBase.VALUE_ELEMENT: 172 visitor.visit((ValueElement)root); 173 break; 174 175 default: 176 throw new IllegalStateException 177 ("Internal error: unknown element type"); 178 179 } 180 181 if (expand && !m_skipSet.contains(root)) { 183 if (root instanceof IncludeElement) { 184 185 BindingElement binding = ((IncludeElement)root).getBinding(); 187 if (binding != null) { 188 m_treeHierarchy.pop(); 189 tourTree((ElementBase)binding, visitor); 190 m_treeHierarchy.push(root); 191 } 192 193 } else if (root instanceof NestingElementBase) { 194 195 ArrayList childs = null; 197 if (root instanceof MappingElement) { 198 childs = ((MappingElement)root).topChildren(); 199 for (int i = 0; i < childs.size(); i++) { 200 tourTree((ElementBase)childs.get(i), visitor); 201 } 202 } 203 if (root instanceof BindingElement) { 204 childs = ((BindingElement)root).topChildren(); 205 } else { 206 childs = ((NestingElementBase)root).children(); 207 } 208 for (int i = 0; i < childs.size(); i++) { 209 tourTree((ElementBase)childs.get(i), visitor); 210 } 211 } 212 } 213 214 switch (root.type()) { 216 217 case ElementBase.BINDING_ELEMENT: 218 visitor.exit((BindingElement)root); 219 break; 220 221 case ElementBase.COLLECTION_ELEMENT: 222 visitor.exit((CollectionElement)root); 223 break; 224 225 case ElementBase.INCLUDE_ELEMENT: 226 visitor.exit((IncludeElement)root); 227 break; 228 229 case ElementBase.INPUT_ELEMENT: 230 visitor.exit((InputElement)root); 231 break; 232 233 case ElementBase.MAPPING_ELEMENT: 234 visitor.exit((MappingElement)root); 235 break; 236 237 case ElementBase.OUTPUT_ELEMENT: 238 visitor.exit((OutputElement)root); 239 break; 240 241 case ElementBase.SPLIT_ELEMENT: 242 visitor.exit((SplitElement)root); 243 break; 244 245 case ElementBase.STRUCTURE_ELEMENT: 246 visitor.exit((StructureElement)root); 247 break; 248 249 case ElementBase.TEMPLATE_ELEMENT: 250 visitor.exit((TemplateElement)root); 251 break; 252 253 case ElementBase.VALUE_ELEMENT: 254 visitor.exit((ValueElement)root); 255 break; 256 257 default: 258 break; 259 260 } 261 m_treeHierarchy.pop(); 262 } 263 264 269 public int getNestingDepth() { 270 return m_treeHierarchy.size(); 271 } 272 273 276 protected ElementBase peekElement() { 277 return (ElementBase)m_treeHierarchy.peek(); 278 } 279 280 286 public boolean isSkipped(Object obj) { 287 return m_skipSet.contains(obj); 288 } 289 290 295 protected void addSkip(Object skip) { 296 if (skip instanceof ElementBase) { 297 m_skipSet.add(skip); 298 } 299 } 300 301 307 public BindingElement getBindingRoot() { 308 if (m_bindingRoot == null) { 309 throw new IllegalStateException ("No binding root defined"); 310 } else { 311 return m_bindingRoot; 312 } 313 } 314 315 322 public void setBindingRoot(BindingElement root) { 323 m_bindingRoot = root; 324 } 325 326 334 public NestingElementBase getParentElement() { 335 if (m_treeHierarchy.size() > 1) { 336 return (NestingElementBase)m_treeHierarchy.peek(1); 337 } else { 338 return null; 339 } 340 } 341 342 350 public ElementBase getParentElement(int level) { 351 return (ElementBase)m_treeHierarchy.peek(level); 352 } 353 354 360 public ContainerElementBase getParentContainer() { 361 int index = 1; 362 while (index < m_treeHierarchy.size()) { 363 NestingElementBase nest = 364 (NestingElementBase)m_treeHierarchy.peek(index++); 365 if (nest instanceof ContainerElementBase) { 366 return (ContainerElementBase)nest; 367 } 368 } 369 throw new IllegalStateException ("Internal error: no container"); 370 } 371 372 378 public ContainerElementBase getContextObject() { 379 int index = 1; 380 while (index < m_treeHierarchy.size()) { 381 NestingElementBase nest = 382 (NestingElementBase)m_treeHierarchy.peek(index++); 383 if (nest instanceof ContainerElementBase) { 384 ContainerElementBase contain = (ContainerElementBase)nest; 385 if (contain.getActualType() != null) { 386 return contain; 387 } 388 } 389 } 390 throw new IllegalStateException ("Internal error: no context object"); 391 } 392 393 398 public boolean isInBinding() { 399 return m_bindingRoot == null ? true : m_bindingRoot.isInBinding(); 400 } 401 402 407 public boolean isOutBinding() { 408 return m_bindingRoot == null ? true : m_bindingRoot.isOutBinding(); 409 } 410 411 416 public DefinitionContext getDefinitions() { 417 int index = 1; 418 while (index < m_treeHierarchy.size()) { 419 NestingElementBase nest = 420 (NestingElementBase)m_treeHierarchy.peek(index++); 421 if (nest.getDefinitions() != null) { 422 return nest.getDefinitions(); 423 } 424 } 425 if (m_globalContext == null) { 426 throw new IllegalStateException 427 ("Internal error: no definition context"); 428 } else { 429 return m_globalContext; 430 } 431 } 432 433 439 public DefinitionContext getCurrentDefinitions() { 440 NestingElementBase parent = getParentElement(); 441 DefinitionContext dctx = parent.getDefinitions(); 442 if (dctx == null) { 443 dctx = new DefinitionContext(getDefinitions()); 444 parent.setDefinitions(dctx); 445 } 446 return dctx; 447 } 448 449 459 public DefinitionContext getFormatDefinitions() { 460 NestingElementBase parent = getParentElement(); 461 DefinitionContext dctx = parent.getDefinitions(); 462 if (dctx == null) { 463 464 int index = 1; 466 DefinitionContext pctx = null; 467 while (++index < m_treeHierarchy.size()) { 468 NestingElementBase nest = 469 (NestingElementBase)m_treeHierarchy.peek(index); 470 pctx = nest.getDefinitions(); 471 if (pctx != null) { 472 break; 473 } 474 } 475 476 while (index >= 2) { 478 dctx = new DefinitionContext(pctx); 479 NestingElementBase nest = 480 (NestingElementBase)m_treeHierarchy.peek(--index); 481 nest.setDefinitions(dctx); 482 pctx = dctx; 483 } 484 } 485 return dctx; 486 } 487 488 495 public IClass getClassInfo(String name) { 496 return m_locator.getClassInfo(name); 497 } 498 499 507 public IClass getRequiredClassInfo(String name) { 508 IClass iclas = m_locator.getClassInfo(name); 509 if (iclas == null) { 510 throw new IllegalStateException ("Internal error: class " + name + 511 " cannot be found"); 512 } else { 513 return iclas; 514 } 515 } 516 } | Popular Tags |