/* * Redistribution and use of this software and associated documentation * ("Software"), with or without modification, are permitted provided * that the following conditions are met: * * 1. Redistributions of source code must retain copyright * statements and notices. Redistributions must also contain a * copy of this document. * * 2. Redistributions in binary form must reproduce the * above copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other * materials provided with the distribution. * * 3. The name "Exolab" must not be used to endorse or promote * products derived from this Software without prior written * permission of Intalio, Inc. For written permission, * please contact info@exolab.org. * * 4. Products derived from this Software may not be called "Exolab" * nor may "Exolab" appear in their names without prior written * permission of Intalio, Inc. Exolab is a registered * trademark of Intalio, Inc. * * 5. Due credit should be given to the Exolab Project * (http://www.exolab.org/). * * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 1999-2004 (C) Intalio, Inc. All Rights Reserved. * * This file was originally developed by Keith Visco during the course * of employment at Intalio Inc. * Portions of this file developed by Keith Visco after Jan 19 2005 are * Copyright (C) 2005 Keith Visco. All Rights Reserverd. * * $Id$ */ package org.exolab.castor.builder.info; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.castor.core.nature.PropertyHolder; import org.exolab.castor.builder.factory.FieldMemberAndAccessorFactory; import org.exolab.castor.builder.info.nature.XMLInfoNature; import org.exolab.castor.builder.types.XSType; import org.exolab.javasource.JType; /** * A class for representing field members of a class. FieldInfo objects hold all * the information required about a member in order to be able to produce * XML data binding (marshal/unmarshal) and validation code. * * @author <a href="mailto:keith AT kvisco DOT com">Keith Visco</a> * @version $Revision$ $Date: 2006-04-25 15:08:23 -0600 (Tue, 25 Apr 2006) $ */ public class FieldInfo implements XMLInfo, PropertyHolder { /** * Map holding the properties set and read by Natures. */ private Map<String, Object> _properties = new HashMap<String, Object>(); /** * Set holding applicable natures. */ private Set<String> _natures = new HashSet<String>(); /** The Read / Getter method flag. */ public static final int READ_METHOD = 1; /** The Write / Setter method flag. */ public static final int WRITE_METHOD = 2; /** The Read and Write methods flags. */ public static final int READ_WRITE_METHODS = 3; /** Method prefixes for "Add" methods. */ protected static final String METHOD_PREFIX_ADD = "add"; /** Method prefixes for "Delete" methods. */ protected static final String METHOD_PREFIX_DELETE = "delete"; /** Method prefixes for "Get" methods. */ protected static final String METHOD_PREFIX_GET = "get"; /** Method prefixes for "Has" methods. */ protected static final String METHOD_PREFIX_HAS = "has"; /** Method prefixes for "Set" methods. */ protected static final String METHOD_PREFIX_SET = "set"; /** Method prefixes for "Is" methods. */ protected static final String METHOD_PREFIX_IS = "is"; /** The Java name for Members described by this FieldInfo. */ private String _name = null; /** * {@link ClassInfo} instance which 'own' (declares) this * {@link FieldInfo}. */ private ClassInfo _declaringClassInfo = null; /** JavaDoc comment. */ private String _comment = null; /** The default value for this FieldInfo. */ private String _default = null; /** The fixed production for this FieldInfo. */ private String _fixed = null; /** A flag to indicate a final member. */ private boolean _final = false; /** The methods flags, indicates which methods to create. */ private int _methods = READ_WRITE_METHODS; /** A reference to the FieldInfo instance within the same class. */ private FieldInfo _fieldInfoReference = null; /** A flag to indicate a static member. */ private boolean _static = false; /** Flags whether or not the a MarshalDescriptor should be created for this FieldInfo. */ private boolean _transient = false; /** A flag to indicate a bound property. */ private boolean _bound = false; /** A flag to indicate a container field. */ private boolean _isContainer = false; /** * The fully qualified name of the XMLFieldHandler (if any) * to use in the generated descriptor. */ private String _fieldHandler; /** A boolean to indicate that this field represents a "nillable" field. */ private boolean _nillable = false; /** The fully qualified name of the Validator (if any) to use in the generated descriptor. */ private String _validator; /** Visibility of this FieldInfo. */ private String _visibility = "private"; /** * Factory responsible for creating a {@link JField} out of a * {@link FieldInfo}. */ private FieldMemberAndAccessorFactory _memberAndAccessorFactory; /** * Holds the possible substitution groups for this class. */ private List<String> _substitutionGroupMembers = new LinkedList<String>(); /** * Creates a new FieldInfo with the given XML Schema type and the given * member name. Adds the {@link XMLInfoNature} for legacy compliance. * * @param type * the XML Schema type of this member * @param name * the name of the member * @param memberAndAccessorFactory * the FieldMemberAndAccessorFactory to be used */ public FieldInfo(final XSType type, final String name, final FieldMemberAndAccessorFactory memberAndAccessorFactory) { this._name = name; this._memberAndAccessorFactory = memberAndAccessorFactory; this.addNature(XMLInfoNature.class.getName()); XMLInfoNature xmlNature = new XMLInfoNature(this); xmlNature.setSchemaType(type); } //-- FieldInfo /** * Returns the FieldMemberAndAccessorFactory instance to use to create * a JField out of this FieldInfo. * @return the suitable FieldMemberAndAccessorFactory */ public FieldMemberAndAccessorFactory getMemberAndAccessorFactory() { return _memberAndAccessorFactory; } /** * Returns the default value for this FieldInfo. * * @return the default value for this FieldInfo, or null if no default value * was set; */ public final String getDefaultValue() { return _default; } /** * Returns the fixed production for this FieldInfo, or null if no fixed * value has been specified. * <p> * NOTE: Fixed values are NOT the same as default values * * @return the fixed value for this FieldInfo */ public final String getFixedValue() { return _fixed; } /** * Returns the name of the delete method for this FieldInfo. * @return the name of the delete method for this FieldInfo. */ public final String getDeleteMethodName() { return METHOD_PREFIX_DELETE + getMethodSuffix(); } //-- getDeleteMethodName /** * Returns the name of the has method for this FieldInfo. * @return the name of the has method for this FieldInfo. */ public final String getHasMethodName() { return METHOD_PREFIX_HAS + getMethodSuffix(); } //-- getHasMethodName /** * Returns the name of the read method for this FieldInfo. * @return the name of the read method for this FieldInfo. */ public final String getReadMethodName() { return METHOD_PREFIX_GET + getMethodSuffix(); } //-- getReadMethodName /** * Returns the fully qualified name of the Validator to use. * * @return the fully qualified name of the Validator to use. */ public final String getValidator() { return _validator; } /** * Returns the name of the write method for this FieldInfo. * @return the name of the write method for this FieldInfo. */ public final String getWriteMethodName() { if (new XMLInfoNature(this).isMultivalued()) { return METHOD_PREFIX_ADD + getMethodSuffix(); } return METHOD_PREFIX_SET + getMethodSuffix(); } //-- getWriteMethodName /** * Get the 'is' method for this FieldInfo. * * @return the name of the 'is' method for this FieldInfo */ public final String getIsMethodName() { return METHOD_PREFIX_IS + getMethodSuffix(); } /** * Returns the fully qualified name of the XMLFieldHandler to use. * * @return the fully qualified name of the XMLFieldHandler to use. */ public final String getXMLFieldHandler() { return _fieldHandler; } /** * Returns the comment associated with this Member. * * @return the comment associated with this Member, or null. * if one has not been set. */ public final String getComment() { return _comment; } //-- getComment /** * Returns the methods flag that indicates which. * * methods will be created. * * @return the methods flag */ public final int getMethods() { return _methods; } //-- getMethods /** * Returns the name of this FieldInfo. * * @return the name of this FieldInfo. */ public final String getName() { return this._name; } //-- getName /** * Returns true if this FieldInfo represents a bound property. * * @return true if this FieldInfo represents a bound property. */ public final boolean isBound() { return _bound; } //-- isBound /** * Returns true if this FieldInfo describes a container class. A container * class is a class which should not be marshalled as XML, but whose members * should be. * * @return true if this ClassInfo describes a container class. */ public final boolean isContainer() { return _isContainer; } //-- isContainer /** * Returns true if the "has" and "delete" methods are needed for the field * associated with this FieldInfo. * * @return true if the has and delete methods are needed. */ public final boolean requiresHasAndDeleteMethods() { XSType xsType = new XMLInfoNature(this).getSchemaType(); JType jType = xsType.getJType(); return ((!xsType.isEnumerated()) && jType.isPrimitive()); } //-- requiresHasAndDeleteMethods /** * Returns true if this field represents a nillable field. A nillable field * is a field that can have null content (see XML Schema 1.0 definition of * nillable). * * @return true if nillable, otherwise false. * @see #setNillable(boolean) */ public final boolean isNillable() { return _nillable; } //-- isNillable /** * Returns true if this FieldInfo is a transient member. Transient members * are members which should be ignored by the Marshalling framework. * * @return true if this FieldInfo is transient. */ public final boolean isTransient() { return (_transient || _final || _static); } //-- isTransient /** * Sets the comment for this Member. * @param comment the comment or description for this Member */ public final void setComment(final String comment) { _comment = comment; } //-- setComment /** * Returns the ClassInfo to which this Member was declared, for inheritance reasons. * @return the ClassInfo to which this Member was declared. */ public final ClassInfo getDeclaringClassInfo() { return this._declaringClassInfo; } //-- getDeclaringClassInfo /** * Sets whether or not this FieldInfo represents a bound property. * * @param bound the flag when true indicates that this FieldInfo represents a * bound property. */ public final void setBound(final boolean bound) { _bound = bound; } //-- setBound /** * Sets whether or not this FieldInfo describes a container field. A * container field is a field which should not be marshalled directly as * XML, but whose members should be. By default this is false. * * @param isContainer * the boolean value when true indicates this class should be a * container class. */ public final void setContainer(final boolean isContainer) { _isContainer = isContainer; } //-- setContainer /** * Sets the {@link ClassInfo} of the class that declares this field. * @param declaringClassInfo The {@link ClassInfo} of the declaring class. */ public final void setDeclaringClassInfo(final ClassInfo declaringClassInfo) { this._declaringClassInfo = declaringClassInfo; } /** * Sets the default value for this FieldInfo. * @param defaultValue the default value */ public final void setDefaultValue(final String defaultValue) { this._default = defaultValue; } /** * Sets the "final" status of this FieldInfo. Final members are also * transient. * * @param isFinal * the boolean indicating the final status, if true this * FieldInfo will be treated as final. */ public final void setFinal(final boolean isFinal) { this._final = isFinal; } //-- isFinal /** * Sets the fixed value in which instances of this field type must lexically * match. NOTE: This is not the same as default value! * * @param fixedValue * the fixed production for this FieldInfo */ public final void setFixedValue(final String fixedValue) { this._fixed = fixedValue; } //-- setFixedValue /** * Sets which methods to create: READ_METHOD, WRITE_METHOD, * READ_WRITE_METHODS. * * @param methods a flag describing which methods to create. */ public final void setMethods(final int methods) { _methods = methods; } //-- setMethods /** * Sets whether or not this field can be nillable. * * @param nillable * a boolean that when true means the field may be nil. * @see #isNillable() */ public final void setNillable(final boolean nillable) { _nillable = nillable; } //-- setNillable /** * Sets the name of the field within the same class that is a reference to * this field. * * @param fieldInfo {@link FieldInfo} for the referencing field (within the same class). */ public final void setFieldInfoReference(final FieldInfo fieldInfo) { _fieldInfoReference = fieldInfo; } /** * Sets the "static" status of this FieldInfo. Static members are also * transient. * * @param isStatic the boolean indicating the static status, if true this * FieldInfo will be treated as static */ public final void setStatic(final boolean isStatic) { this._static = isStatic; } //-- setStatic /** * Sets the transient status of this FieldInfo. * * @param isTransient the boolean indicating the transient status, if true this * FieldInfo will be treated as transient */ public final void setTransient(final boolean isTransient) { this._transient = isTransient; } //-- setTransient /** * Sets the name of the Validator to use. * * @param validator the fully qualified name of the validator to use. */ public final void setValidator(final String validator) { _validator = validator; } /** * Sets the name of the XMLfieldHandler to use. * * @param handler the fully qualified name of the handler to use. */ public final void setXMLFieldHandler(final String handler) { _fieldHandler = handler; } /** * Returns the method suffix for creating method names. * * @return the method suffix used when creating method names. */ public String getMethodSuffix() { if (_name.startsWith("_")) { return _memberAndAccessorFactory.getJavaNaming().toJavaClassName(_name.substring(1)); } return _memberAndAccessorFactory.getJavaNaming().toJavaClassName(_name); } /** * Sets the visibility of this FieldInfo. * * @param visibility the visibility of this FieldInfo. */ public final void setVisibility(final String visibility) { _visibility = visibility; } /** * Sets the possible substitution groups for this class. * @param substitutionGroupMembers Possible substitution groups for this class. */ public void setSubstitutionGroupMembers(final List<String> substitutionGroupMembers) { this._substitutionGroupMembers = substitutionGroupMembers; } /** * Returns the possible substitution groups for this class. * @return the possible substitution groups for this class. */ public List<String> getSubstitutionGroupMembers() { return this._substitutionGroupMembers; } /** * Indicates whether this field is static. * @return True if this field is static. */ public boolean isStatic() { return _static; } /** * Indicates whether this field is final. * @return True if this field is final. */ public boolean isFinal() { return _final; } /** * Returns this field's 'visibility'. * @return This field's visibility. */ public Object getVisibility() { return _visibility; } /** * Returns the reference to the {@link FieldInfo} instance within the same class. * @return the reference to the {@link FieldInfo} instance */ public FieldInfo getFieldInfoReference() { return _fieldInfoReference; } /** * @see org.exolab.castor.builder.info.nature.PropertyHolder# * getProperty(java.lang.String) * @param name * of the property * @return value of the property */ public final Object getProperty(final String name) { return _properties.get(name); } /** * @see org.exolab.castor.builder.info.nature.PropertyHolder# * setProperty(java.lang.String, java.lang.Object) * @param name * of the property * @param value * of the property */ public final void setProperty(final String name, final Object value) { _properties.put(name, value); } /** * @see org.exolab.castor.builder.info.nature.NatureExtendable# * addNature(java.lang.String) * @param nature * ID of the Nature */ public final void addNature(final String nature) { _natures.add(nature); } /** * @see org.exolab.castor.builder.info.nature.NatureExtendable# * hasNature(java.lang.String) * @param nature * ID of the Nature * @return true if the Nature ID was added. */ public final boolean hasNature(final String nature) { return _natures.contains(nature); } }