1 28 29 package org.jibx.binding.def; 30 31 import org.apache.bcel.Constants; 32 import org.apache.bcel.generic.Type; 33 34 import org.jibx.binding.classes.*; 35 import org.jibx.runtime.JiBXException; 36 37 44 45 public class DirectObject implements IComponent 46 { 47 50 private static final String GETUNMARSHALLER_METHOD = 51 "org.jibx.runtime.IUnmarshallingContext.getUnmarshaller"; 52 private static final String GETUNMARSHALLER_SIGNATURE = 53 "(I)Lorg/jibx/runtime/IUnmarshaller;"; 54 private static final String GETMARSHALLER_METHOD = 55 "org.jibx.runtime.IMarshallingContext.getMarshaller"; 56 private static final String GETMARSHALLER_SIGNATURE = 57 "(ILjava/lang/String;)Lorg/jibx/runtime/IMarshaller;"; 58 private static final String MARSHALLER_MARSHAL_METHOD = 59 "org.jibx.runtime.IMarshaller.marshal"; 60 private static final String MARSHALLER_MARSHAL_SIGNATURE = 61 "(Ljava/lang/Object;Lorg/jibx/runtime/IMarshallingContext;)V"; 62 private static final String UNMARSHALLER_TESTPRESENT_METHOD = 63 "org.jibx.runtime.IUnmarshaller.isPresent"; 64 private static final String UNMARSHALLER_TESTPRESENT_SIGNATURE = 65 "(Lorg/jibx/runtime/IUnmarshallingContext;)Z"; 66 private static final String UNMARSHALLER_UNMARSHAL_METHOD = 67 "org.jibx.runtime.IUnmarshaller.unmarshal"; 68 private static final String UNMARSHALLER_UNMARSHAL_SIGNATURE = 69 "(Ljava/lang/Object;Lorg/jibx/runtime/IUnmarshallingContext;)" + 70 "Ljava/lang/Object;"; 71 private static final String ABSTRACTMARSHALLER_INTERFACE = 72 "org.jibx.runtime.IAbstractMarshaller"; 73 private static final String ABSTRACTMARSHAL_METHOD = 74 "org.jibx.runtime.IAbstractMarshaller.baseMarshal"; 75 private static final String ABSTRACTMARSHAL_SIGNATURE = 76 MARSHALLER_MARSHAL_SIGNATURE; 77 private static final String ALIASABLE_INTERFACETYPE = 78 "Lorg/jibx/runtime/IAliasable;"; 79 private static final String ANY_INIT_SIG = "()V"; 80 private static final String ANY_INITCLASS_SIG = "(Ljava/lang/String;)V"; 81 private static final String MARSHALUNMARSHAL_INIT_SIG = 82 "(Ljava/lang/String;ILjava/lang/String;)V"; 83 private static final String MARSHALONLY_INIT_SIG = "(ILjava/lang/String;)V"; 84 private static final String UNMARSHALONLY_INIT_SIG = 85 "(Ljava/lang/String;Ljava/lang/String;)V"; 86 private static final String MARSHALUNMARSHAL_INITCLASS_SIG = 87 "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V"; 88 private static final String MARSHALONLY_INITCLASS_SIG = 89 "(ILjava/lang/String;Ljava/lang/String;)V"; 90 private static final String UNMARSHALONLY_INITCLASS_SIG = 91 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"; 92 93 96 97 private final IContainer m_parent; 98 99 100 private final DefinitionContext m_defContext; 101 102 105 private final boolean m_isAbstract; 106 107 108 private final NameDefinition m_name; 109 110 114 private boolean m_isSlotSet; 115 116 117 private int m_mumSlot; 118 119 120 private final ClassFile m_targetClass; 121 122 123 private final ClassFile m_marshallerBase; 124 125 126 private final ClassFile m_unmarshallerBase; 127 128 129 private ClassFile m_marshaller; 130 131 132 private ClassFile m_unmarshaller; 133 134 150 151 public DirectObject(IContainer parent, DefinitionContext defc, 152 ClassFile target, boolean abs, ClassFile mcf, ClassFile ucf, int slot, 153 NameDefinition name) throws JiBXException { 154 155 m_parent = parent; 157 m_defContext = (defc == null) ? m_parent.getDefinitionContext() : defc; 158 m_isAbstract = abs; 159 m_targetClass = target; 160 m_marshallerBase = mcf; 161 m_unmarshallerBase = ucf; 162 m_name = name; 163 m_mumSlot = slot; 164 m_isSlotSet = slot >= 0; 165 166 if (name == null) { 168 169 if (mcf != null) { 171 if (mcf.getInitializerMethod(ANY_INIT_SIG) != null) { 172 m_marshaller = mcf; 173 } else if (mcf.getInitializerMethod 174 (ANY_INITCLASS_SIG) == null) { 175 throw new JiBXException("Marshaller class " + 176 mcf.getName() + " requires name to be set"); 177 } 178 } 179 if (ucf != null) { 180 if (ucf.getInitializerMethod(ANY_INIT_SIG) != null) { 181 m_unmarshaller = ucf; 182 } else if (ucf.getInitializerMethod 183 (ANY_INITCLASS_SIG) == null) { 184 throw new JiBXException("Unmarshaller class " + 185 ucf.getName() + " requires name to be set"); 186 } 187 } 188 } 189 if (name != null) { 190 191 if (mcf != null && !mcf.isImplements(ALIASABLE_INTERFACETYPE)) { 193 throw new JiBXException("Marshaller class " + 194 mcf.getName() + " does not allow name to be set"); 195 } 196 if (ucf != null && !ucf.isImplements(ALIASABLE_INTERFACETYPE)) { 197 throw new JiBXException("Unmarshaller class " + 198 ucf.getName() + " does not allow name to be set"); 199 } 200 } 201 } 202 203 212 213 private int getSlot() throws JiBXException { 214 if (!m_isSlotSet) { 215 216 BindingDefinition bdef = m_parent.getBindingRoot(); 218 m_mumSlot = bdef.getMarshallerUnmarshallerIndex 219 (m_targetClass.getName()); 220 m_isSlotSet = true; 221 222 String mclas = null; 224 String uclas = null; 225 if (bdef.isOutput()) { 226 if (m_marshaller == null) { 227 createSubclass(true); 228 } 229 mclas = m_marshaller.getName(); 230 } 231 if (bdef.isInput()) { 232 if (m_unmarshaller == null) { 233 createSubclass(false); 234 } 235 uclas = m_unmarshaller.getName(); 236 } 237 bdef.setMarshallerUnmarshallerClasses(m_mumSlot, mclas, uclas); 238 } 239 return m_mumSlot; 240 } 241 242 248 249 private void genLoadSlot(ContextMethodBuilder mb) throws JiBXException { 250 mb.appendLoadConstant(getSlot()); 251 } 252 253 263 264 private void createSubclass(boolean out) throws JiBXException { 265 266 ClassItem init = null; 268 boolean dual = false; 269 boolean classed = true; 270 boolean named = false; 271 ClassFile base = out ? m_marshallerBase : m_unmarshallerBase; 272 273 if (m_name == null) { 275 init = base.getInitializerMethod(ANY_INITCLASS_SIG); 276 classed = init != null; 277 } 278 if (init == null) { 279 named = true; 280 if (m_unmarshallerBase == m_marshallerBase) { 281 282 init = base.getInitializerMethod 284 (MARSHALUNMARSHAL_INITCLASS_SIG); 285 if (init == null) { 286 classed = false; 287 init = base.getInitializerMethod(MARSHALUNMARSHAL_INIT_SIG); 288 } 289 dual = true; 290 291 } else { 292 293 String sig = out ? 295 MARSHALONLY_INITCLASS_SIG : UNMARSHALONLY_INITCLASS_SIG; 296 init = base.getInitializerMethod(sig); 297 if (init == null) { 298 299 sig = MARSHALUNMARSHAL_INITCLASS_SIG; 301 init = base.getInitializerMethod(sig); 302 dual = true; 303 if (init == null) { 304 305 classed = false; 307 sig = out ? MARSHALONLY_INIT_SIG : 308 UNMARSHALONLY_INIT_SIG; 309 init = base.getInitializerMethod(sig); 310 dual = false; 311 if (init == null) { 312 sig = MARSHALUNMARSHAL_INIT_SIG; 313 init = base.getInitializerMethod(sig); 314 dual = true; 315 } 316 317 } 318 } 319 } 320 } 321 322 if (init == null || ((init.getAccessFlags() & 324 Constants.ACC_PUBLIC) == 0)) { 325 throw new JiBXException("No usable constructor for " + 326 "marshaller or unmarshaller based on " + base.getName()); 327 } 328 329 String tname = base.getName(); 331 int split = tname.lastIndexOf('.'); 332 if (split >= 0) { 333 tname = tname.substring(split+1); 334 } 335 336 BindingDefinition def = m_parent.getBindingRoot(); 338 String name = def.getDefaultPackage() + '.' + def.getPrefix() + tname + 339 '_' + getSlot(); 340 String [] intfs = def.isInput() ? (def.isOutput() ? 341 MappingDefinition.BOTH_INTERFACES : 342 MappingDefinition.UNMARSHALLER_INTERFACES) : 343 MappingDefinition.MARSHALLER_INTERFACES; 344 ClassFile cf = new ClassFile(name, def.getDefaultRoot(), 345 base, Constants.ACC_PUBLIC, intfs); 346 347 ExceptionMethodBuilder mb = new ExceptionMethodBuilder("<init>", 349 Type.VOID, new Type[0], cf, Constants.ACC_PUBLIC); 350 351 mb.appendLoadLocal(0); 353 if (m_name == null) { 354 if (named) { 355 if (dual) { 356 mb.appendACONST_NULL(); 357 mb.appendICONST_0(); 358 mb.appendACONST_NULL(); 359 } else if (out) { 360 mb.appendICONST_0(); 361 mb.appendACONST_NULL(); 362 } else { 363 mb.appendACONST_NULL(); 364 mb.appendACONST_NULL(); 365 } 366 } 367 } else { 368 if (dual) { 369 m_name.genPushUri(mb); 370 m_name.genPushIndexPair(mb); 371 } else if (out) { 372 m_name.genPushIndexPair(mb); 373 } else { 374 m_name.genPushUriPair(mb); 375 } 376 } 377 if (classed) { 378 mb.appendLoadConstant(m_targetClass.getName()); 379 } 380 mb.appendCallInit(base.getName(), init.getSignature()); 381 382 mb.appendReturn(); 384 mb.codeComplete(false); 385 386 mb.addMethod(); 388 cf = MungedClass.getUniqueSupportClass(cf); 389 390 if (dual) { 392 m_marshaller = m_unmarshaller = cf; 393 } else if (out) { 394 m_marshaller = cf; 395 } else { 396 m_unmarshaller = cf; 397 } 398 } 399 400 408 409 public void genTestPresent(ContextMethodBuilder mb) throws JiBXException { 410 411 mb.loadContext(); 414 genLoadSlot(mb); 415 mb.appendCallInterface(GETUNMARSHALLER_METHOD, 416 GETUNMARSHALLER_SIGNATURE); 417 418 mb.loadContext(); 420 mb.appendCallInterface(UNMARSHALLER_TESTPRESENT_METHOD, 421 UNMARSHALLER_TESTPRESENT_SIGNATURE); 422 } 423 424 436 437 public void genUnmarshal(ContextMethodBuilder mb) throws JiBXException { 438 439 mb.loadContext(); 442 genLoadSlot(mb); 443 mb.appendCallInterface(GETUNMARSHALLER_METHOD, 444 GETUNMARSHALLER_SIGNATURE); 445 446 mb.appendSWAP(); 448 mb.loadContext(); 449 mb.appendCallInterface(UNMARSHALLER_UNMARSHAL_METHOD, 450 UNMARSHALLER_UNMARSHAL_SIGNATURE); 451 } 452 453 461 462 public void genMarshal(ContextMethodBuilder mb) throws JiBXException { 463 464 mb.loadContext(); 467 genLoadSlot(mb); 468 mb.appendLoadConstant(m_targetClass.getName()); 469 mb.appendCallInterface(GETMARSHALLER_METHOD, GETMARSHALLER_SIGNATURE); 470 471 if (m_isAbstract) { 473 474 mb.appendCreateCast(ABSTRACTMARSHALLER_INTERFACE); 476 477 mb.appendSWAP(); 479 480 mb.loadContext(); 483 mb.appendCallInterface(ABSTRACTMARSHAL_METHOD, 484 ABSTRACTMARSHAL_SIGNATURE); 485 486 } else { 487 488 mb.appendSWAP(); 490 491 mb.loadContext(); 494 mb.appendCallInterface(MARSHALLER_MARSHAL_METHOD, 495 MARSHALLER_MARSHAL_SIGNATURE); 496 } 497 } 498 499 504 505 public ClassFile getTargetClass() { 506 return m_targetClass; 507 } 508 509 515 516 public NameDefinition getName() { 517 return m_name; 518 } 519 520 528 529 public ClassFile getMarshaller() throws JiBXException { 530 if (m_marshaller == null && m_marshallerBase != null) { 531 createSubclass(true); 532 } 533 return m_marshaller; 534 } 535 536 544 545 public ClassFile getUnmarshaller() throws JiBXException { 546 if (m_unmarshaller == null && m_unmarshallerBase != null) { 547 createSubclass(false); 548 } 549 return m_unmarshaller; 550 } 551 552 555 public boolean isOptional() { 556 return false; 557 } 558 559 public boolean hasAttribute() { 560 return false; 561 } 562 563 public void genAttrPresentTest(ContextMethodBuilder mb) { 564 throw new IllegalStateException 565 ("Internal error - no attributes defined"); 566 } 567 568 public void genAttributeUnmarshal(ContextMethodBuilder mb) { 569 throw new IllegalStateException 570 ("Internal error - no attributes defined"); 571 } 572 573 public void genAttributeMarshal(ContextMethodBuilder mb) { 574 throw new IllegalStateException 575 ("Internal error - no attributes defined"); 576 } 577 578 public boolean hasContent() { 579 return true; 580 } 581 582 public void genContentPresentTest(ContextMethodBuilder mb) 583 throws JiBXException { 584 genTestPresent(mb); 585 } 586 587 public void genContentUnmarshal(ContextMethodBuilder mb) 588 throws JiBXException { 589 genUnmarshal(mb); 590 } 591 592 public void genContentMarshal(ContextMethodBuilder mb) 593 throws JiBXException { 594 genMarshal(mb); 595 } 596 597 public void genNewInstance(ContextMethodBuilder mb) { 598 throw new IllegalStateException 599 ("Internal error - no instance creation"); 600 } 601 602 public String getType() { 603 return m_targetClass.getFile().getName(); 604 } 605 606 public boolean hasId() { 607 return false; 608 } 609 610 public void genLoadId(ContextMethodBuilder mb) { 611 throw new IllegalStateException ("Internal error - no ID allowed"); 612 } 613 614 public boolean checkContentSequence(boolean text) { 615 return true; 616 } 617 618 public void setLinkages() throws JiBXException { 619 if (m_name != null) { 620 m_name.fixNamespace(m_defContext); 621 } 622 } 623 624 public void print(int depth) { 626 BindingDefinition.indent(depth); 627 System.out.println("direct marshaller/unmarshaller reference" ); 628 } 629 } 630 | Popular Tags |