1 28 29 package org.jibx.binding.def; 30 31 import java.util.ArrayList ; 32 33 import org.jibx.binding.classes.BranchWrapper; 34 import org.jibx.binding.classes.ClassFile; 35 import org.jibx.binding.classes.ClassItem; 36 import org.jibx.binding.classes.ContextMethodBuilder; 37 import org.jibx.binding.classes.MethodBuilder; 38 import org.jibx.binding.model.ClassUtils; 39 import org.jibx.runtime.JiBXException; 40 41 49 50 public class PropertyDefinition 51 { 52 55 56 private final boolean m_isThis; 57 58 59 private final boolean m_isImplicit; 60 61 62 private boolean m_isOptional; 63 64 65 private final IContextObj m_objContext; 66 67 68 private final String m_typeName; 69 70 71 private final String m_getValueType; 72 73 74 private final String m_setValueType; 75 76 77 private final ClassItem m_fieldItem; 78 79 80 private final ClassItem m_testMethod; 81 82 83 private final ClassItem m_getMethod; 84 85 86 private final ClassItem m_setMethod; 87 88 106 107 public PropertyDefinition(IContainer parent, IContextObj obj, String type, 108 boolean isthis, boolean opt, String fname, String test, String get, 109 String set) throws JiBXException { 110 m_objContext = obj; 111 m_isThis = isthis; 112 m_isOptional = opt; 113 ClassFile cf = m_objContext.getBoundClass().getClassFile(); 114 m_isImplicit = false; 115 String dtype = null; 116 String gtype = null; 117 String stype = null; 118 if (isthis) { 119 if (type == null) { 120 dtype = gtype = stype = cf.getName(); 121 } else { 122 dtype = gtype = stype = type; 123 } 124 } 125 if (fname == null) { 126 m_fieldItem = null; 127 } else { 128 m_fieldItem = cf.getField(fname); 129 dtype = gtype = stype = m_fieldItem.getTypeName(); 130 } 131 if (test == null) { 132 m_testMethod = null; 133 } else { 134 if (opt) { 135 m_testMethod = cf.getMethod(test, "()Z"); 136 if (m_testMethod == null) { 137 throw new JiBXException("test-method " + test + 138 " not found in class " + cf.getName()); 139 } 140 } else { 141 throw new JiBXException 142 ("Test method only allowed for optional properties"); 143 } 144 } 145 if (get == null) { 146 m_getMethod = null; 147 } else { 148 m_getMethod = cf.getMethod(get, "()"); 149 if (m_getMethod == null) { 150 throw new JiBXException("get-method " + get + 151 " not found in class " + cf.getName()); 152 } else { 153 gtype = m_getMethod.getTypeName(); 154 if (dtype == null) { 155 dtype = gtype; 156 } 157 } 158 } 159 if (set == null) { 160 m_setMethod = null; 161 } else { 162 163 ArrayList sigs = new ArrayList (); 165 if (m_getMethod != null) { 166 sigs.add("(" + ClassUtils.getSignature(gtype) + ")V"); 167 } 168 if (type != null) { 169 sigs.add("(" + ClassUtils.getSignature(type) + ")V"); 170 } 171 if (m_fieldItem != null) { 172 sigs.add("(" + m_fieldItem.getSignature() + ")V"); 173 } 174 sigs.add("(Ljava/lang/Object;)V"); 175 176 m_setMethod = cf.getMethod(set, 178 (String [])sigs.toArray(new String [0])); 179 if (m_setMethod == null) { 180 throw new JiBXException("set-method " + set + 181 " not found in class " + cf.getName()); 182 } else { 183 stype = m_setMethod.getArgumentType(0); 184 if (dtype == null) { 185 dtype = stype; 186 } 187 } 188 } 189 m_getValueType = gtype; 190 m_setValueType = stype; 191 192 BindingDefinition root = parent.getBindingRoot(); 194 if (!isthis && m_fieldItem == null) { 195 if (root.isInput() && m_setMethod == null) { 196 throw new JiBXException 197 ("Missing way to set value for input binding"); 198 } 199 if (root.isOutput() && m_getMethod == null) { 200 throw new JiBXException 201 ("Missing way to get value for output binding"); 202 } 203 } 204 205 if (type == null) { 207 m_typeName = dtype; 208 } else { 209 m_typeName = type; 210 boolean valid = true; 211 if (isthis) { 212 valid = ClassItem.isAssignable(dtype, type); 213 } else { 214 if (root.isInput()) { 215 valid = ClassItem.isAssignable(type, m_setValueType); 216 } 217 if (valid && root.isOutput()) { 218 valid = ClassItem.isAssignable(type, m_getValueType) || 219 ClassItem.isAssignable(m_getValueType, type); 220 } 221 } 222 if (!valid) { 223 throw new JiBXException 224 ("Incompatible types for property definition"); 225 } 226 } 227 } 228 229 235 236 public PropertyDefinition(IContextObj obj, boolean opt) { 237 m_objContext = obj; 238 m_isThis = true; 239 m_isImplicit = false; 240 m_isOptional = opt; 241 ClassFile cf = m_objContext.getBoundClass().getClassFile(); 242 m_fieldItem = m_testMethod = m_getMethod = m_setMethod = null; 243 m_typeName = m_getValueType = m_setValueType = cf.getName(); 244 } 245 246 253 254 public PropertyDefinition(String type, IContextObj obj, boolean opt) { 255 m_objContext = obj; 256 m_isImplicit = true; 257 m_isThis = false; 258 m_isOptional = opt; 259 m_fieldItem = m_testMethod = m_getMethod = m_setMethod = null; 260 m_typeName = m_getValueType = m_setValueType = type; 261 } 262 263 269 270 public boolean isThis() { 271 return m_isThis; 272 } 273 274 279 280 public boolean isImplicit() { 281 return m_isImplicit; 282 } 283 284 289 290 public boolean isOptional() { 291 return m_isOptional; 292 } 293 294 300 301 public void setOptional(boolean opt) { 302 m_isOptional = opt; 303 } 304 305 313 314 public String getName() { 315 if (m_isThis) { 316 return "this"; 317 } else if (m_fieldItem != null) { 318 return m_fieldItem.getName(); 319 } else if (m_getMethod != null) { 320 String name = m_getMethod.getName(); 321 if (name.startsWith("get") && name.length() > 3) { 322 name = name.substring(3); 323 } 324 return name; 325 } else if (m_setMethod != null) { 326 String name = m_setMethod.getName(); 327 if (name.startsWith("set") && name.length() > 3) { 328 name = name.substring(3); 329 } 330 return name; 331 } else { 332 return "item"; 333 } 334 } 335 336 341 342 public String getTypeName() { 343 return m_typeName; 344 } 345 346 351 352 public String getGetValueType() { 353 return m_getValueType; 354 } 355 356 361 362 public String getSetValueType() { 363 return m_setValueType; 364 } 365 366 374 375 public boolean hasTest() { 376 return isOptional() && 377 (m_testMethod != null || !ClassItem.isPrimitive(m_typeName)); 378 } 379 380 390 391 public BranchWrapper genTest(ContextMethodBuilder mb) 392 throws JiBXException { 393 394 if (m_isThis && m_testMethod == null) { 396 throw new IllegalStateException 397 ("Internal error: No test for \"this\""); 398 } else if (m_isImplicit) { 399 throw new IllegalStateException 400 ("Internal error: No test for implicit value from collection"); 401 } 402 403 if (m_testMethod != null) { 405 406 mb.addMethodExceptions(m_testMethod); 408 if (m_testMethod.isStatic()) { 409 mb.appendPOP(); 410 } 411 mb.appendCall(m_testMethod); 412 return mb.appendIFEQ(this); 413 414 } else if (!ClassItem.isPrimitive(m_typeName)) { 415 416 if (m_getMethod == null) { 419 if (m_fieldItem.isStatic()) { 420 mb.appendPOP(); 421 } 422 mb.appendGet(m_fieldItem); 423 } else { 424 if (m_getMethod.isStatic()) { 425 mb.appendPOP(); 426 } 427 mb.addMethodExceptions(m_getMethod); 428 mb.appendCall(m_getMethod); 429 } 430 return mb.appendIFNULL(this); 431 432 } else { 433 return null; 434 } 435 } 436 437 448 449 public void genLoad(MethodBuilder mb) throws JiBXException { 450 451 if (!m_isThis && !m_isImplicit) { 453 454 ClassFile from = mb.getClassFile(); 456 ClassItem access = m_getMethod; 457 if (access == null) { 458 access = m_fieldItem; 459 } 460 if (!from.isAccessible(access)) { 461 access = m_objContext.getBoundClass(). 462 getLoadMethod(access, mb.getClassFile()); 463 } 464 465 if (access.isStatic()) { 468 mb.appendPOP(); 469 } 470 if (access.isMethod()) { 471 mb.addMethodExceptions(access); 472 mb.appendCall(access); 473 } else { 474 mb.appendGet(access); 475 } 476 477 mb.appendCreateCast(m_getValueType, m_typeName); 479 480 } 481 } 482 483 494 495 public void genStore(MethodBuilder mb) throws JiBXException { 496 497 if (!m_isThis && !m_isImplicit) { 499 500 ClassFile from = mb.getClassFile(); 502 ClassItem access = m_setMethod; 503 if (access == null) { 504 access = m_fieldItem; 505 } 506 if (!from.isAccessible(access)) { 507 access = m_objContext.getBoundClass(). 508 getStoreMethod(access, mb.getClassFile()); 509 } 510 511 if (access.isStatic()) { 514 mb.appendPOP(); 515 } 516 if (access.isMethod()) { 517 mb.addMethodExceptions(access); 518 mb.appendCall(access); 519 } else { 520 mb.appendPut(access); 521 } 522 } 523 } 524 525 public String toString() { 527 StringBuffer text = new StringBuffer (); 528 if (m_isOptional) { 529 text.append("optional "); 530 } 531 text.append("property "); 532 if (m_isThis) { 533 text.append("\"this\" "); 534 } else if (m_isImplicit) { 535 text.append("from collection "); 536 } else if (m_fieldItem != null) { 537 text.append(m_fieldItem.getName() + " "); 538 } else { 539 if (m_getMethod != null) { 540 text.append("from " + m_getMethod.getName() + " "); 541 } 542 if (m_setMethod != null) { 543 text.append("to " + m_setMethod.getName() + " "); 544 } 545 } 546 text.append( "("+ m_typeName + ")"); 547 return text.toString(); 548 } 549 } | Popular Tags |