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