KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > plugins > cmp > jdbc > metadata > JDBCCMPFieldMetaData


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ejb.plugins.cmp.jdbc.metadata;
23
24 import java.lang.reflect.Field JavaDoc;
25 import java.lang.reflect.Method JavaDoc;
26 import java.lang.reflect.Modifier JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Collections JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31
32 import org.jboss.deployment.DeploymentException;
33 import org.jboss.metadata.MetaData;
34
35 import org.w3c.dom.Element JavaDoc;
36
37 /**
38  * Imutable class which holds all the information jbosscmp-jdbc needs to know
39  * about a CMP field It loads its data from standardjbosscmp-jdbc.xml and
40  * jbosscmp-jdbc.xml
41  *
42  * @author <a HREF="mailto:dain@daingroup.com">Dain Sundstrom</a>
43  * @author <a HREF="sebastien.alborini@m4x.org">Sebastien Alborini</a>
44  * @author <a HREF="mailto:dirk@jboss.de">Dirk Zimmermann</a>
45  * @author <a HREF="mailto:vincent.harcq@hubmethods.com">Vincent Harcq</a>
46  * @author <a HREF="mailto:loubyansky@hotmail.com">Alex Loubyansky</a>
47  * @author <a HREF="mailto:heiko.rupp@cellent.de">Heiko W.Rupp</a>
48  *
49  * @version $Revision: 37459 $
50  */

51 public final class JDBCCMPFieldMetaData
52 {
53    public static final byte CHECK_DIRTY_AFTER_GET_TRUE = 1;
54    public static final byte CHECK_DIRTY_AFTER_GET_FALSE = 2;
55    public static final byte CHECK_DIRTY_AFTER_GET_NOT_PRESENT = 4;
56
57    /** The entity on which this field is defined. */
58    private final JDBCEntityMetaData entity;
59
60    /** The name of this field. */
61    private final String JavaDoc fieldName;
62
63    /** The java type of this field */
64    private final Class JavaDoc fieldType;
65
66    /** The column name in the table */
67    private final String JavaDoc columnName;
68
69    /**
70     * The jdbc type (see java.sql.Types), used in PreparedStatement.setParameter
71     * default value used is intended to cause an exception if used
72     */

73    private final int jdbcType;
74
75    /** The sql type, used for table creation. */
76    private final String JavaDoc sqlType;
77
78    /** Is this field read only? */
79    private final boolean readOnly;
80
81    /** How long is read valid */
82    private final int readTimeOut;
83
84    /** Is this field a memeber of the primary keys or the sole prim-key-field. */
85    private final boolean primaryKeyMember;
86
87    /** Should null values not be allowed for this field. */
88    private final boolean notNull;
89
90    /** Should an index for this field be generated? */
91    private final boolean genIndex;
92
93    /**
94     * The Field object in the primary key class for this
95     * cmp field, or null if this field is the prim-key-field.
96     */

97    private final Field JavaDoc primaryKeyField;
98
99    /** property overrides */
100    private final List JavaDoc propertyOverrides = new ArrayList JavaDoc();
101
102    /** indicates whether this is an unknown pk field */
103    private final boolean unknownPkField;
104
105    /** auto-increment flag */
106    private final boolean autoIncrement;
107
108    /** whether this field is a relation table key field*/
109    private final boolean relationTableField;
110
111    /** If true, the field should be checked for dirty state after its get method was invoked */
112    private final byte checkDirtyAfterGet;
113
114    /** Fully qualified class name of implementation of CMPFieldStateFactory */
115    private final String JavaDoc stateFactory;
116
117    private static byte readCheckDirtyAfterGet(Element JavaDoc element, byte defaultValue) throws DeploymentException
118    {
119       byte checkDirtyAfterGet;
120       String JavaDoc dirtyAfterGetStr = MetaData.getOptionalChildContent(element, "check-dirty-after-get");
121       if(dirtyAfterGetStr == null)
122       {
123          checkDirtyAfterGet = defaultValue;
124       }
125       else
126       {
127          checkDirtyAfterGet = (Boolean.valueOf(dirtyAfterGetStr).booleanValue() ?
128             CHECK_DIRTY_AFTER_GET_TRUE : CHECK_DIRTY_AFTER_GET_FALSE);
129       }
130       return checkDirtyAfterGet;
131    }
132
133    public static byte readCheckDirtyAfterGet(Element JavaDoc element) throws DeploymentException
134    {
135       return readCheckDirtyAfterGet(element, CHECK_DIRTY_AFTER_GET_NOT_PRESENT);
136    }
137
138    /**
139     * This constructor is added especially for unknown primary key field
140     */

141    public JDBCCMPFieldMetaData(JDBCEntityMetaData entity)
142    {
143       this.entity = entity;
144       fieldName = entity.getName() + "_upk";
145       fieldType = entity.getPrimaryKeyClass(); // java.lang.Object.class
146
columnName = entity.getName() + "_upk";
147       jdbcType = Integer.MIN_VALUE;
148       sqlType = null;
149       readOnly = entity.isReadOnly();
150       readTimeOut = entity.getReadTimeOut();
151       primaryKeyMember = true;
152       notNull = true;
153       primaryKeyField = null;
154       genIndex = false;
155       unknownPkField = true;
156       autoIncrement = false;
157       relationTableField = false;
158       checkDirtyAfterGet = CHECK_DIRTY_AFTER_GET_NOT_PRESENT;
159       stateFactory = null;
160    }
161
162    /**
163     * Constructs cmp field meta data for a field on the specified entity with
164     * the specified fieldName.
165     *
166     * @param fieldName name of the field for which the meta data will be loaded
167     * @param entity entity on which this field is defined
168     * @throws DeploymentException if data in the entity is inconsistent with field type
169     */

170    public JDBCCMPFieldMetaData(JDBCEntityMetaData entity, String JavaDoc fieldName)
171       throws DeploymentException
172    {
173       this.entity = entity;
174       this.fieldName = fieldName;
175
176       fieldType = loadFieldType(entity, fieldName);
177       columnName = fieldName;
178       jdbcType = Integer.MIN_VALUE;
179       sqlType = null;
180       readOnly = entity.isReadOnly();
181       readTimeOut = entity.getReadTimeOut();
182       genIndex = false;
183
184       // initialize primary key info
185
String JavaDoc pkFieldName = entity.getPrimaryKeyFieldName();
186       if(pkFieldName != null)
187       {
188          // single-valued key so field is null
189
primaryKeyField = null;
190
191          // is this the pk field
192
if(pkFieldName.equals(fieldName))
193          {
194             // verify field type
195
if(!entity.getPrimaryKeyClass().equals(fieldType))
196             {
197                throw new DeploymentException("primkey-field must be the same type as prim-key-class");
198             }
199             // we are the pk
200
primaryKeyMember = true;
201          }
202          else
203          {
204             primaryKeyMember = false;
205          }
206       }
207       else
208       {
209          // this is a multi-valued key
210
Field JavaDoc[] fields = entity.getPrimaryKeyClass().getFields();
211
212          boolean pkMember = false;
213          Field JavaDoc pkField = null;
214          for(int i = 0; i < fields.length; i++)
215          {
216             final Field JavaDoc field = fields[i];
217             if(field.getName().equals(fieldName))
218             {
219
220                // verify field type
221
if(!field.getType().equals(fieldType))
222                {
223                   throw new DeploymentException("Field " + fieldName + " in prim-key-class must be of the same type.");
224                }
225
226                if(pkField != null)
227                {
228                   if(field.getDeclaringClass().equals(entity.getPrimaryKeyClass()))
229                   {
230                      pkField = field;
231                   }
232
233                   org.jboss.logging.Logger.getLogger(getClass().getName() + '.' + entity.getName()).warn(
234                      "PK field " + fieldName + " was found more than once in class hierarchy of " +
235                      entity.getPrimaryKeyClass().getName() + ". Will use the one from " + pkField.getDeclaringClass().getName()
236                   );
237                }
238                else
239                {
240                   pkField = field;
241                }
242
243                // we are a pk member
244
pkMember = true;
245             }
246          }
247          primaryKeyMember = pkMember;
248          primaryKeyField = pkField;
249       }
250       notNull = fieldType.isPrimitive() || primaryKeyMember;
251
252       unknownPkField = false;
253       autoIncrement = false;
254       relationTableField = false;
255       checkDirtyAfterGet = CHECK_DIRTY_AFTER_GET_NOT_PRESENT;
256       stateFactory = null;
257    }
258
259    public JDBCCMPFieldMetaData(JDBCEntityMetaData entity,
260                                JDBCCMPFieldMetaData defaultValues)
261    {
262       this.entity = entity;
263       fieldName = defaultValues.getFieldName();
264       fieldType = defaultValues.getFieldType();
265       columnName = defaultValues.getColumnName();
266       jdbcType = defaultValues.getJDBCType();
267       sqlType = defaultValues.getSQLType();
268       readOnly = entity.isReadOnly();
269       readTimeOut = entity.getReadTimeOut();
270       primaryKeyMember = defaultValues.isPrimaryKeyMember();
271       primaryKeyField = defaultValues.getPrimaryKeyField();
272       notNull = defaultValues.isNotNull();
273       unknownPkField = defaultValues.isUnknownPkField();
274       autoIncrement = defaultValues.isAutoIncrement();
275       genIndex = false; // If <dbindex/> is not given on a field, no index is wanted.
276
relationTableField = defaultValues.isRelationTableField();
277       checkDirtyAfterGet = defaultValues.getCheckDirtyAfterGet();
278       stateFactory = defaultValues.getStateFactory();
279    }
280
281    /**
282     * Constructs cmp field meta data with the data contained in the cmp-field
283     * xml element from a jbosscmp-jdbc xml file. Optional values of the xml
284     * element that are not present are instead loaded from the defalutValues
285     * parameter.
286     *
287     * @param element the xml Element which contains the metadata about
288     * this field
289     * @param defaultValues the JDBCCMPFieldMetaData which contains the values
290     * for optional elements of the element
291     * @throws DeploymentException if the xml element is not semantically correct
292     */

293    public JDBCCMPFieldMetaData(JDBCEntityMetaData entity,
294                                Element JavaDoc element,
295                                JDBCCMPFieldMetaData defaultValues)
296       throws DeploymentException
297    {
298       this.entity = entity;
299
300       // unknown primary key
301
this.unknownPkField = defaultValues.isUnknownPkField();
302
303       // Field name
304
// if field-name is specified for unknown-pk, it's set here
305
String JavaDoc unknownFieldName =
306          MetaData.getOptionalChildContent(element, "field-name");
307       if(unknownPkField && unknownFieldName != null)
308       {
309          fieldName = unknownFieldName;
310       }
311       else
312       {
313          fieldName = defaultValues.getFieldName();
314       }
315
316       // Field type
317
// must be set for unknow-pk
318
String JavaDoc unknownPkClass = MetaData.getOptionalChildContent(element, "unknown-pk-class");
319       if(unknownPkClass == null)
320       {
321          fieldType = defaultValues.getFieldType();
322       }
323       else
324       {
325          try
326          {
327             fieldType = entity.getClassLoader().loadClass(unknownPkClass);
328          }
329          catch(ClassNotFoundException JavaDoc e)
330          {
331             throw new DeploymentException("could not load the class for "
332                + " unknown primary key: " + unknownPkClass);
333          }
334       }
335
336       // Column name
337
String JavaDoc columnStr = MetaData.getOptionalChildContent(element, "column-name");
338       if(columnStr != null)
339       {
340          columnName = columnStr;
341       }
342       else
343       {
344          columnName = defaultValues.getColumnName();
345       }
346
347       // JDBC Type
348
String JavaDoc jdbcStr = MetaData.getOptionalChildContent(element, "jdbc-type");
349       if(jdbcStr != null)
350       {
351          jdbcType = JDBCMappingMetaData.getJdbcTypeFromName(jdbcStr);
352          // SQL Type
353
sqlType = MetaData.getUniqueChildContent(element, "sql-type");
354       }
355       else
356       {
357          jdbcType = defaultValues.getJDBCType();
358          sqlType = defaultValues.getSQLType();
359       }
360
361       // read-only
362
String JavaDoc readOnlyStr = MetaData.getOptionalChildContent(element, "read-only");
363       if(readOnlyStr != null)
364       {
365          readOnly = Boolean.valueOf(readOnlyStr).booleanValue();
366       }
367       else
368       {
369          readOnly = defaultValues.isReadOnly();
370       }
371
372       // read-time-out
373
String JavaDoc readTimeOutStr = MetaData.getOptionalChildContent(element, "read-time-out");
374       if(readTimeOutStr != null)
375       {
376          try
377          {
378             readTimeOut = Integer.parseInt(readTimeOutStr);
379          }
380          catch(NumberFormatException JavaDoc e)
381          {
382             throw new DeploymentException("Invalid number format in " +
383                "read-time-out '" + readTimeOutStr + "': " + e);
384          }
385       }
386       else
387       {
388          readTimeOut = defaultValues.getReadTimeOut();
389       }
390
391       // primary key member?
392
this.primaryKeyMember = defaultValues.isPrimaryKeyMember();
393
394       // field object of the primary key
395
primaryKeyField = defaultValues.getPrimaryKeyField();
396
397       // not-null
398
Element JavaDoc notNullElement = MetaData.getOptionalChild(element, "not-null");
399       notNull =
400          fieldType.isPrimitive() ||
401          primaryKeyMember ||
402          (notNullElement != null);
403
404       // property overrides
405
Iterator JavaDoc iterator = MetaData.getChildrenByTagName(element, "property");
406       while(iterator.hasNext())
407       {
408          propertyOverrides.add(new JDBCCMPFieldPropertyMetaData(this, (Element JavaDoc)iterator.next()));
409       }
410
411       // is the field auto-increment?
412
autoIncrement = MetaData.getOptionalChild(element, "auto-increment") != null;
413
414       // should an index for this field be generated?
415
if(MetaData.getOptionalChild(element, "dbindex") == null)
416          genIndex = false;
417       else
418          genIndex = true;
419
420       relationTableField = defaultValues.isRelationTableField();
421
422       checkDirtyAfterGet = readCheckDirtyAfterGet(element, defaultValues.getCheckDirtyAfterGet());
423
424       String JavaDoc stateFactoryStr = MetaData.getOptionalChildContent(element, "state-factory");
425       if(stateFactoryStr == null)
426          stateFactory = defaultValues.getStateFactory();
427       else
428          stateFactory = stateFactoryStr;
429    }
430
431    /**
432     * Constructs cmp field meta data with the data contained in the cmp-field
433     * xml element from a jbosscmp-jdbc xml file. Optional values of the xml
434     * element that are not present are instead loaded from the defalutValues
435     * parameter.
436     *
437     * This constructor form is used to create cmp field meta data for use as
438     * foreign keys. The primaryKeyMember parameter is very important in this
439     * context because a foreign key is not a primary key member but used a pk
440     * member as the default value. If we did not have the primary key member
441     * parameter this JDBCCMPFieldMetaData would get the value from the
442     * defaultValues and be declared a memeber.
443     */

444    public JDBCCMPFieldMetaData(JDBCEntityMetaData entity,
445                                Element JavaDoc element,
446                                JDBCCMPFieldMetaData defaultValues,
447                                boolean primaryKeyMember,
448                                boolean notNull,
449                                boolean readOnly,
450                                int readTimeOut,
451                                boolean relationTableField)
452       throws DeploymentException
453    {
454       this.entity = entity;
455       fieldName = defaultValues.getFieldName();
456       fieldType = defaultValues.getFieldType();
457       String JavaDoc columnStr = MetaData.getOptionalChildContent(element, "column-name");
458       if(columnStr != null)
459       {
460          columnName = columnStr;
461       }
462       else
463       {
464          columnName = defaultValues.getColumnName();
465       }
466
467       // JDBC Type
468
String JavaDoc jdbcStr = MetaData.getOptionalChildContent(element, "jdbc-type");
469       if(jdbcStr != null)
470       {
471          jdbcType = JDBCMappingMetaData.getJdbcTypeFromName(jdbcStr);
472          sqlType = MetaData.getUniqueChildContent(element, "sql-type");
473       }
474       else
475       {
476          jdbcType = defaultValues.getJDBCType();
477          sqlType = defaultValues.getSQLType();
478       }
479
480       // read-only
481
this.readOnly = readOnly;
482
483       // read-time-out
484
this.readTimeOut = readTimeOut;
485
486       // primary key member?
487
this.primaryKeyMember = primaryKeyMember;
488
489       // not-null
490
this.notNull = notNull;
491
492       // field object of the primary key
493
primaryKeyField = defaultValues.getPrimaryKeyField();
494
495       // property overrides
496
Iterator JavaDoc iterator = MetaData.getChildrenByTagName(element, "property");
497       while(iterator.hasNext())
498       {
499          propertyOverrides.add(new JDBCCMPFieldPropertyMetaData(this, (Element JavaDoc)iterator.next()));
500       }
501
502       this.unknownPkField = defaultValues.isUnknownPkField();
503       autoIncrement = MetaData.getOptionalChild(element, "auto-increment") != null;
504
505       if(MetaData.getOptionalChild(element, "dbindex") == null)
506          genIndex = false;
507       else
508          genIndex = true;
509
510       this.relationTableField = relationTableField;
511
512       String JavaDoc dirtyAfterGetStr = MetaData.getOptionalChildContent(element, "check-dirty-after-get");
513       if(dirtyAfterGetStr == null)
514       {
515          checkDirtyAfterGet = defaultValues.getCheckDirtyAfterGet();
516       }
517       else
518       {
519          checkDirtyAfterGet = (Boolean.valueOf(dirtyAfterGetStr).booleanValue() ?
520             CHECK_DIRTY_AFTER_GET_TRUE : CHECK_DIRTY_AFTER_GET_FALSE);
521       }
522
523       String JavaDoc stateFactoryStr = MetaData.getOptionalChildContent(element, "state-factory");
524       if(stateFactoryStr == null)
525          stateFactory = defaultValues.getStateFactory();
526       else
527          stateFactory = stateFactoryStr;
528    }
529
530    /**
531     * Constructs a foreign key or a relation table key field.
532     */

533    public JDBCCMPFieldMetaData(JDBCEntityMetaData entity,
534                                JDBCCMPFieldMetaData defaultValues,
535                                String JavaDoc columnName,
536                                boolean primaryKeyMember,
537                                boolean notNull,
538                                boolean readOnly,
539                                int readTimeOut,
540                                boolean relationTableField)
541    {
542       this.entity = entity;
543       fieldName = defaultValues.getFieldName();
544       fieldType = defaultValues.getFieldType();
545       this.columnName = columnName;
546       jdbcType = defaultValues.getJDBCType();
547       sqlType = defaultValues.getSQLType();
548       this.readOnly = readOnly;
549       this.readTimeOut = readTimeOut;
550       this.primaryKeyMember = primaryKeyMember;
551       primaryKeyField = defaultValues.getPrimaryKeyField();
552       this.notNull = notNull;
553
554       for(Iterator JavaDoc i = defaultValues.propertyOverrides.iterator(); i.hasNext();)
555       {
556          propertyOverrides.add(new JDBCCMPFieldPropertyMetaData(
557             this, (JDBCCMPFieldPropertyMetaData)i.next()));
558       }
559
560       this.unknownPkField = defaultValues.isUnknownPkField();
561       autoIncrement = false;
562       genIndex = false;
563
564       this.relationTableField = relationTableField;
565       checkDirtyAfterGet = defaultValues.getCheckDirtyAfterGet();
566       stateFactory = defaultValues.getStateFactory();
567    }
568
569
570    /**
571     * Constructs a field that is used as an optimistic lock
572     */

573    public JDBCCMPFieldMetaData(JDBCEntityMetaData entity,
574                                String JavaDoc fieldName,
575                                Class JavaDoc fieldType,
576                                String JavaDoc columnName,
577                                int jdbcType,
578                                String JavaDoc sqlType)
579       throws DeploymentException
580    {
581       this.entity = entity;
582       this.fieldName = fieldName;
583       this.fieldType = fieldType;
584       this.columnName = columnName;
585       this.jdbcType = jdbcType;
586       this.sqlType = sqlType;
587       readOnly = false;
588       readTimeOut = -1;
589       primaryKeyMember = false;
590       notNull = true;
591       primaryKeyField = null;
592       unknownPkField = false;
593       autoIncrement = false;
594       genIndex = false;
595       relationTableField = false;
596       checkDirtyAfterGet = CHECK_DIRTY_AFTER_GET_NOT_PRESENT;
597       stateFactory = null;
598    }
599
600
601    /**
602     * Gets the entity on which this field is defined
603     * @return the entity on which this field is defined
604     */

605    public JDBCEntityMetaData getEntity()
606    {
607       return entity;
608    }
609
610    /**
611     * Gets the name of the field.
612     * @return the name of this field
613     */

614    public String JavaDoc getFieldName()
615    {
616       return fieldName;
617    }
618
619    /**
620     * Gets the java Class type of this field.
621     * @return the Class type of this field
622     */

623    public Class JavaDoc getFieldType()
624    {
625       return fieldType;
626    }
627
628    /**
629     * Gets the column name the property should use or null if the
630     * column name is not overriden.
631     * @return the name to which this field is persisted or null if the
632     * column name is not overriden
633     */

634    public String JavaDoc getColumnName()
635    {
636       return columnName;
637    }
638
639    /**
640     * Gets the JDBC type the property should use or Integer.MIN_VALUE
641     * if not overriden.
642     * @return the jdbc type of this field
643     */

644    public int getJDBCType()
645    {
646       return jdbcType;
647    }
648
649    /**
650     * Gets the SQL type the property should use or null
651     * if not overriden.
652     * @return the sql data type string used in create table statements
653     */

654    public String JavaDoc getSQLType()
655    {
656       return sqlType;
657    }
658
659    /**
660     * Gets the property overrides. Property overrides change the default
661     * mapping of Dependent Value Object properties. If there are no property
662     * overrides this method returns an empty list.
663     * @return an unmodifiable list of the property overrides.
664     */

665    public List JavaDoc getPropertyOverrides()
666    {
667       return Collections.unmodifiableList(propertyOverrides);
668    }
669
670    /**
671     * Is this field read only. A read only field will never be persisted
672     *
673     * @return true if this field is read only
674     */

675    public boolean isReadOnly()
676    {
677       return readOnly;
678    }
679
680    /**
681     * Gets the length of time (ms) that a read valid or -1 if data must
682     * always be reread from the database
683     * @return the length of time that data read database is valid, or -1
684     * if data must always be reread from the database
685     */

686    public int getReadTimeOut()
687    {
688       return readTimeOut;
689    }
690
691    /**
692     * Is this field one of the primary key fields?
693     * @return true if this field is one of the primary key fields
694     */

695    public boolean isPrimaryKeyMember()
696    {
697       return primaryKeyMember;
698    }
699
700    /**
701     * Should this field allow null values?
702     * @return true if this field will not allow a null value.
703     */

704    public boolean isNotNull()
705    {
706       return notNull;
707    }
708
709    /**
710     * Should an index for this field be generated?
711     * Normally this should be false for primary key fields
712     * But it seems there are databases that do not automatically
713     * put indices on primary keys *sigh*
714     * @return true if an index should be generated on this field
715     */

716    public boolean isIndexed()
717    {
718       return genIndex;
719    }
720
721    /**
722     * Gets the Field of the primary key object which contains the value of
723     * this field. Returns null, if this field is not a member of the primary
724     * key, or if the primray key is single valued.
725     * @return the Field of the primary key which contains the
726     * value of this field
727     */

728    public Field JavaDoc getPrimaryKeyField()
729    {
730       return primaryKeyField;
731    }
732
733    /**
734     * Is this field an unknown primary key field?
735     * @return true if the field is an unknown primary key field
736     */

737    public boolean isUnknownPkField()
738    {
739       return unknownPkField;
740    }
741
742    /**
743     * @return true if the key is auto incremented by the database
744     */

745    public boolean isAutoIncrement()
746    {
747       return autoIncrement;
748    }
749
750    public boolean isRelationTableField()
751    {
752       return relationTableField;
753    }
754
755    public byte getCheckDirtyAfterGet()
756    {
757       return checkDirtyAfterGet;
758    }
759
760    public String JavaDoc getStateFactory()
761    {
762       return stateFactory;
763    }
764
765    /**
766     * Compares this JDBCCMPFieldMetaData against the specified object. Returns
767     * true if the objects are the same. Two JDBCCMPFieldMetaData are the same
768     * if they both have the same name and are defined on the same entity.
769     * @param o the reference object with which to compare
770     * @return true if this object is the same as the object argument; false
771     * otherwise
772     */

773    public boolean equals(Object JavaDoc o)
774    {
775       if(o instanceof JDBCCMPFieldMetaData)
776       {
777          JDBCCMPFieldMetaData cmpField = (JDBCCMPFieldMetaData)o;
778          return fieldName.equals(cmpField.fieldName) &&
779             entity.equals(cmpField.entity);
780       }
781       return false;
782    }
783
784    /**
785     * Returns a hashcode for this JDBCCMPFieldMetaData. The hashcode is computed
786     * based on the hashCode of the declaring entity and the hashCode of the
787     * fieldName
788     * @return a hash code value for this object
789     */

790    public int hashCode()
791    {
792       int result = 17;
793       result = 37 * result + entity.hashCode();
794       result = 37 * result + fieldName.hashCode();
795       return result;
796    }
797
798    /**
799     * Returns a string describing this JDBCCMPFieldMetaData. The exact details
800     * of the representation are unspecified and subject to change, but the
801     * following may be regarded as typical:
802     *
803     * "[JDBCCMPFieldMetaData: fieldName=name, [JDBCEntityMetaData:
804     * entityName=UserEJB]]"
805     *
806     * @return a string representation of the object
807     */

808    public String JavaDoc toString()
809    {
810       return "[JDBCCMPFieldMetaData : fieldName=" + fieldName + ", " +
811          entity + "]";
812    }
813
814    /**
815     * Loads the java type of this field from the entity bean class. If this
816     * bean uses, cmp 1.x persistence, the field type is loaded from the field
817     * in the bean class with the same name as this field. If this bean uses,
818     * cmp 2.x persistence, the field type is loaded from the abstract getter
819     * or setter method for field in the bean class.
820     */

821    private Class JavaDoc loadFieldType(JDBCEntityMetaData entity, String JavaDoc fieldName)
822       throws DeploymentException
823    {
824       if(entity.isCMP1x())
825       {
826          // CMP 1.x field Style
827
try
828          {
829             return entity.getEntityClass().getField(fieldName).getType();
830          }
831          catch(NoSuchFieldException JavaDoc e)
832          {
833             throw new DeploymentException("No field named '" + fieldName +
834                "' found in entity class." +
835                entity.getEntityClass().getName());
836          }
837       }
838       else
839       {
840          // CMP 2.x abstract accessor style
841
String JavaDoc baseName = Character.toUpperCase(fieldName.charAt(0)) +
842             fieldName.substring(1);
843          String JavaDoc getName = "get" + baseName;
844          String JavaDoc setName = "set" + baseName;
845
846          Method JavaDoc[] methods = entity.getEntityClass().getMethods();
847          for(int i = 0; i < methods.length; i++)
848          {
849             // is this a public abstract method?
850
if(Modifier.isPublic(methods[i].getModifiers()) &&
851                Modifier.isAbstract(methods[i].getModifiers()))
852             {
853
854                // get accessor
855
if(getName.equals(methods[i].getName()) &&
856                   methods[i].getParameterTypes().length == 0 &&
857                   !methods[i].getReturnType().equals(Void.TYPE))
858                {
859                   return methods[i].getReturnType();
860                }
861
862                // set accessor
863
if(setName.equals(methods[i].getName()) &&
864                   methods[i].getParameterTypes().length == 1 &&
865                   methods[i].getReturnType().equals(Void.TYPE))
866                {
867
868                   return methods[i].getParameterTypes()[0];
869                }
870             }
871          }
872          throw new DeploymentException("No abstract accessors for field " +
873             "named '" + fieldName + "' found in entity class " +
874             entity.getEntityClass().getName());
875       }
876    }
877 }
878
Popular Tags