1 /* 2 * Redistribution and use of this software and associated documentation 3 * ("Software"), with or without modification, are permitted provided 4 * that the following conditions are met: 5 * 6 * 1. Redistributions of source code must retain copyright 7 * statements and notices. Redistributions must also contain a 8 * copy of this document. 9 * 10 * 2. Redistributions in binary form must reproduce the 11 * above copyright notice, this list of conditions and the 12 * following disclaimer in the documentation and/or other 13 * materials provided with the distribution. 14 * 15 * 3. The name "Exolab" must not be used to endorse or promote 16 * products derived from this Software without prior written 17 * permission of Intalio, Inc. For written permission, 18 * please contact info@exolab.org. 19 * 20 * 4. Products derived from this Software may not be called "Exolab" 21 * nor may "Exolab" appear in their names without prior written 22 * permission of Intalio, Inc. Exolab is a registered 23 * trademark of Intalio, Inc. 24 * 25 * 5. Due credit should be given to the Exolab Project 26 * (http://www.exolab.org/). 27 * 28 * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 32 * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 39 * OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Copyright 1999-2004 (C) Intalio, Inc. All Rights Reserved. 42 * 43 * This file was originally developed by Keith Visco during the course 44 * of employment at Intalio Inc. 45 * Portions of this file developed by Keith Visco after Jan 19 2005 are 46 * Copyright (C) 2005 Keith Visco. All Rights Reserverd. 47 * 48 * $Id$ 49 */ 50 package org.exolab.castor.builder.info; 51 52 import java.util.HashMap; 53 import java.util.HashSet; 54 import java.util.LinkedList; 55 import java.util.List; 56 import java.util.Map; 57 import java.util.Set; 58 59 import org.castor.core.nature.PropertyHolder; 60 import org.exolab.castor.builder.factory.FieldMemberAndAccessorFactory; 61 import org.exolab.castor.builder.info.nature.XMLInfoNature; 62 import org.exolab.castor.builder.types.XSType; 63 import org.exolab.javasource.JType; 64 65 /** 66 * A class for representing field members of a class. FieldInfo objects hold all 67 * the information required about a member in order to be able to produce 68 * XML data binding (marshal/unmarshal) and validation code. 69 * 70 * @author <a href="mailto:keith AT kvisco DOT com">Keith Visco</a> 71 * @version $Revision$ $Date: 2006-04-25 15:08:23 -0600 (Tue, 25 Apr 2006) $ 72 */ 73 public class FieldInfo implements XMLInfo, PropertyHolder { 74 /** 75 * Map holding the properties set and read by Natures. 76 */ 77 private Map<String, Object> _properties = new HashMap<String, Object>(); 78 79 /** 80 * Set holding applicable natures. 81 */ 82 private Set<String> _natures = new HashSet<String>(); 83 84 /** The Read / Getter method flag. */ 85 public static final int READ_METHOD = 1; 86 /** The Write / Setter method flag. */ 87 public static final int WRITE_METHOD = 2; 88 /** The Read and Write methods flags. */ 89 public static final int READ_WRITE_METHODS = 3; 90 91 /** Method prefixes for "Add" methods. */ 92 protected static final String METHOD_PREFIX_ADD = "add"; 93 /** Method prefixes for "Delete" methods. */ 94 protected static final String METHOD_PREFIX_DELETE = "delete"; 95 /** Method prefixes for "Get" methods. */ 96 protected static final String METHOD_PREFIX_GET = "get"; 97 /** Method prefixes for "Has" methods. */ 98 protected static final String METHOD_PREFIX_HAS = "has"; 99 /** Method prefixes for "Set" methods. */ 100 protected static final String METHOD_PREFIX_SET = "set"; 101 /** Method prefixes for "Is" methods. */ 102 protected static final String METHOD_PREFIX_IS = "is"; 103 104 /** The Java name for Members described by this FieldInfo. */ 105 private String _name = null; 106 107 /** 108 * {@link ClassInfo} instance which 'own' (declares) this 109 * {@link FieldInfo}. 110 */ 111 private ClassInfo _declaringClassInfo = null; 112 113 /** JavaDoc comment. */ 114 private String _comment = null; 115 116 /** The default value for this FieldInfo. */ 117 private String _default = null; 118 /** The fixed production for this FieldInfo. */ 119 private String _fixed = null; 120 /** A flag to indicate a final member. */ 121 private boolean _final = false; 122 /** The methods flags, indicates which methods to create. */ 123 private int _methods = READ_WRITE_METHODS; 124 /** A reference to the FieldInfo instance within the same class. */ 125 private FieldInfo _fieldInfoReference = null; 126 /** A flag to indicate a static member. */ 127 private boolean _static = false; 128 /** Flags whether or not the a MarshalDescriptor should be created for this FieldInfo. */ 129 private boolean _transient = false; 130 /** A flag to indicate a bound property. */ 131 private boolean _bound = false; 132 /** A flag to indicate a container field. */ 133 private boolean _isContainer = false; 134 /** 135 * The fully qualified name of the XMLFieldHandler (if any) 136 * to use in the generated descriptor. 137 */ 138 private String _fieldHandler; 139 /** A boolean to indicate that this field represents a "nillable" field. */ 140 private boolean _nillable = false; 141 /** The fully qualified name of the Validator (if any) to use in the generated descriptor. */ 142 private String _validator; 143 /** Visibility of this FieldInfo. */ 144 private String _visibility = "private"; 145 146 /** 147 * Factory responsible for creating a {@link JField} out of a 148 * {@link FieldInfo}. 149 */ 150 private FieldMemberAndAccessorFactory _memberAndAccessorFactory; 151 152 /** 153 * Holds the possible substitution groups for this class. 154 */ 155 private List<String> _substitutionGroupMembers = new LinkedList<String>(); 156 157 /** 158 * Creates a new FieldInfo with the given XML Schema type and the given 159 * member name. Adds the {@link XMLInfoNature} for legacy compliance. 160 * 161 * @param type 162 * the XML Schema type of this member 163 * @param name 164 * the name of the member 165 * @param memberAndAccessorFactory 166 * the FieldMemberAndAccessorFactory to be used 167 */ 168 public FieldInfo(final XSType type, final String name, 169 final FieldMemberAndAccessorFactory memberAndAccessorFactory) { 170 this._name = name; 171 this._memberAndAccessorFactory = memberAndAccessorFactory; 172 this.addNature(XMLInfoNature.class.getName()); 173 XMLInfoNature xmlNature = new XMLInfoNature(this); 174 xmlNature.setSchemaType(type); 175 } //-- FieldInfo 176 177 178 /** 179 * Returns the FieldMemberAndAccessorFactory instance to use to create 180 * a JField out of this FieldInfo. 181 * @return the suitable FieldMemberAndAccessorFactory 182 */ 183 public FieldMemberAndAccessorFactory getMemberAndAccessorFactory() { 184 return _memberAndAccessorFactory; 185 } 186 187 /** 188 * Returns the default value for this FieldInfo. 189 * 190 * @return the default value for this FieldInfo, or null if no default value 191 * was set; 192 */ 193 public final String getDefaultValue() { 194 return _default; 195 } 196 197 /** 198 * Returns the fixed production for this FieldInfo, or null if no fixed 199 * value has been specified. 200 * <p> 201 * NOTE: Fixed values are NOT the same as default values 202 * 203 * @return the fixed value for this FieldInfo 204 */ 205 public final String getFixedValue() { 206 return _fixed; 207 } 208 209 /** 210 * Returns the name of the delete method for this FieldInfo. 211 * @return the name of the delete method for this FieldInfo. 212 */ 213 public final String getDeleteMethodName() { 214 return METHOD_PREFIX_DELETE + getMethodSuffix(); 215 } //-- getDeleteMethodName 216 217 /** 218 * Returns the name of the has method for this FieldInfo. 219 * @return the name of the has method for this FieldInfo. 220 */ 221 public final String getHasMethodName() { 222 return METHOD_PREFIX_HAS + getMethodSuffix(); 223 } //-- getHasMethodName 224 225 /** 226 * Returns the name of the read method for this FieldInfo. 227 * @return the name of the read method for this FieldInfo. 228 */ 229 public final String getReadMethodName() { 230 return METHOD_PREFIX_GET + getMethodSuffix(); 231 } //-- getReadMethodName 232 233 /** 234 * Returns the fully qualified name of the Validator to use. 235 * 236 * @return the fully qualified name of the Validator to use. 237 */ 238 public final String getValidator() { 239 return _validator; 240 } 241 242 /** 243 * Returns the name of the write method for this FieldInfo. 244 * @return the name of the write method for this FieldInfo. 245 */ 246 public final String getWriteMethodName() { 247 if (new XMLInfoNature(this).isMultivalued()) { 248 return METHOD_PREFIX_ADD + getMethodSuffix(); 249 } 250 return METHOD_PREFIX_SET + getMethodSuffix(); 251 } //-- getWriteMethodName 252 253 /** 254 * Get the 'is' method for this FieldInfo. 255 * 256 * @return the name of the 'is' method for this FieldInfo 257 */ 258 public final String getIsMethodName() { 259 return METHOD_PREFIX_IS + getMethodSuffix(); 260 } 261 262 /** 263 * Returns the fully qualified name of the XMLFieldHandler to use. 264 * 265 * @return the fully qualified name of the XMLFieldHandler to use. 266 */ 267 public final String getXMLFieldHandler() { 268 return _fieldHandler; 269 } 270 271 /** 272 * Returns the comment associated with this Member. 273 * 274 * @return the comment associated with this Member, or null. 275 * if one has not been set. 276 */ 277 public final String getComment() { 278 return _comment; 279 } //-- getComment 280 281 /** 282 * Returns the methods flag that indicates which. 283 * 284 * methods will be created. 285 * 286 * @return the methods flag 287 */ 288 public final int getMethods() { 289 return _methods; 290 } //-- getMethods 291 292 /** 293 * Returns the name of this FieldInfo. 294 * 295 * @return the name of this FieldInfo. 296 */ 297 public final String getName() { 298 return this._name; 299 } //-- getName 300 301 /** 302 * Returns true if this FieldInfo represents a bound property. 303 * 304 * @return true if this FieldInfo represents a bound property. 305 */ 306 public final boolean isBound() { 307 return _bound; 308 } //-- isBound 309 310 /** 311 * Returns true if this FieldInfo describes a container class. A container 312 * class is a class which should not be marshalled as XML, but whose members 313 * should be. 314 * 315 * @return true if this ClassInfo describes a container class. 316 */ 317 public final boolean isContainer() { 318 return _isContainer; 319 } //-- isContainer 320 321 /** 322 * Returns true if the "has" and "delete" methods are needed for the field 323 * associated with this FieldInfo. 324 * 325 * @return true if the has and delete methods are needed. 326 */ 327 public final boolean requiresHasAndDeleteMethods() { 328 XSType xsType = new XMLInfoNature(this).getSchemaType(); 329 JType jType = xsType.getJType(); 330 return ((!xsType.isEnumerated()) && jType.isPrimitive()); 331 } //-- requiresHasAndDeleteMethods 332 333 /** 334 * Returns true if this field represents a nillable field. A nillable field 335 * is a field that can have null content (see XML Schema 1.0 definition of 336 * nillable). 337 * 338 * @return true if nillable, otherwise false. 339 * @see #setNillable(boolean) 340 */ 341 public final boolean isNillable() { 342 return _nillable; 343 } //-- isNillable 344 345 /** 346 * Returns true if this FieldInfo is a transient member. Transient members 347 * are members which should be ignored by the Marshalling framework. 348 * 349 * @return true if this FieldInfo is transient. 350 */ 351 public final boolean isTransient() { 352 return (_transient || _final || _static); 353 } //-- isTransient 354 355 /** 356 * Sets the comment for this Member. 357 * @param comment the comment or description for this Member 358 */ 359 public final void setComment(final String comment) { 360 _comment = comment; 361 } //-- setComment 362 363 /** 364 * Returns the ClassInfo to which this Member was declared, for inheritance reasons. 365 * @return the ClassInfo to which this Member was declared. 366 */ 367 public final ClassInfo getDeclaringClassInfo() { 368 return this._declaringClassInfo; 369 } //-- getDeclaringClassInfo 370 371 /** 372 * Sets whether or not this FieldInfo represents a bound property. 373 * 374 * @param bound the flag when true indicates that this FieldInfo represents a 375 * bound property. 376 */ 377 public final void setBound(final boolean bound) { 378 _bound = bound; 379 } //-- setBound 380 381 /** 382 * Sets whether or not this FieldInfo describes a container field. A 383 * container field is a field which should not be marshalled directly as 384 * XML, but whose members should be. By default this is false. 385 * 386 * @param isContainer 387 * the boolean value when true indicates this class should be a 388 * container class. 389 */ 390 public final void setContainer(final boolean isContainer) { 391 _isContainer = isContainer; 392 } //-- setContainer 393 394 /** 395 * Sets the {@link ClassInfo} of the class that declares this field. 396 * @param declaringClassInfo The {@link ClassInfo} of the declaring class. 397 */ 398 public final void setDeclaringClassInfo(final ClassInfo declaringClassInfo) { 399 this._declaringClassInfo = declaringClassInfo; 400 } 401 402 /** 403 * Sets the default value for this FieldInfo. 404 * @param defaultValue the default value 405 */ 406 public final void setDefaultValue(final String defaultValue) { 407 this._default = defaultValue; 408 } 409 410 /** 411 * Sets the "final" status of this FieldInfo. Final members are also 412 * transient. 413 * 414 * @param isFinal 415 * the boolean indicating the final status, if true this 416 * FieldInfo will be treated as final. 417 */ 418 public final void setFinal(final boolean isFinal) { 419 this._final = isFinal; 420 } //-- isFinal 421 422 /** 423 * Sets the fixed value in which instances of this field type must lexically 424 * match. NOTE: This is not the same as default value! 425 * 426 * @param fixedValue 427 * the fixed production for this FieldInfo 428 */ 429 public final void setFixedValue(final String fixedValue) { 430 this._fixed = fixedValue; 431 } //-- setFixedValue 432 433 /** 434 * Sets which methods to create: READ_METHOD, WRITE_METHOD, 435 * READ_WRITE_METHODS. 436 * 437 * @param methods a flag describing which methods to create. 438 */ 439 public final void setMethods(final int methods) { 440 _methods = methods; 441 } //-- setMethods 442 443 /** 444 * Sets whether or not this field can be nillable. 445 * 446 * @param nillable 447 * a boolean that when true means the field may be nil. 448 * @see #isNillable() 449 */ 450 public final void setNillable(final boolean nillable) { 451 _nillable = nillable; 452 } //-- setNillable 453 454 /** 455 * Sets the name of the field within the same class that is a reference to 456 * this field. 457 * 458 * @param fieldInfo {@link FieldInfo} for the referencing field (within the same class). 459 */ 460 public final void setFieldInfoReference(final FieldInfo fieldInfo) { 461 _fieldInfoReference = fieldInfo; 462 } 463 464 /** 465 * Sets the "static" status of this FieldInfo. Static members are also 466 * transient. 467 * 468 * @param isStatic the boolean indicating the static status, if true this 469 * FieldInfo will be treated as static 470 */ 471 public final void setStatic(final boolean isStatic) { 472 this._static = isStatic; 473 } //-- setStatic 474 475 /** 476 * Sets the transient status of this FieldInfo. 477 * 478 * @param isTransient the boolean indicating the transient status, if true this 479 * FieldInfo will be treated as transient 480 */ 481 public final void setTransient(final boolean isTransient) { 482 this._transient = isTransient; 483 } //-- setTransient 484 485 /** 486 * Sets the name of the Validator to use. 487 * 488 * @param validator the fully qualified name of the validator to use. 489 */ 490 public final void setValidator(final String validator) { 491 _validator = validator; 492 } 493 494 /** 495 * Sets the name of the XMLfieldHandler to use. 496 * 497 * @param handler the fully qualified name of the handler to use. 498 */ 499 public final void setXMLFieldHandler(final String handler) { 500 _fieldHandler = handler; 501 } 502 503 /** 504 * Returns the method suffix for creating method names. 505 * 506 * @return the method suffix used when creating method names. 507 */ 508 public String getMethodSuffix() { 509 if (_name.startsWith("_")) { 510 return _memberAndAccessorFactory.getJavaNaming().toJavaClassName(_name.substring(1)); 511 } 512 return _memberAndAccessorFactory.getJavaNaming().toJavaClassName(_name); 513 } 514 515 /** 516 * Sets the visibility of this FieldInfo. 517 * 518 * @param visibility the visibility of this FieldInfo. 519 */ 520 public final void setVisibility(final String visibility) { 521 _visibility = visibility; 522 } 523 524 /** 525 * Sets the possible substitution groups for this class. 526 * @param substitutionGroupMembers Possible substitution groups for this class. 527 */ 528 public void setSubstitutionGroupMembers(final List<String> substitutionGroupMembers) { 529 this._substitutionGroupMembers = substitutionGroupMembers; 530 } 531 532 /** 533 * Returns the possible substitution groups for this class. 534 * @return the possible substitution groups for this class. 535 */ 536 public List<String> getSubstitutionGroupMembers() { 537 return this._substitutionGroupMembers; 538 } 539 540 /** 541 * Indicates whether this field is static. 542 * @return True if this field is static. 543 */ 544 public boolean isStatic() { 545 return _static; 546 } 547 548 /** 549 * Indicates whether this field is final. 550 * @return True if this field is final. 551 */ 552 public boolean isFinal() { 553 return _final; 554 } 555 556 /** 557 * Returns this field's 'visibility'. 558 * @return This field's visibility. 559 */ 560 public Object getVisibility() { 561 return _visibility; 562 } 563 564 /** 565 * Returns the reference to the {@link FieldInfo} instance within the same class. 566 * @return the reference to the {@link FieldInfo} instance 567 */ 568 public FieldInfo getFieldInfoReference() { 569 return _fieldInfoReference; 570 } 571 572 /** 573 * @see org.exolab.castor.builder.info.nature.PropertyHolder# 574 * getProperty(java.lang.String) 575 * @param name 576 * of the property 577 * @return value of the property 578 */ 579 public final Object getProperty(final String name) { 580 return _properties.get(name); 581 } 582 583 /** 584 * @see org.exolab.castor.builder.info.nature.PropertyHolder# 585 * setProperty(java.lang.String, java.lang.Object) 586 * @param name 587 * of the property 588 * @param value 589 * of the property 590 */ 591 public final void setProperty(final String name, final Object value) { 592 _properties.put(name, value); 593 } 594 595 /** 596 * @see org.exolab.castor.builder.info.nature.NatureExtendable# 597 * addNature(java.lang.String) 598 * @param nature 599 * ID of the Nature 600 */ 601 public final void addNature(final String nature) { 602 _natures.add(nature); 603 } 604 605 /** 606 * @see org.exolab.castor.builder.info.nature.NatureExtendable# 607 * hasNature(java.lang.String) 608 * @param nature 609 * ID of the Nature 610 * @return true if the Nature ID was added. 611 */ 612 public final boolean hasNature(final String nature) { 613 return _natures.contains(nature); 614 } 615 616 }