1 28 29 package org.jibx.binding.model; 30 31 import java.util.ArrayList ; 32 33 import org.jibx.binding.util.StringArray; 34 import org.jibx.runtime.IUnmarshallingContext; 35 import org.jibx.runtime.JiBXException; 36 37 43 44 public class CollectionElement extends StructureElementBase 45 { 46 47 public static final StringArray s_allowedAttributes = 48 new StringArray(new String [] { "add-method", "item-type", "iter-method", 49 "load-method", "size-method", "store-method" }, 50 StructureElementBase.s_allowedAttributes); 51 52 53 private String m_loadMethodName; 54 55 56 private String m_sizeMethodName; 57 58 59 private String m_storeMethodName; 60 61 62 private String m_addMethodName; 63 64 65 private String m_iterMethodName; 66 67 68 private String m_itemTypeName; 69 70 71 private IClassItem m_loadMethodItem; 72 73 74 private IClassItem m_sizeMethodItem; 75 76 77 private IClassItem m_storeMethodItem; 78 79 80 private IClassItem m_addMethodItem; 81 82 83 private IClassItem m_iterMethodItem; 84 85 86 private IClass m_itemTypeClass; 87 88 91 public CollectionElement() { 92 super(COLLECTION_ELEMENT); 93 } 94 95 100 public String getItemTypeName() { 101 return m_itemTypeName; 102 } 103 104 109 public void setItemTypeName(String type) { 110 m_itemTypeName = type; 111 } 112 113 119 public IClass getItemTypeClass() { 120 return m_itemTypeClass; 121 } 122 123 128 public String getAddMethodName() { 129 return m_addMethodName; 130 } 131 132 137 public void setAddMethodName(String name) { 138 m_addMethodName = name; 139 } 140 141 147 public IClassItem getAddMethodItem() { 148 return m_addMethodItem; 149 } 150 151 156 public String getIterMethodName() { 157 return m_iterMethodName; 158 } 159 160 165 public void setIterMethodName(String name) { 166 m_iterMethodName = name; 167 } 168 169 175 public IClassItem getIterMethodItem() { 176 return m_iterMethodItem; 177 } 178 179 184 public String getLoadMethodName() { 185 return m_loadMethodName; 186 } 187 188 193 public void setLoadMethodName(String name) { 194 m_loadMethodName = name; 195 } 196 197 203 public IClassItem getLoadMethodItem() { 204 return m_loadMethodItem; 205 } 206 207 212 public String getSizeMethodName() { 213 return m_sizeMethodName; 214 } 215 216 221 public void setSizeMethodName(String name) { 222 m_sizeMethodName = name; 223 } 224 225 231 public IClassItem getSizeMethodItem() { 232 return m_sizeMethodItem; 233 } 234 235 240 public String getStoreMethodName() { 241 return m_storeMethodName; 242 } 243 244 249 public void setStoreMethodName(String name) { 250 m_storeMethodName = name; 251 } 252 253 259 public IClassItem getStoreMethodItem() { 260 return m_storeMethodItem; 261 } 262 263 266 272 public IClass getEffectiveType() { 273 return m_itemTypeClass; 274 } 275 276 282 public IClass getActualType() { 283 return m_itemTypeClass; 284 } 285 286 294 public boolean setIdChild(IComponent child) { 295 throw new IllegalStateException 296 ("Internal error: method should never be called"); 297 } 298 299 302 308 private void preSet(IUnmarshallingContext uctx) throws JiBXException { 309 validateAttributes(uctx, s_allowedAttributes); 310 } 311 312 315 public void prevalidate(ValidationContext vctx) { 316 317 super.prevalidate(vctx); 319 if (!vctx.isSkipped(this)) { 320 321 IClass clas = getType(); 323 if (clas == null) { 324 clas = vctx.getContextObject().getActualType(); 325 } 326 String tname = m_itemTypeName; 327 if (tname == null) { 328 tname = "java.lang.Object"; 329 } 330 m_itemTypeClass = vctx.getClassInfo(tname); 331 if (m_itemTypeClass == null) { 332 vctx.addFatal("Can't find class " + tname); 333 } 334 336 if (vctx.isInBinding()) { 338 339 String sname = m_storeMethodName; 341 String aname = m_addMethodName; 342 if (sname != null && aname != null) { 343 vctx.addWarning("Both store-method and add-method " + 344 "supplied; using add-method"); 345 sname = null; 346 } 347 348 if (sname == null && aname == null) { 350 if (clas.isSuperclass("java.util.ArrayList") || 351 clas.isSuperclass("java.util.Vector") || 352 clas.isImplements("Ljava/util/Collection;")) { 353 aname = "add"; 354 } else { 355 vctx.addError("Need store-method or add-method for " + 356 "input binding"); 357 } 358 } 359 360 if (sname != null) { 362 m_storeMethodItem = clas.getBestMethod(sname, 363 null, new String [] { "int", tname }); 364 if (m_storeMethodItem == null) { 365 vctx.addError("store-method " + sname + 366 " not found in class " + clas.getName()); 367 } 368 } 369 if (aname != null) { 370 m_addMethodItem = clas.getBestMethod(aname, 371 null, new String [] { tname }); 372 if (m_addMethodItem == null) { 373 vctx.addError("add-method " + aname + 374 " not found in class " + clas.getName()); 375 } 376 } 377 378 } 379 if (vctx.isOutBinding()) { 380 381 String lname = m_loadMethodName; 383 String sname = m_sizeMethodName; 384 String iname = m_iterMethodName; 385 if (lname == null) { 386 if (sname != null) { 387 vctx.addWarning("size-method requires load-method; " + 388 "ignoring supplied size-method"); 389 sname = null; 390 } 391 } else { 392 if (sname == null) { 393 vctx.addWarning("load-method requires " + 394 "size-method; ignoring supplied load-method"); 395 lname = null; 396 } else { 397 if (iname != null) { 398 vctx.addWarning("Both load-method and " + 399 "iter-method supplied; using load-method"); 400 iname = null; 401 } 402 } 403 } 404 405 if (lname == null && iname == null) { 407 if (clas.isSuperclass("java.util.ArrayList") || 408 clas.isSuperclass("java.util.Vector")) { 409 lname = "get"; 410 sname = "size"; 411 } else if (clas.isImplements("Ljava/util/Collection;")) { 412 iname = "iterator"; 413 } 414 } 415 416 if (lname == null) { 418 if (iname == null) { 419 vctx.addError("Need load-method and size-method, or " + 420 "iter-method, for output binding"); 421 } 422 } else { 423 if (sname == null && iname == null) { 424 vctx.addError("Need load-method and size-method," + 425 " or iter-method, for output binding"); 426 } 427 } 428 429 if (lname != null) { 431 m_loadMethodItem = clas.getBestMethod(lname, 432 tname, new String [] { "int" }); 433 if (m_loadMethodItem == null) { 434 vctx.addError("load-method " + lname + 435 " not found in class " + clas.getName()); 436 } 437 } 438 if (iname != null) { 439 m_iterMethodItem = clas.getBestMethod(iname, 440 "java.util.Iterator", new String [0]); 441 if (m_iterMethodItem == null) { 442 vctx.addError("iter-method " + iname + 443 " not found in class " + clas.getName()); 444 } 445 } 446 } 447 } 448 } 449 450 453 public void validate(ValidationContext vctx) { 454 455 super.validate(vctx); 457 458 ArrayList children = children(); 460 for (int i = 0; i < children.size(); i++) { 461 ElementBase child = (ElementBase)children.get(i); 462 if (child instanceof IComponent) { 463 IComponent comp = (IComponent)child; 464 if (!comp.hasName()) { 465 vctx.addFatal("Child components of collection must " + 466 "define element names", comp); 467 } 468 if (vctx.isInBinding() && !comp.hasType()) { 469 if (children.size() != 1) { 470 vctx.addFatal("Child components of collection must " + 471 "define type", comp); 472 } 473 } 474 if (m_itemTypeClass != null) { 475 if (comp.hasType()) { 476 IClass ctype = comp.getType(); 477 if (!ctype.isAssignable(m_itemTypeClass)) { 478 vctx.addFatal("Child components of collection " + 479 "must have types compatible with specified " + 480 "item-type of collection", comp); 481 } 482 } 483 } 484 } 485 } 486 } 487 } | Popular Tags |