KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jdo > api > persistence > mapping > ejb > MappingFile


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * MappingFile.java
26  *
27  * Created on February 1, 2002, 9:47 PM
28  */

29
30 package com.sun.jdo.api.persistence.mapping.ejb;
31
32 import java.io.InputStream JavaDoc;
33 import java.io.OutputStream JavaDoc;
34 import java.io.File JavaDoc;
35
36 import java.util.Collection JavaDoc;
37 import java.util.Map JavaDoc;
38 import java.util.List JavaDoc;
39 import java.util.ArrayList JavaDoc;
40 import java.util.HashMap JavaDoc;
41 import java.util.ResourceBundle JavaDoc;
42 import java.util.Iterator JavaDoc;
43 import java.io.IOException JavaDoc;
44
45 import java.text.MessageFormat JavaDoc;
46
47 import org.netbeans.modules.dbschema.*;
48
49 import com.sun.jdo.api.persistence.mapping.ejb.beans.*;
50 import com.sun.jdo.spi.persistence.utility.StringHelper;
51 import com.sun.jdo.api.persistence.model.*;
52 import com.sun.jdo.api.persistence.model.mapping.*;
53 import com.sun.jdo.api.persistence.model.mapping.impl.*;
54 import com.sun.jdo.api.persistence.model.jdo.*;
55 import com.sun.jdo.api.persistence.model.jdo.impl.*;
56 import com.sun.jdo.spi.persistence.utility.logging.Logger;
57 import com.sun.jdo.spi.persistence.utility.I18NHelper;
58
59 import org.netbeans.modules.schema2beans.Schema2BeansException;
60
61 /** This class supports the conversion between the iAS mapping file
62  * format and the object used to represent that mapping to support
63  * the iAS EJBC process and iAS CMP run-time.
64  *
65  * @author vbk
66  * @version 1.0
67  */

68 public class MappingFile {
69
70     private static final String JavaDoc JAVA_TYPE_SET = "java.util.Set"; //NOI18N
71
private static final String JavaDoc JAVA_TYPE_COLLECTION = "java.util.Collection"; //NOI18N
72
private static final List JavaDoc types = new ArrayList JavaDoc();
73
74     /** Definitive location for a mapping file in an ejb-jar file. */
75     public static String JavaDoc DEFAULT_LOCATION_IN_EJB_JAR = null;
76
77     /** The logger */
78     private static final Logger logger =
79         LogHelperMappingConversion.getLogger();
80
81     /**
82      * I18N message handler
83      */

84     private final static ResourceBundle JavaDoc messages = I18NHelper.loadBundle(
85             MappingFile.class);
86
87     static {
88         types.add(JAVA_TYPE_SET);
89         types.add(JAVA_TYPE_COLLECTION);
90
91         DEFAULT_LOCATION_IN_EJB_JAR = new StringBuffer JavaDoc(I18NHelper.getMessage(
92             messages, "CONST_IAS_MAPPING_FILE_LOC")). //NOI18N
93
append(File.separator).
94             append(I18NHelper.getMessage(
95             messages, "CONST_IAS_MAPPING_FILE")).toString(); //NOI18N
96
}
97
98     private Map JavaDoc inverseRelationships = null;
99     private Map JavaDoc namedGroups = null;
100     private int groupCount = MappingFieldElement.GROUP_INDEPENDENT;
101
102     private ClassLoader JavaDoc classLoader = null;
103
104     private static int MINIMUM_PRECISION = 19;
105
106     /**
107      * An object which implements ConversionHelper interface to
108      * access data from other available sources to support the mapping
109      * generation.
110      */

111     private ConversionHelper helper = null;
112
113     private HashMap JavaDoc loadedSchema = new HashMap JavaDoc();
114
115     /** Creates new MappingFile */
116     public MappingFile() {
117         classLoader = null;
118     }
119
120     /** Creates new MappingFile */
121     public MappingFile(ClassLoader JavaDoc cl) {
122         this();
123         classLoader = cl;
124     }
125
126     /** Convert an SunCmpMapping object into the equivelent collection of
127      * MappingClassElement objects
128      * @param content An SunCmpMapping object that describes a mapping
129      * for one or more beans
130      * @param helper An object which implements ConversionHelper interface to
131      * access data from other available sources to support the mapping
132      * generation
133      * @return A Collection of MappingClassElement objects
134      * @throws DBException
135      * @throws ModelException
136      * @throws ConversionException
137      */

138     public Map JavaDoc intoMappingClasses(SunCmpMappings content,
139         ConversionHelper helper)
140         throws DBException, ModelException, ConversionException {
141         Map JavaDoc mces = new java.util.HashMap JavaDoc();
142         this.helper = helper;
143         boolean ensureValidation = helper.ensureValidation();
144
145         for (int i = 0; i < content.sizeSunCmpMapping(); i++) {
146             SunCmpMapping beanSet = content.getSunCmpMapping(i);
147             inverseRelationships = new HashMap JavaDoc();
148             namedGroups = new HashMap JavaDoc();
149             String JavaDoc schema = beanSet.getSchema();
150
151             if (helper.generateFields()) {
152
153                 // sweep through the mappings to complete them
154
completeCmrMappings(beanSet);
155             }
156
157             // process bean mapping and fields mapping
158
for (int k = 0; k < beanSet.sizeEntityMapping(); k++) {
159                 EntityMapping beanMapping = beanSet.getEntityMapping(k);
160                 MappingClassElement aTpMapping = null;
161                 if (ensureValidation) {
162                     aTpMapping = mapFieldsOfBean(beanMapping, schema);
163                 }
164                 else {
165                     try {
166                         aTpMapping = mapFieldsOfBean(beanMapping, schema);
167                     }
168                     catch (ConversionException t) {
169                         if (logger.isLoggable(Logger.FINE))
170                             logger.fine(
171                                 I18NHelper.getMessage(
172                                 messages,
173                                 "MESSAGE_CONV_EXC", //NOI18N
174
t.toString()));
175                     }
176                 }
177
178                 mces.put(beanMapping.getEjbName(), aTpMapping);
179             }
180         }
181         return mces;
182     }
183
184     /** Convert an SunCmpMapping object into the equivelent collection of
185      * MappingClassElement objects
186      * @param content An InputStream that contains an xml data stream that
187      * conforms to the sun-cmp-mapping.dtd
188      * @param helper An object which implements ConversionHelper interface to
189      * access data from other available sources to support the mapping
190      * generation
191      * @return A Collection of MappingClassElement objects
192      * @throws DBException
193      * @throws ModelException
194      * @throws ConversionException
195      */

196     public Map JavaDoc intoMappingClasses(InputStream JavaDoc content, ConversionHelper helper)
197         throws DBException, ModelException, ConversionException {
198         SunCmpMappings foo = null;
199         try {
200             foo = SunCmpMappings.createGraph(content);
201         }
202         catch (Schema2BeansException t) {
203             if (helper.ensureValidation()) {
204                 throw new ConversionException(
205                     I18NHelper.getMessage(messages,
206                     "XML_ERROR_IN_MAPPING_FILE", //NOI18N
207
DEFAULT_LOCATION_IN_EJB_JAR));
208             }
209             foo = SunCmpMappings.createGraph();
210         }
211
212         return intoMappingClasses(foo, helper);
213     }
214
215     /** Creates an SunCmpMapping object from a Collection of
216      * MappingClassElement objects
217      * @param dest The output for processing
218      * @param mappingClasses The Collection of MappingClassElements
219      * @param helper An object which implements ConversionHelper interface to
220      * access data from other available sources to support the mapping
221      * generation
222      * @throws IOException Thrown if there is a problem
223      * sending the data out on <CODE>dest</CODE>.
224      * @throws Schema2BeansException
225      */

226     public void fromMappingClasses(OutputStream JavaDoc dest, Map JavaDoc mappingClasses,
227         ConversionHelper helper)
228         throws IOException JavaDoc, Schema2BeansException {
229         SunCmpMappings tmp = fromMappingClasses(mappingClasses, helper);
230         tmp.write(dest);
231     }
232
233     /** Creates an SunCmpMapping object from a Collection of
234      * MappingClassElement objects
235      * @param mappingClasses The Collection of MappingClassElements
236      * @param helper An object which implements ConversionHelper interface to
237      * access data from other available sources to support the mapping
238      * generation.
239      * @return The SunCmpMapping object that is equivelent to the
240      * collection of MappingClassElements.
241      * throws Schema2BeansException
242      */

243     public SunCmpMappings fromMappingClasses(Map JavaDoc mappingClasses,
244         ConversionHelper helper) throws Schema2BeansException {
245         Iterator JavaDoc keyIter = mappingClasses.keySet().iterator();
246         Map JavaDoc mapOfMapping = new java.util.HashMap JavaDoc();
247         while (keyIter.hasNext()) {
248             String JavaDoc ejbName = (String JavaDoc) keyIter.next();
249             MappingClassElement mce = (MappingClassElement)
250                 mappingClasses.get(ejbName);
251             EntityMapping beanMapping = new EntityMapping();
252
253             if (null != mce) {
254                 setConsistency(mce, beanMapping);
255
256                 String JavaDoc schemaName = mce.getDatabaseRoot();
257                 SunCmpMapping aMapping = (SunCmpMapping) mapOfMapping.get(
258                     schemaName);
259                 if (null == aMapping) {
260                     aMapping = new SunCmpMapping();
261                     aMapping.setSchema(schemaName);
262                     mapOfMapping.put(schemaName, aMapping);
263                 }
264                 List JavaDoc tables = mce.getTables();
265                 MappingTableElement primary = null;
266                 if (tables.size() > 0) {
267                     primary = (MappingTableElement) tables.get(0);
268                     beanMapping.setTableName(primary.getName());
269                 }
270                 beanMapping.setEjbName(ejbName);
271                 if (null != primary) {
272                     List JavaDoc refKeys = primary.getReferencingKeys();
273                     for (int i = 0; refKeys != null && i < refKeys.size(); i++) {
274                         SecondaryTable sT = new SecondaryTable();
275                         MappingReferenceKeyElement mrke =
276                             (MappingReferenceKeyElement) refKeys.get(i);
277                         MappingTableElement mte = mrke.getTable();
278                         if (null != mte) {
279                             sT.setTableName(mte.getName());
280                             List JavaDoc cpnames = mrke.getColumnPairNames();
281                             boolean hasPairs = false;
282                             for (int j = 0; cpnames != null &&
283                                 j < cpnames.size(); j++) {
284                                 List JavaDoc token =
285                                     StringHelper.separatedListToArray((String JavaDoc)cpnames.get(j),";"); //NOI18N
286
ColumnPair cp = new ColumnPair();
287                                 Iterator JavaDoc iter = token.iterator();
288                                 while (iter.hasNext()) {
289                                     String JavaDoc columnName = (String JavaDoc)iter.next();
290                                     cp.addColumnName(columnName);
291                                 }
292                                 sT.addColumnPair(cp);
293                                 hasPairs = true;
294                             }
295                             if (hasPairs)
296                                 beanMapping.addSecondaryTable(sT);
297                             else
298                                 if (logger.isLoggable(Logger.FINE))
299                                     logger.fine(
300                                         I18NHelper.getMessage(
301                                         messages,
302                                         "WARN_ILLEGAL_PAIR", //NOI18N
303
new Object JavaDoc [] {ejbName, mte.getName(), cpnames}));
304                         }
305                         else {
306                             if (logger.isLoggable(Logger.FINE))
307                                 logger.fine(
308                                     I18NHelper.getMessage(
309                                     messages,
310                                     "WARN_MISSING_TABLE", //NOI18N
311
new Object JavaDoc [] {ejbName, primary.getName()}));
312                         }
313                     }
314                 }
315                 else {
316                     if (logger.isLoggable(Logger.FINE))
317                         logger.fine(
318                             I18NHelper.getMessage(
319                             messages,
320                             "WARN_NO_PRIMARY", //NOI18N
321
ejbName));
322                 }
323
324                 // transform the field mappings
325
PersistenceClassElement pce = null;
326                 PersistenceFieldElement pfields[] = null;
327                 if (mce instanceof MappingClassElementImpl) {
328                     MappingClassElementImpl mcei =
329                         (MappingClassElementImpl) mce;
330                     pce = mcei.getPersistenceElement();
331                     pfields = pce.getFields();
332                 }
333                 int len = 0;
334                 if (null != pfields)
335                     len = pfields.length;
336                 for (int i = 0; i < len; i++) {
337                     PersistenceFieldElement pfield = pfields[i];
338                     String JavaDoc fieldName = pfield.getName();
339                     if (helper.isGeneratedField(ejbName, fieldName)) {
340                         continue;
341                     }
342                     if (pfield instanceof RelationshipElement) {
343                         MappingRelationshipElement mre =
344                             (MappingRelationshipElement) mce.getField(fieldName);
345                         MappingFieldElement mfe = mre;
346                         CmrFieldMapping cfm = new CmrFieldMapping();
347                         cfm.setCmrFieldName(fieldName);
348                         List JavaDoc cols = null;
349                         if (null != mfe) {
350                             cols = mfe.getColumns();
351                             int fgVal = mfe.getFetchGroup();
352                             setFetchedWith(cfm, fgVal);
353                         }
354                         for (int j = 0; null != cols && j < cols.size(); j++) {
355                             String JavaDoc cpstring = (String JavaDoc) cols.get(j);
356                             int slen = cpstring.indexOf(';');
357                             ColumnPair cp = new ColumnPair();
358                             cp.addColumnName(cpstring.substring(0,slen));
359                             cp.addColumnName(cpstring.substring(slen+1));
360                             cfm.addColumnPair(cp);
361                         }
362                         if (null != mre)
363                             cols = mre.getAssociatedColumns();
364                         for (int j = 0; null != cols && j < cols.size(); j++) {
365                             String JavaDoc cpstring = (String JavaDoc) cols.get(j);
366                             int slen = cpstring.indexOf(';');
367                             ColumnPair cp = new ColumnPair();
368                             cp.addColumnName(cpstring.substring(0,slen));
369                             cp.addColumnName(cpstring.substring(slen+1));
370                             cfm.addColumnPair(cp);
371                         }
372                         beanMapping.addCmrFieldMapping(cfm);
373                     }
374                     else {
375                         MappingFieldElement mfe = mce.getField(fieldName);
376                         CmpFieldMapping cfm = new CmpFieldMapping();
377                         cfm.setFieldName(fieldName);
378                         List JavaDoc cols = null;
379                         if (null != mfe) {
380                             cols = mfe.getColumns();
381                             for (int j = 0; null != cols &&
382                                 j < cols.size(); j++) {
383                                 cfm.addColumnName((String JavaDoc)cols.get(j));
384                             }
385                             int fgVal = mfe.getFetchGroup();
386                             setFetchedWith(cfm,fgVal);
387                         }
388                         beanMapping.addCmpFieldMapping(cfm);
389                     }
390                 }
391                 aMapping.addEntityMapping(beanMapping);
392             }
393         }
394         SunCmpMappings retVal = null;
395         retVal = new SunCmpMappings();
396         Iterator JavaDoc mapOfMappingIter = mapOfMapping.values().iterator();
397         while (mapOfMappingIter.hasNext()) {
398             SunCmpMapping aVal = (SunCmpMapping) mapOfMappingIter.next();
399             retVal.addSunCmpMapping(aVal);
400         }
401         return retVal;
402     }
403
404     /** Set fetchgroup in schema2beans FetchedWith bean
405      * @param cfm An object that represents HasFetchedWith object
406      * in schema2beans
407      * @param fgVal integer that represents fetch group value
408      */

409     private void setFetchedWith(HasFetchedWith cfm, int fgVal) {
410         FetchedWith fw = new FetchedWith();
411         if (fgVal <= MappingFieldElement.GROUP_INDEPENDENT) {
412             String JavaDoc key = "IndependentFetchGroup"+fgVal; //NOI18N
413
fw.setNamedGroup(key);
414         }
415         else if (fgVal == MappingFieldElement.GROUP_DEFAULT) {
416             fw.setDefault(true);
417         }
418         else if (fgVal > MappingFieldElement.GROUP_DEFAULT) {
419             fw.setLevel(fgVal-1);
420         }
421         else if (fgVal == MappingFieldElement.GROUP_NONE) {
422             fw.setNone(true);
423         }
424         cfm.setFetchedWith(fw);
425     }
426
427     /** Convert a bean's cmp-field-mapping and cmr-field-mapping elements into
428      * mapping model objects.
429      *
430      * The method can be called in two distinct cases:
431      *
432      * 1. At deployment time. The mapping must be complete enough to create a
433      * valid mapping model, in order to support execution.
434      *
435      * 2. During mapping development. The mapping may be incomplete, but the
436      * model objects that are created need to be as consistent as possible.
437      * The absence of data should not be fatal, if possible.
438      *
439      * @param mapping The schema2beans object that represents the mapping
440      * for a particular bean.
441      * @param schemaArg The name of the schema that the bean is mapped against.
442      * @return The MappingClassElement that corresponds to the
443      * schema2beans object.
444      * @throws DBException
445      * @throws ModelException
446      * @throws ConversionException
447      */

448     private MappingClassElement mapFieldsOfBean(EntityMapping mapping,
449                                                 String JavaDoc schemaArg)
450         throws DBException, ModelException, ConversionException {
451
452         String JavaDoc beanName = mapping.getEjbName();
453         MappingClassElement mce = null;
454         List JavaDoc tablesOfBean = new ArrayList JavaDoc();
455         Map JavaDoc knownTables = new HashMap JavaDoc();
456
457         if (logger.isLoggable(Logger.FINE))
458             logger.fine(
459                 I18NHelper.getMessage(
460                 messages,
461                 "MESSAGE_START_BEAN", //NOI18N
462
beanName));
463
464         String JavaDoc jdoClassName = helper.getMappedClassName(beanName);
465         if (logger.isLoggable(Logger.FINE))
466             logger.fine(
467                 I18NHelper.getMessage(
468                 messages,
469                 "MESSAGE_JDOCLASS_NAME", //NOI18N
470
beanName, jdoClassName));
471
472         if (null == jdoClassName) {
473             throw new ConversionException(
474                 I18NHelper.getMessage(
475                 messages,
476                 "ERR_INVALID_CLASS", //NOI18N
477
beanName));
478         }
479
480         // create the mapping class element and its children
481
PersistenceClassElementImpl persistElImpl =
482             new PersistenceClassElementImpl(jdoClassName);
483         persistElImpl.setKeyClass(jdoClassName+".Oid"); //NOI18N
484
mce = new MappingClassElementImpl(
485             new PersistenceClassElement(persistElImpl));
486
487         SchemaElement schema = null;
488
489         // Assign the schema
490
if (!StringHelper.isEmpty(schemaArg))
491             schema = setDatabaseRoot(mce, schemaArg,
492                 helper.ensureValidation());
493
494         // Map the table information
495
// Ensure the bean is mapped to a primary table.
496
if (!StringHelper.isEmpty(mapping.getTableName())) {
497
498             mapPrimaryTable(mapping, mce,
499                 schema, knownTables, tablesOfBean);
500             mapSecondaryTables(mapping, mce,
501                 schema, knownTables, tablesOfBean);
502         }
503
504         ColumnElement candidatePK = null;
505
506         // map the simple fields.
507
candidatePK = mapNonRelationshipFields(mapping, mce,
508             beanName, schema, knownTables);
509
510         createMappingForUnknownPKClass(mapping, mce,
511             beanName, candidatePK);
512
513         createMappingForConsistency(mapping, mce,
514             beanName, knownTables);
515
516         // map the relationship fields.
517
mapRelationshipFields(mapping, mce,
518             beanName, schema, knownTables, tablesOfBean);
519
520         // map any unmapped fields.
521
mapUnmappedFields(mce, beanName);
522
523         return mce;
524     }
525
526     /** Create field mapping for unknown primary key
527      * @param mapping The schema2beans object that represents the mapping
528      * for a particular bean.
529      * @param mce Mapping class element
530      * @param beanName Bean name
531      * @param candidatePK A ColumnElement object which is a candidate column for
532      * mapping to primary key field if it is unknown primary key
533      * @throws ModelException
534      * @throws ConversionException
535      */

536     private void createMappingForUnknownPKClass(EntityMapping mapping,
537                                                 MappingClassElement mce,
538                                                 String JavaDoc beanName,
539                                                 ColumnElement candidatePK)
540         throws ModelException, ConversionException {
541         String JavaDoc primaryTableName = mapping.getTableName();
542
543         if (helper.generateFields()
544             && helper.applyDefaultUnknownPKClassStrategy(beanName)) {
545             if (null != candidatePK) {
546                 String JavaDoc fieldName = helper.getGeneratedPKFieldName();
547
548                 // Fix later. Since mapping and persistence classes in the
549
// cache are only skeletons and not the one we want,
550
// put pce in a map at pce creation time for persistence
551
// class look up later to avoid a cast
552
// to MappingClassElementImpl.
553
PersistenceFieldElement pfe = createPersistenceField(mce,
554                     fieldName);
555                 pfe.setKey(true);
556                 MappingFieldElement mfe = createMappingField(mce, fieldName,
557                     candidatePK);
558             }
559             else {
560                 // There is no column which meets primary key criteria.
561
// Report error.
562
throw new ConversionException(
563                     I18NHelper.getMessage(
564                     messages,
565                     "WARN_NO_PKCOLUMN", //NOI18N
566
primaryTableName));
567             }
568         }
569     }
570
571     /** Load the consistency information. if it is version consistency, create
572      * field mapping for version columns.
573      * @param mapping The schema2beans object that represents the mapping
574      * for a particular bean.
575      * @param mce Mapping class element
576      * @param beanName Bean name
577      * @param knownTables A Map which contains primary and secondary tables
578      * for beans in the set. Keys: table names Values: TableElement objects
579      * @throws ModelException
580      * @throws DBException
581      * @throws ConversionException
582      */

583     private void createMappingForConsistency(EntityMapping mapping,
584                                              MappingClassElement mce,
585                                              String JavaDoc beanName,
586                                              Map JavaDoc knownTables)
587         throws ModelException, DBException, ConversionException {
588
589         // load the consistency information
590
List JavaDoc versionColumns = loadConsistency(mapping, mce);
591
592         // If the consistency level is version consistency, the version field
593
// is always created, independent of the ConversionHelper's value for
594
// generateFields. This is because a generated version field is
595
// needed to hold the version column information.
596
if (versionColumns != null) {
597
598             String JavaDoc primaryTableName = mapping.getTableName();
599
600             // For 8.1 release, we only support one version column per bean
601
if (versionColumns.size() > 1) {
602                 throw new ConversionException(
603                     I18NHelper.getMessage(
604                     messages,
605                     "ERR_INVALID_VERSION_COLUMNS")); //NOI18N
606
}
607             String JavaDoc versionColumn = (String JavaDoc)versionColumns.get(0);
608
609             String JavaDoc sourceTableName = getTableName(versionColumn,
610                     primaryTableName);
611
612             // we do not support version column from secondary table
613
// in 8.1 release
614
if (!sourceTableName.equals(primaryTableName)) {
615                 throw new ConversionException(
616                     I18NHelper.getMessage(
617                     messages,
618                     "WARN_VERSION_COLUMN_INVALID_TABLE", //NOI18N
619
primaryTableName, beanName, versionColumn));
620             }
621
622             TableElement sourceTableEl = (TableElement) knownTables.get(
623                     sourceTableName);
624             String JavaDoc versionColumnName = getColumnName(versionColumn);
625             ColumnElement versionCol = getColumnElement(sourceTableEl,
626                     DBIdentifier.create(versionColumnName), helper);
627
628             if (null != versionCol) {
629
630                 // Since 8.1 release only support one version column per bean,
631
// use prefix as the version field name
632
String JavaDoc fieldName = helper.getGeneratedVersionFieldNamePrefix();
633                 PersistenceFieldElement pfe = createPersistenceField(mce,
634                     fieldName);
635                 MappingFieldElement mfe = createMappingField(mce, fieldName,
636                     versionCol);
637                 mfe.setVersion(true);
638             }
639             else {
640                 // There is no version column.
641
// Report error.
642
throw new ConversionException(
643                     I18NHelper.getMessage(
644                     messages,
645                     "WARN_VERSION_COLUMN_MISSING", //NOI18N
646
primaryTableName, beanName));
647             }
648         }
649     }
650
651     /** Map simple cmp field to MappingFieldElement
652      * @param mapping The schema2beans object that represents the mapping
653      * for a particular bean.
654      * @param mce Mapping class element
655      * @param beanName Bean name
656      * @param schema dbschema information for all beans
657      * @param knownTables A Map which contains primary and secondary tables
658      * for beans in the set. Keys: table names Values: TableElement objects
659      * @return candidate primary key column for unknown
660      * primary key class mapping, if applicable
661      * @throws DBException
662      * @throws ModelException
663      * @throws ConversionException
664      */

665     private ColumnElement mapNonRelationshipFields(EntityMapping mapping,
666                                                    MappingClassElement mce,
667                                                    String JavaDoc beanName,
668                                                    SchemaElement schema,
669                                                    Map JavaDoc knownTables)
670         throws DBException, ModelException, ConversionException {
671
672         CmpFieldMapping [] mapOfFields = mapping.getCmpFieldMapping();
673         String JavaDoc primaryTableName = mapping.getTableName();
674         ColumnElement candidatePK = null;
675
676         // get candidate column only used for unknown primary key
677
if (helper.generateFields()
678             && helper.applyDefaultUnknownPKClassStrategy(beanName)) {
679
680             candidatePK = getCandidatePK(schema, primaryTableName);
681         }
682
683         for (int i = 0; i < mapOfFields.length; i++) {
684             CmpFieldMapping mapForOneField = mapOfFields[i];
685
686             String JavaDoc fieldName = mapForOneField.getFieldName();
687             if (!validateField(mce, beanName, fieldName,
688                 helper.ensureValidation())) {
689                 if (logger.isLoggable(Logger.FINE))
690                     logger.fine(
691                         I18NHelper.getMessage(
692                         messages,
693                         "WARN_INVALID_FIELD", //NOI18N
694
beanName, fieldName));
695
696                 continue;
697             }
698
699             String JavaDoc columnNames[] = mapForOneField.getColumnName();
700             MappingFieldElement mfe = createUnmappedField(mce, beanName,
701                 fieldName);
702             boolean fieldMappedToABlob = false;
703
704             for (int j = 0; j < columnNames.length; j++) {
705                 String JavaDoc sourceTableName = getTableName(columnNames[j],
706                     primaryTableName);
707                 if (null == sourceTableName) {
708                     throw new ConversionException(
709                         I18NHelper.getMessage(
710                         messages,
711                         "ERR_UNDEFINED_TABLE")); //NOI18N
712
}
713
714                 String JavaDoc sourceColumnName = getColumnName(columnNames[j]);
715
716                 // get the table element
717
TableElement sourceTableEl = getTableElement(sourceTableName,
718                     knownTables, schema);
719                 ColumnElement aCol = getColumnElement(sourceTableEl,
720                     DBIdentifier.create(sourceColumnName), helper);
721                 if (logger.isLoggable(Logger.FINE))
722                     logger.fine(
723                         I18NHelper.getMessage(
724                         messages,
725                         "MESSAGE_ADD_COLUMN", //NOI18N
726
new Object JavaDoc [] {aCol, fieldName}));
727
728                 // If candidatePK is mapped to a field, then it can not
729
// treated as a primary key for unknown primary key
730
if (helper.generateFields()
731                     && helper.applyDefaultUnknownPKClassStrategy(beanName)) {
732                     if (candidatePK != null && candidatePK.equals(aCol)) {
733                         candidatePK = null;
734                     }
735                 }
736
737                 fieldMappedToABlob |= aCol.isBlobType();
738                 mfe.addColumn(aCol);
739             }
740
741             FetchedWith fw = mapForOneField.getFetchedWith();
742             setFetchGroup(fw, mfe, beanName, fieldMappedToABlob);
743             mce.addField(mfe);
744         }
745
746         return candidatePK;
747     }
748
749     /**
750      * Converts entity mapping relationship information from sun-cmp-mappings.xml
751      * into JDO mapping file information.
752      *
753      * @param mapping The schema2beans object that represents the mapping
754      * for a particular bean.
755      * @param mce Mapping class element being populated corresponding to the bean.
756      * @param beanName Bean name.
757      * @param knownTables A Map which contains primary and secondary tables
758      * for beans in the set. Keys: table names Values: TableElement objects
759      * @param tablesOfBean contains primary table and
760      * secondary tables of the bean <code>beanName</code>.
761      * @throws ModelException
762      * @throws DBException
763      * @throws ConversionException
764      */

765     private void mapRelationshipFields(EntityMapping mapping,
766                                        MappingClassElement mce,
767                                        String JavaDoc beanName,
768                                        SchemaElement schema,
769                                        Map JavaDoc knownTables,
770                                        List JavaDoc tablesOfBean)
771         throws ModelException, DBException, ConversionException {
772
773         String JavaDoc primaryTableName = mapping.getTableName();
774         CmrFieldMapping mapOfRelations[] = mapping.getCmrFieldMapping();
775         PersistenceClassElement pce = ((MappingClassElementImpl)mce).getPersistenceElement();
776
777         for (int i = 0; mapOfRelations != null && i < mapOfRelations.length;
778                 i++) {
779             CmrFieldMapping aRelation = mapOfRelations[i];
780             String JavaDoc fieldName = aRelation.getCmrFieldName();
781
782             if (!validateField(mce, beanName, fieldName, helper.ensureValidation())) {
783                 if (logger.isLoggable(Logger.FINE))
784                     logger.fine(
785                         I18NHelper.getMessage(
786                         messages,
787                         "WARN_INVALID_CMRFIELD", //NOI18N
788
beanName, fieldName));
789                 continue;
790             }
791
792             RelationshipElement rel = new RelationshipElement(
793                 new RelationshipElementImpl(fieldName), pce);
794             MappingRelationshipElement mre =
795                 new MappingRelationshipElementImpl(fieldName, mce);
796
797             // Register the inverse RelationshipElement
798
registerInverseRelationshipElement(rel, beanName, fieldName);
799
800             final ColumnPair pairs[] = aRelation.getColumnPair();
801             final String JavaDoc relationId = mapping.getEjbName() + "_Relationship_" + i; //NOI18N
802
Collection JavaDoc primaryTableColumns = convertToColumnPairElements(
803                     pairs,
804                     primaryTableName, schema, knownTables, tablesOfBean,
805                     relationId,
806                     mre);
807
808             setUpperBound(rel, beanName, fieldName);
809             setCascadeDeleteAction(rel, beanName, fieldName);
810             setLowerBound(rel,
811                     primaryTableColumns,
812                     primaryTableName,schema, knownTables,
813                     beanName, fieldName);
814             setFetchGroup(aRelation.getFetchedWith(), mre, beanName, false);
815
816             pce.addField(rel);
817             mce.addField(mre);
818         }
819     }
820
821     /** Map unmapped field to mapping field object.
822      * @param mce Mapping class element
823      * @param beanName Bean name
824      * @throws ModelException
825      */

826     private void mapUnmappedFields(MappingClassElement mce, String JavaDoc beanName)
827         throws ModelException {
828
829         Object JavaDoc[] fields = helper.getFields(beanName);
830         if (!helper.ensureValidation()) {
831             for (int i = 0; i < fields.length; i++) {
832                 String JavaDoc fieldName = (String JavaDoc) fields[i];
833                 MappingFieldElement mfe = mce.getField(fieldName);
834
835                 if (null == mfe) {
836
837                     // this field needs a mapping created for it...
838
mfe = createUnmappedField(mce, beanName, fieldName);
839                     mce.addField(mfe);
840                 }
841             }
842         }
843     }
844
845     /** Set consistency from MappingClassElement into schema2beans
846      * Consistency bean.
847      * @param mce An object that represents the mapping object
848      * @param beanMapping The schema2beans object that represents the mapping
849      * for a particular bean.
850      */

851     private void setConsistency(MappingClassElement mce,
852         EntityMapping beanMapping) {
853         int consistency = mce.getConsistencyLevel();
854         if (MappingClassElement.NONE_CONSISTENCY != consistency) {
855             Consistency c = new Consistency();
856             if (MappingClassElement.LOCK_WHEN_MODIFIED_CHECK_ALL_AT_COMMIT_CONSISTENCY == consistency) {
857                 c.setLockWhenModified(true);
858                 c.setCheckAllAtCommit(true);
859             }
860             if (MappingClassElement.LOCK_WHEN_MODIFIED_CONSISTENCY == consistency)
861                 c.setLockWhenModified(true);
862             if (MappingClassElement.CHECK_ALL_AT_COMMIT_CONSISTENCY == consistency)
863                 c.setCheckAllAtCommit(true);
864             if (MappingClassElement.LOCK_WHEN_LOADED_CONSISTENCY == consistency)
865                 c.setLockWhenLoaded(true);
866             if (MappingClassElement.CHECK_MODIFIED_AT_COMMIT_CONSISTENCY == consistency)
867                 c.setCheckModifiedAtCommit(true);
868             if (MappingClassElement.VERSION_CONSISTENCY == consistency) {
869                 CheckVersionOfAccessedInstances versionIns =
870                     new CheckVersionOfAccessedInstances();
871                 Iterator JavaDoc iter = mce.getVersionFields().iterator();
872                 while (iter.hasNext()) {
873                     List JavaDoc columnNames = ((MappingFieldElement)iter.next()).
874                         getColumns();
875
876                     // vesion field only allow to map to one column
877
if (columnNames != null && columnNames.size() > 0)
878                         versionIns.addColumnName((String JavaDoc)columnNames.get(0));
879                 }
880                 c.setCheckVersionOfAccessedInstances(versionIns);
881             }
882             beanMapping.setConsistency(c);
883         }
884     }
885
886     /** Load consistency from schema2beans into MappingClassElement
887      * @param mapping The schema2beans object that represents the mapping
888      * for a particular bean.
889      * @param mce An object that represents mapping object
890      * @return a list of version column names if applicable; return null
891      * otherwise.
892      * @throws ModelException
893      * @throws ConversionException
894      */

895     private List JavaDoc loadConsistency(EntityMapping mapping, MappingClassElement mce)
896         throws ModelException, ConversionException {
897         Consistency c = mapping.getConsistency();
898         if (null == c) {
899             mce.setConsistencyLevel(MappingClassElement.NONE_CONSISTENCY);
900         }
901         else {
902             CheckVersionOfAccessedInstances versionIns =
903                 (CheckVersionOfAccessedInstances)
904                 c.getCheckVersionOfAccessedInstances();
905
906             if (c.isCheckModifiedAtCommit())
907                 mce.setConsistencyLevel(
908                     MappingClassElement.CHECK_MODIFIED_AT_COMMIT_CONSISTENCY);
909             else if(c.isLockWhenLoaded())
910                 mce.setConsistencyLevel(
911                     MappingClassElement.LOCK_WHEN_LOADED_CONSISTENCY);
912             else if(c.isCheckAllAtCommit())
913                 mce.setConsistencyLevel(
914                     MappingClassElement.CHECK_ALL_AT_COMMIT_CONSISTENCY);
915             else if(c.isLockWhenModified())
916                 mce.setConsistencyLevel(
917                     MappingClassElement.LOCK_WHEN_MODIFIED_CONSISTENCY);
918             else if(c.isLockWhenModified() && c.isCheckAllAtCommit())
919                 mce.setConsistencyLevel(MappingClassElement.
920                     LOCK_WHEN_MODIFIED_CHECK_ALL_AT_COMMIT_CONSISTENCY);
921             else if(c.isNone())
922                 mce.setConsistencyLevel(MappingClassElement.NONE_CONSISTENCY);
923             else if (versionIns != null) {
924                 mce.setConsistencyLevel(MappingClassElement.VERSION_CONSISTENCY);
925                 List JavaDoc versionColumns = new ArrayList JavaDoc();
926                 for (int i = 0; i < versionIns.sizeColumnName(); i++) {
927                     versionColumns.add(versionIns.getColumnName(i));
928                 }
929                 return versionColumns;
930             }
931             else {
932                 throw new ConversionException(
933                     I18NHelper.getMessage(
934                     messages,
935                     "ERR_INVALID_CONSISTENCY_VALUE", mce)); //NOI18N
936
}
937         }
938         return null;
939     }
940
941     /** Map the primary table of the bean.
942      * @param mapping The schema2beans object that represents the mapping
943      * for a particular bean.
944      * @param mce Mapping class element
945      * @param schema dbschema information for all beans
946      * @param knownTables A Map which contains primary and secondary tables
947      * for beans in the set. Keys: table names Values: TableElement objects
948      * @param tablesOfBean contains primary table and
949      * secondary tables of the bean corresponding to the <code>mapping</code>
950      * @throws DBException
951      * @throws ModelException
952      * @throws ConversionException
953      */

954     private void mapPrimaryTable(EntityMapping mapping,
955                                   MappingClassElement mce,
956                                   SchemaElement schema,
957                                   Map JavaDoc knownTables,
958                                   List JavaDoc tablesOfBean)
959         throws DBException, ModelException, ConversionException {
960
961         String JavaDoc primaryTableName = mapping.getTableName();
962         TableElement primTabEl = getTableElement(primaryTableName, knownTables, schema);
963
964         mce.addTable(primTabEl);
965         tablesOfBean.add(primaryTableName);
966     }
967
968     /** Get the candidate pk column for unknown primary key.
969      * @param schema dbschema information for all beans
970      * @param primaryTableName Primary table name
971      * @return candidate pk column which will be used for unknown primary key,
972      * if applicable
973      * @throws DBException
974      * @throws ConversionException
975      */

976     private ColumnElement getCandidatePK(SchemaElement schema,
977                                          String JavaDoc primaryTableName)
978         throws DBException, ConversionException {
979         ColumnElement candidatePK = null;
980
981         TableElement primTabEl = getTableElement(schema,
982             DBIdentifier.create(primaryTableName), helper);
983         // Check if the candidatePK is really satisfying primary key
984
// criteria. It will be used only for unknown primary key.
985
UniqueKeyElement uke = primTabEl.getPrimaryKey();
986
987         if (null != uke) {
988             ColumnElement cols[] = uke.getColumns();
989             if (null != cols && 1 == cols.length) {
990                 candidatePK = cols[0];
991                 if (logger.isLoggable(Logger.FINE))
992                     logger.fine(
993                         I18NHelper.getMessage(
994                         messages,
995                         "MESSAGE_CANDIDATE_PK", //NOI18N
996
candidatePK.getName()));
997
998                 Integer JavaDoc pre = candidatePK.getPrecision();
999                 if (null != candidatePK && !candidatePK.isNumericType()) {
1000                    candidatePK = null;
1001                }
1002                if (null != candidatePK && (null != pre) && pre.intValue() < MINIMUM_PRECISION) {
1003                    candidatePK = null;
1004                }
1005            }
1006        }
1007        return candidatePK;
1008    }
1009
1010    /**
1011     * Converts column pair information from sun-cmp-mappings.xml into
1012     * column pair elements from the JDO mapping definition.
1013     *
1014     * @param pairs ColumnPair information from sun-cmp-mappings.xml.
1015     * @param primaryTableName Name of the bean's primary table.
1016     * @param schema dbschema information for all beans.
1017     * @param knownTables A Map which contains primary and secondary tables
1018     * for beans in the set. Keys: table names Values: TableElement objects
1019     * @param tablesOfBean contains primary table and
1020     * secondary tables of the bean corresponding to the <code>mre</code>'s
1021     * declaring class.
1022     * @param relationId Relationship id used to name the ColumnPairElements.
1023     * @param mre Mapping relationship element (== JDO information).
1024     * @return Collection of column elements, including all columns from the
1025     * current cmr definition that are part of the primary table.
1026     * @throws DBException
1027     * @throws ModelException
1028     * @throws ConversionException
1029     */

1030    private Collection JavaDoc convertToColumnPairElements(ColumnPair pairs[],
1031                                                   String JavaDoc primaryTableName,
1032                                                   SchemaElement schema,
1033                                                   Map JavaDoc knownTables,
1034                                                   List JavaDoc tablesOfBean,
1035                                                   String JavaDoc relationId,
1036                                                   MappingRelationshipElement mre)
1037            throws DBException, ModelException, ConversionException {
1038
1039        Collection JavaDoc primaryTableColumns = new ArrayList JavaDoc();
1040        boolean isJoin = false;
1041
1042        for (int i = 0; null != pairs && i < pairs.length; i++) {
1043            ColumnPair pair = pairs[i];
1044            ColumnPairElement cpe = new ColumnPairElement();
1045            boolean localSet = false;
1046
1047            cpe.setName(DBIdentifier.create(relationId + "_ColumnPair_" + i)); //NOI18N
1048

1049            for (int j = 0; j < 2; j++) {
1050                String JavaDoc columnName = pair.getColumnName(j);
1051                String JavaDoc sourceTableName = getTableName(columnName,
1052                    primaryTableName);
1053                String JavaDoc sourceColumnName = getColumnName(columnName);
1054                TableElement sourceTableEl = getTableElement(sourceTableName,
1055                    knownTables, schema);
1056                ColumnElement ce = getColumnElement(sourceTableEl,
1057                    DBIdentifier.create(sourceColumnName), helper);
1058                ce.toString();
1059
1060                // tablesOfBean stores the primary table and the secondary
1061
// tables for the bean.
1062
// It can be used for checking join table if sourceTableName
1063
// is not in the tablesOfBean.
1064
// If it is join table, should use addLocalColumn instead of
1065
// addColumn.
1066
if (j == 0) {
1067                    if (tablesOfBean.contains(sourceTableName)) {
1068                        localSet = true;
1069
1070                        // Remember local columns for lower bound determination.
1071
primaryTableColumns.add(ce);
1072                    }
1073                    else {
1074
1075                        // join table
1076
isJoin = true;
1077                        localSet = false;
1078                    }
1079                }
1080
1081                if (cpe.getLocalColumn() == null) {
1082                    cpe.setLocalColumn(ce);
1083                }
1084                else {
1085                    cpe.setReferencedColumn(ce);
1086                }
1087            }
1088
1089            if (localSet) {
1090                if (!isJoin) {
1091                    mre.addColumn(cpe);
1092                }
1093                else {
1094                    mre.addLocalColumn(cpe);
1095                }
1096            }
1097            else if (isJoin) {
1098                mre.addAssociatedColumn(cpe);
1099            }
1100        }
1101
1102        return primaryTableColumns;
1103    }
1104
1105    /**
1106     * If a non-collection relationship field is mapped to a
1107     * non-nullable column, the lower bound of the relationship might
1108     * be set to 1. To set the lower bound, we have to determine the
1109     * dependent side of the relationship. We set the lower bound to 1
1110     * based on the following rules:
1111     *
1112     * <ul>
1113     * <li>If the non-nullable column is not part of the primary key.</li>
1114     * <li>If the local side has got a foreign key.</li>
1115     * <li>If the local columns are a real subset of the primary key.</li>
1116     * <li>If the user specified the local side for cascade delete.</li>
1117     * </ul>
1118     *
1119     * @param rel JDO relationship information being constructed.
1120     * @param primaryTableColumns Collection of all columns from the
1121     * current cmr definition that are part of the primary table.
1122     * @param primaryTableName Name of the bean's primary table.
1123     * @param knownTables A Map which contains primary and secondary tables
1124     * for beans in the set. Keys: table names Values: TableElement objects
1125     * @param schema dbschema information for all beans.
1126     * @param beanName Bean name.
1127     * @param fieldName Relationship field name.
1128     * @throws ModelException
1129     * @throws DBException
1130     * @throws ConversionException
1131     */

1132    private void setLowerBound(RelationshipElement rel,
1133                               Collection JavaDoc primaryTableColumns,
1134                               String JavaDoc primaryTableName,
1135                               SchemaElement schema,
1136                               Map JavaDoc knownTables,
1137                               String JavaDoc beanName,
1138                               String JavaDoc fieldName)
1139                               throws ModelException, DBException,
1140                               ConversionException {
1141
1142        rel.setLowerBound(0);
1143        if (logger.isLoggable(Logger.FINE))
1144            logger.fine(
1145                I18NHelper.getMessage(
1146                messages,
1147                "MESSAGE_LWB_NULL", //NOI18N
1148
beanName, fieldName));
1149
1150        if (1 == rel.getUpperBound() && null != primaryTableName) {
1151
1152            boolean isPartOfPrimaryKey = false;
1153            TableElement primaryTable = getTableElement(primaryTableName,
1154                knownTables, schema);
1155            UniqueKeyElement pk = primaryTable.getPrimaryKey();
1156            ForeignKeyElement fks[] = primaryTable.getForeignKeys();
1157            Iterator JavaDoc iter = primaryTableColumns.iterator();
1158
1159            while (iter.hasNext() && 0 == rel.getLowerBound()) {
1160                ColumnElement ce = (ColumnElement) iter.next();
1161                if (!ce.isNullable()) {
1162                    isPartOfPrimaryKey |= isPartOfPrimaryKey(ce, pk);
1163
1164                    if (!isPartOfPrimaryKey) {
1165                        // We suppose that all primary key columns are non-nullable.
1166
// If the non-nullable column is not part of the primary key,
1167
// this is the dependent side.
1168
rel.setLowerBound(1);
1169                        if (logger.isLoggable(Logger.FINE))
1170                            logger.fine(
1171                                I18NHelper.getMessage(
1172                                messages,
1173                                "MESSAGE_LWB_NOPK", //NOI18N
1174
beanName, fieldName));
1175                    }
1176                    // Check the foreign key constraint
1177
else if (isPartOfForeignKey(ce, fks)) {
1178                        // If the non-nullable column is part of the foreign key,
1179
// this is the dependent side.
1180
rel.setLowerBound(1);
1181                        if (logger.isLoggable(Logger.FINE))
1182                            logger.fine(
1183                                I18NHelper.getMessage(
1184                                messages,
1185                                "MESSAGE_LWB_FK", //NOI18N
1186
beanName, fieldName));
1187                    }
1188                }
1189            }
1190
1191            if (0 == rel.getLowerBound() && isPartOfPrimaryKey) {
1192                // The lower bound is still unset and all local columns
1193
// are part of the primary key.
1194
if (primaryTableColumns.size() < pk.getColumns().length) {
1195                    // The local columns are a real subset of the primary key.
1196
// ==> This must be the dependent side.
1197
rel.setLowerBound(1);
1198                    if (logger.isLoggable(Logger.FINE))
1199                        logger.fine(
1200                            I18NHelper.getMessage(
1201                            messages,
1202                            "MESSAGE_LWB_PKSUBSET", //NOI18N
1203
beanName, fieldName));
1204                }
1205                else if (isCascadeDelete(beanName, fieldName)) {
1206                    // This relationship side is marked as dependent side by the user.
1207
rel.setLowerBound(1);
1208                    if (logger.isLoggable(Logger.FINE))
1209                        logger.fine(
1210                            I18NHelper.getMessage(
1211                            messages,
1212                            "MESSAGE_LWB_CASCADE", //NOI18N
1213
beanName, fieldName));
1214                }
1215                else {
1216                    if (logger.isLoggable(Logger.FINE))
1217                        logger.fine(
1218                            I18NHelper.getMessage(
1219                            messages,
1220                            "MESSAGE_LWB_NODEPENDENT", //NOI18N
1221
beanName, fieldName));
1222                }
1223            }
1224        }
1225    }
1226
1227    /**
1228     * Looks up the table element for <code>tableName</code> in the
1229     * table element cache <code>knownTables</code>. If the table
1230     * element is not found, the table name is looked up in the
1231     * database schema and registered in the cache.
1232     *
1233     * @param tableName Table name.
1234     * @param knownTables A Map which contains primary and secondary tables
1235     * for beans in the set. Keys: table names Values: TableElement objects
1236     * @param schema dbschema information for all beans.
1237     * @return Table element for table <code>tableName</code>.
1238     * @exception DBException
1239     * @exception ConversionException
1240     */

1241    private TableElement getTableElement(String JavaDoc tableName,
1242                                         Map JavaDoc knownTables,
1243                                         SchemaElement schema)
1244        throws DBException, ConversionException {
1245
1246        TableElement te = (TableElement) knownTables.get(tableName);
1247
1248        if (null == te) {
1249            te = getTableElement(schema, DBIdentifier.create(tableName),
1250                helper);
1251            knownTables.put(tableName, te);
1252        }
1253
1254        return te;
1255    }
1256
1257    /**
1258     * Checks, if the column <code>ce</code> is part of the
1259     * primary key <code>pk</code>.
1260     * RESOLVE: Method isPrimaryKeyColumn in ModelValidator
1261     * implements similar functionality.
1262     *
1263     * @param ce Column element for the column to be tested.
1264     * @param pk Primary key element. The column to be tested
1265     * <b>must</b> be defined in the same table.
1266     * @return True, if the column is part of the primary key,
1267     * false otherwise.
1268     * @see com.sun.jdo.api.persistence.model.util.ModelValidator
1269     */

1270    private boolean isPartOfPrimaryKey(ColumnElement ce, UniqueKeyElement pk) {
1271        return null != pk && ce.equals(pk.getColumn(ce.getName()));
1272    }
1273
1274    /**
1275     * Checks, if the column <code>ce</code> is part of one
1276     * of the foreign key constraints defined in <code>fks</code>.
1277     * RESOLVE: Method matchesFK in ModelValidator implements similar
1278     * functionality.
1279     *
1280     * @param ce Column element for the column to be tested.
1281     * @param fks Array of foreign key elements. The column to be
1282     * tested <b>must</b> be defined in the same table.
1283     * @return True, if the column is part of one of the foreign keys,
1284     * false otherwise.
1285     * @see com.sun.jdo.api.persistence.model.util.ModelValidator
1286     */

1287    private boolean isPartOfForeignKey(ColumnElement ce,
1288        ForeignKeyElement[] fks) {
1289
1290        // RESOLVE: Column ce might be included in multiple foreign
1291
// keys. The foreign key check applies to ALL relationships
1292
// mapped to column ce. How can we find out, that a foreign
1293
// key matches exactly the relationship being checked here?
1294

1295        if (fks != null) {
1296            for (int index = 0; index < fks.length; index++) {
1297                if (ce.equals(fks[index].getColumn(ce.getName()))) {
1298                    // The current ce is part of the foreign key.
1299
return true;
1300                }
1301            }
1302        }
1303
1304        return false;
1305    }
1306
1307    /**
1308     * Returns the cascade delete setting for the current relationship side.
1309     * The ConversionHelper interface provides cascade delete information
1310     * for the related side only.
1311     *
1312     * @param beanName Bean name.
1313     * @param fieldName Relationship field name.
1314     * @return True, if the current relationship side is marked for cascade delete,
1315     * false otherwise.
1316     */

1317    private boolean isCascadeDelete(String JavaDoc beanName, String JavaDoc fieldName) {
1318        final String JavaDoc beanInField = helper.getRelationshipFieldContent(beanName, fieldName);
1319        final String JavaDoc inverseField = helper.getInverseFieldName(beanName,
1320            fieldName);
1321
1322        return (null != beanInField && null != inverseField) ?
1323                helper.relatedObjectsAreDeleted(beanInField, inverseField) : false;
1324    }
1325
1326    /**
1327     * Registers relationship element <code>rel</code> in the cache
1328     * mapping field names to inverse relationship elements. The
1329     * inverse bean- and field names for the registration are
1330     * determined with the conversion helper. Returns the
1331     * relationship element for the inverse field, if this field has
1332     * been already processed, null otherwise.
1333     *
1334     * @param rel JDO relationship information being constructed.
1335     * @param beanName Bean name.
1336     * @param fieldName Relationship field name.
1337     * @return The relationship element for the inverse field, if this field
1338     * has been already processed, null otherwise.
1339     * @throws ModelException
1340     */

1341    private RelationshipElement registerInverseRelationshipElement(
1342        RelationshipElement rel, String JavaDoc beanName, String JavaDoc fieldName)
1343        throws ModelException {
1344
1345        String JavaDoc key = beanName + "." + fieldName; //NOI18N
1346
RelationshipElement inverse = (RelationshipElement) inverseRelationships.get(key);
1347
1348        if (null == inverse) {
1349            final String JavaDoc beanInField = helper.getRelationshipFieldContent(
1350                beanName, fieldName);
1351            final String JavaDoc inverseField = helper.getInverseFieldName(beanName,
1352                fieldName);
1353
1354            if (null != beanInField && null != inverseField) {
1355                key = beanInField + "." + inverseField; //NOI18N
1356
inverseRelationships.put(key, rel);
1357            }
1358        }
1359        else {
1360            rel.changeInverseRelationship(inverse);
1361            inverse.changeInverseRelationship(rel);
1362        }
1363
1364        return inverse;
1365    }
1366
1367    /**
1368     * Sets the upper bound for relationship element <code>rel</code>
1369     * depending on the upper bound information from the deployment
1370     * descriptor and defines the element class for collection
1371     * relationship fields.
1372     *
1373     * @param rel JDO relationship information being constructed.
1374     * @param beanName Bean name.
1375     * @param fieldName Relationship field name.
1376     * @throws ModelException
1377     * @throws ConversionException
1378     */

1379    private void setUpperBound(RelationshipElement rel,
1380                               String JavaDoc beanName, String JavaDoc fieldName)
1381        throws ModelException, ConversionException {
1382
1383        String JavaDoc beanInField = helper.getRelationshipFieldContent(beanName,
1384            fieldName);
1385        String JavaDoc classInJdoField = helper.getMappedClassName(beanInField);
1386        String JavaDoc multiplicity = helper.getMultiplicity(beanName, fieldName);
1387
1388        // Set the upper bound.
1389
if (multiplicity.equals(helper.MANY)) {
1390            rel.setUpperBound(Integer.MAX_VALUE);
1391            rel.setElementClass(classInJdoField);
1392            String JavaDoc collectionClass = helper.getRelationshipFieldType(beanName,
1393                fieldName);
1394            if (types.contains(collectionClass)) {
1395                rel.setCollectionClass(collectionClass);
1396            }
1397            else {
1398                rel.setCollectionClass(null);
1399                if (logger.isLoggable(Logger.WARNING))
1400                    logger.warning(
1401                        I18NHelper.getMessage(
1402                        messages,
1403                        "WARN_INVALID_RELATIONSHIP_FIELDTYPE", //NOI18N
1404
beanName, fieldName, collectionClass));
1405            }
1406        }
1407        else if (multiplicity.equals(helper.ONE)) {
1408            rel.setUpperBound(1);
1409            // Fix later. This code should be removed because in one side
1410
// setElementClass should not be called.
1411
// This line of code is for bug 4665051 which is plugin bug.
1412
// It is likely that bug 4665051 indicates that there is code
1413
// in the plugin which depends on the element class being set
1414
// for a one side relationship.
1415
rel.setElementClass(classInJdoField);
1416        }
1417        else {
1418            throw new ConversionException(
1419                I18NHelper.getMessage(
1420                messages,
1421                "ERR_BAD_MULTIPLICTY", //NOI18N
1422
multiplicity, rel.getName()));
1423        }
1424    }
1425
1426    /**
1427     * Sets the cascade delete option for relationship element
1428     * <code>rel</code> depending on the information from the
1429     * deployment descriptor. While the deployment descriptor
1430     * specifies cascade delete option on the dependent side, JDO
1431     * specifies it on the primary side. For this reason, the
1432     * information must be "switched".
1433     *
1434     * @param rel JDO relationship information being constructed.
1435     * @param beanName Bean name.
1436     * @param fieldName Relationship field name.
1437     * @throws ModelException
1438     */

1439    private void setCascadeDeleteAction(RelationshipElement rel,
1440                                        String JavaDoc beanName, String JavaDoc fieldName)
1441            throws ModelException {
1442
1443        if (helper.relatedObjectsAreDeleted(beanName, fieldName)) {
1444            if (logger.isLoggable(Logger.FINE))
1445                logger.fine(
1446                    I18NHelper.getMessage(
1447                    messages,
1448                    "MESSAGE_REL_OBJ_DEL", //NOI18N
1449
beanName, fieldName));
1450            rel.setDeleteAction(RelationshipElement.CASCADE_ACTION);
1451        }
1452    }
1453
1454    private SchemaElement setDatabaseRoot(MappingClassElement foo,
1455        String JavaDoc schemaElementValue, boolean strict)
1456        throws ModelException, DBException, ConversionException {
1457        SchemaElement bar = null;
1458        if (null != classLoader) {
1459            if (loadedSchema.get(schemaElementValue) == null) {
1460                SchemaElement.removeFromCache(schemaElementValue);
1461                loadedSchema.put(schemaElementValue, schemaElementValue);
1462            }
1463            bar = SchemaElement.forName(schemaElementValue,classLoader);
1464        }
1465        else
1466            bar = SchemaElement.forName(schemaElementValue);
1467        if (strict) {
1468            if (bar == null) {
1469                // Prepare for a schema related error
1470
throw new ConversionException(
1471                    I18NHelper.getMessage(
1472                    messages,
1473                    "ERR_CANNOT_FIND_SCHEMA", //NOI18N
1474
new Object JavaDoc [] {schemaElementValue, classLoader}));
1475            }
1476        }
1477        else {
1478            if (null == bar) {
1479                // conjure up a schema element and set its name...
1480
// need to create a dummy for invalid mappings because the
1481
// mapping model setter methods don't accept strings even
1482
// though that is what they store.
1483
bar = new SchemaElement();
1484                DBIdentifier n = DBIdentifier.create(schemaElementValue);
1485                n.setFullName(schemaElementValue);
1486                bar.setName(n);
1487            }
1488        }
1489        foo.setDatabaseRoot(bar);
1490        return bar;
1491    }
1492
1493    private String JavaDoc getTableName(String JavaDoc columnName, String JavaDoc defaultName) {
1494        String JavaDoc retVal = defaultName;
1495        int len = columnName.lastIndexOf('.');
1496        if (len > 0)
1497            retVal = columnName.substring(0,len);
1498        return retVal;
1499    }
1500
1501    private String JavaDoc getColumnName(String JavaDoc columnName) {
1502        String JavaDoc retVal = columnName;
1503        int len = columnName.lastIndexOf('.');
1504        if (len > 0)
1505            retVal = columnName.substring(len+1);
1506        return retVal;
1507    }
1508
1509    /** Map the secondary tables of the bean.
1510     * @param mapping The schema2beans object that represents the mapping
1511     * for a particular bean.
1512     * @param mce Mapping class element
1513     * @param schema dbschema information for all beans
1514     * @param knownTables A Map which contains primary and secondary tables
1515     * for beans in the set. Keys: table names Values: TableElement objects
1516     * @param tablesOfBean contains primary table and
1517     * secondary tables of the bean corresponding to the <code>mapping</code>
1518     * @throws ModelException
1519     * @throws DBException
1520     * @throws ConversionException
1521     */

1522    private void mapSecondaryTables(EntityMapping mapping,
1523                                    MappingClassElement mce,
1524                                    SchemaElement schema,
1525                                    Map JavaDoc knownTables,
1526                                    List JavaDoc tablesOfBean)
1527        throws ModelException, DBException, ConversionException {
1528
1529        SecondaryTable [] tableList = mapping.getSecondaryTable();
1530        List JavaDoc tl = mce.getTables();
1531
1532        if (null != tl && tl.size() > 0 && null != tl.get(0)) {
1533            MappingTableElement primary = (MappingTableElement) tl.get(0);
1534
1535            for (int i = 0; null != tableList && i < tableList.length; i++) {
1536                String JavaDoc tn = tableList[i].getTableName();
1537                if (StringHelper.isEmpty(tn))
1538                    continue;
1539                TableElement te = getTableElement(schema,
1540                    DBIdentifier.create(tn.trim()), helper);
1541                ColumnPair pairs[] = tableList[i].getColumnPair();
1542                int len = 0;
1543                if (null != pairs)
1544                    len = pairs.length;
1545                if (0 == len) {
1546                    if (logger.isLoggable(Logger.WARNING))
1547                        logger.warning(
1548                            I18NHelper.getMessage(
1549                            messages,
1550                            "WARN_NO_PAIRS", //NOI18N
1551
new Object JavaDoc [] {mce, tn}));
1552                    continue;
1553                }
1554                MappingReferenceKeyElement mrke = mce.addSecondaryTable(
1555                    primary,te);
1556                for (int j = 0; null != pairs && j < pairs.length; j++) {
1557                    ColumnPairElement cpe = new ColumnPairElement();
1558                    DBIdentifier dbId = DBIdentifier.create("SecondaryTable"+j); //NOI18N
1559
cpe.setName(dbId);
1560                    ColumnPair pair = pairs[j];
1561                    for (int k = 0; k < 2; k++) {
1562                        String JavaDoc nameOne = pair.getColumnName(k);
1563                        String JavaDoc sourceTableName = getTableName(
1564                            nameOne.trim(),
1565                            primary.getName().toString());
1566                        String JavaDoc sourceColumnName = getColumnName(nameOne);
1567                        dbId = DBIdentifier.create(sourceTableName);
1568                        TableElement sourceTableEl = getTableElement(schema,
1569                            dbId, helper);
1570                        dbId = DBIdentifier.create(sourceColumnName);
1571                        ColumnElement ce = getColumnElement(sourceTableEl,
1572                            dbId, helper);
1573                        if (k == 0)
1574                            cpe.setLocalColumn(ce);
1575                        else
1576                            cpe.setReferencedColumn(ce);
1577                    }
1578                    mrke.addColumnPair(cpe);
1579                }
1580                knownTables.put(tn,te);
1581                tablesOfBean.add(tn);
1582            }
1583        }
1584        else
1585            throw new ConversionException(
1586                    I18NHelper.getMessage(
1587                    messages,
1588                    "WARN_NOT_MAPPED_TO_PRIMARY", //NOI18N
1589
mce.getName()));
1590    }
1591
1592    private boolean validateField(MappingClassElement mce, String JavaDoc beanName,
1593        String JavaDoc fieldName, boolean throwEx) throws ConversionException {
1594        MappingFieldElement mfe = mce.getField(fieldName);
1595        if (null != mfe) {
1596            if (throwEx)
1597                throw new ConversionException(
1598                    I18NHelper.getMessage(
1599                    messages,
1600                    "ERR_FIELD_MAPPED_TWICE", //NOI18N
1601
beanName, fieldName));
1602            else
1603                return false;
1604        }
1605        if (!helper.hasField(beanName,fieldName)) {
1606            if (throwEx)
1607                throw new ConversionException(
1608                I18NHelper.getMessage(
1609                messages,
1610                "ERR_INVALID_FIELD", //NOI18N
1611
beanName, fieldName));
1612            else
1613                return false;
1614        }
1615        return true;
1616    }
1617
1618    // loop through the mappings to create a hash from bean name to em objects
1619
private Map JavaDoc getBean2EntityMappingMap(SunCmpMapping beanSet) {
1620        Map JavaDoc retVal = new HashMap JavaDoc();
1621        EntityMapping [] entityMappingsInSet = beanSet.getEntityMapping();
1622        int len = 0;
1623        if (null != entityMappingsInSet)
1624            len = entityMappingsInSet.length;
1625        for (int k = 0; k < len; k++) {
1626            EntityMapping anEntityMapping = entityMappingsInSet[k];
1627            String JavaDoc beanName = anEntityMapping.getEjbName();
1628            beanName.trim().charAt(0);
1629            retVal.put(beanName,anEntityMapping);
1630        }
1631        return retVal;
1632    }
1633
1634    // for each cmr field in the mapping
1635
// determine is the inverse is a generated field
1636
// create the mapping data for this generated field
1637
private boolean completeCmrMappings(SunCmpMapping beanSet)
1638        throws ConversionException {
1639
1640        // loop through the mappings to create a hash from bean name to em objects
1641
Map JavaDoc beanName2EntityMapping = getBean2EntityMappingMap(beanSet);
1642        Iterator JavaDoc emIter = beanName2EntityMapping.values().iterator();
1643        boolean retVal = false;
1644        String JavaDoc errorMsg = I18NHelper.getMessage(
1645            messages,
1646            "ERR_BAD_CONVERSION_HELPER"); //NOI18N
1647

1648        while (emIter.hasNext()) {
1649            EntityMapping anEM = (EntityMapping) emIter.next();
1650            String JavaDoc beanName = anEM.getEjbName();
1651            String JavaDoc pt = anEM.getTableName();
1652            CmrFieldMapping[] cmrsInEM = anEM.getCmrFieldMapping();
1653            int len = 0;
1654            if (null != cmrsInEM && !StringHelper.isEmpty(beanName))
1655                len = cmrsInEM.length;
1656            for (int i = 0; i < len; i++) {
1657                String JavaDoc fieldName = cmrsInEM[i].getCmrFieldName();
1658                if (!helper.hasField(beanName, fieldName)) {
1659                    throw new ConversionException(I18NHelper.getMessage(
1660                        messages,
1661                        "WARN_INVALID_CMRFIELD", //NOI18N
1662
beanName, fieldName));
1663                }
1664                fieldName.trim().charAt(0);
1665                String JavaDoc otherField = helper.getInverseFieldName(beanName,
1666                    fieldName);
1667                if (otherField == null) {
1668                    throw new ConversionException(errorMsg);
1669                }
1670                String JavaDoc otherBean = helper.getRelationshipFieldContent(beanName,
1671                    fieldName);
1672                if (otherBean == null) {
1673                    throw new ConversionException(errorMsg);
1674                }
1675
1676                if (helper.isGeneratedRelationship(otherBean,otherField)) {
1677                    retVal = true;
1678                    String JavaDoc otherBeanName = helper.getRelationshipFieldContent(
1679                        beanName, fieldName);
1680                    otherBeanName.trim().charAt(0);
1681                    EntityMapping otherEM =
1682                        (EntityMapping) beanName2EntityMapping.get(
1683                            otherBeanName);
1684                    CmrFieldMapping inverseMapping = new CmrFieldMapping();
1685                    inverseMapping.setCmrFieldName(otherField);
1686                    inverseMapping.setColumnPair(
1687                        reverseCPArray(cmrsInEM[i].getColumnPair(), pt,
1688                            beanName, fieldName));
1689                    otherEM.addCmrFieldMapping(inverseMapping);
1690                }
1691            }
1692        }
1693        return retVal;
1694    }
1695
1696    private ColumnPair[] reverseCPArray(ColumnPair[] cpa, String JavaDoc primeTable,
1697        String JavaDoc beanName, String JavaDoc fieldName)
1698        throws ConversionException {
1699        int len = (cpa == null) ? 0 : cpa.length;
1700        if (len == 0) {
1701            throw new ConversionException(
1702                I18NHelper.getMessage(
1703                messages,
1704                "ERR_COLUMN_PAIR_MISSING", //NOI18N
1705
beanName, fieldName));
1706        }
1707        ColumnPair [] retVal = new ColumnPair[len];
1708        for (int index = 0; index < len; index++) {
1709            retVal[index] = new ColumnPair();
1710            retVal[index].addColumnName(
1711                qualify(primeTable,cpa[index].getColumnName(1)));
1712            retVal[index].addColumnName(
1713                qualify(primeTable,cpa[index].getColumnName(0)));
1714        }
1715        return retVal;
1716    }
1717
1718    private String JavaDoc qualify(String JavaDoc tn, String JavaDoc cn) {
1719        int tmp = cn.indexOf('.');
1720        String JavaDoc retVal = cn;
1721        if (-1 == tmp)
1722            retVal = tn + "." + cn; // NOI18N
1723
return retVal;
1724    }
1725
1726    private TableElement getTableElement(SchemaElement schema,
1727        DBIdentifier dbId, ConversionHelper helper)
1728        throws DBException, ConversionException {
1729
1730        TableElement retVal = ((schema != null) ?
1731            schema.getTable(dbId) : null);
1732
1733        if (null == retVal && !helper.ensureValidation()) {
1734            // Need to create a dummy for invalid mappings because
1735
// the mapping model setter methods don't accept
1736
// strings even though that is what they store.
1737
// Create the table and add it to the knownTables list
1738
// for later
1739

1740            retVal = new TableElement();
1741            retVal.setName(dbId);
1742            retVal.setDeclaringSchema(schema);
1743            org.netbeans.modules.dbschema.UniqueKeyElement tkey =
1744                new org.netbeans.modules.dbschema.UniqueKeyElement();
1745            ColumnElement fakeKeyCol = new ColumnElement();
1746            fakeKeyCol.setName(DBIdentifier.create(retVal.getName().getName()+ "."+"fookeyng")); //NOI18N
1747

1748            // Type numeric=2
1749
fakeKeyCol.setType(2);
1750            fakeKeyCol.setPrecision(new Integer JavaDoc(MINIMUM_PRECISION));
1751            tkey.setPrimaryKey(true);
1752            tkey.addColumn(fakeKeyCol);
1753            retVal.addColumn(fakeKeyCol);
1754            retVal.addKey(tkey);
1755        }
1756        if (retVal == null) {
1757            throw new ConversionException(
1758                I18NHelper.getMessage(
1759                messages,
1760                "ERR_INVALID_TABLE", //NOI18N
1761
new Object JavaDoc [] {dbId.getName(), schema}));
1762        }
1763        return retVal;
1764    }
1765
1766    private ColumnElement getColumnElement(TableElement sourceTableEl,
1767        DBIdentifier sourceColumnName, ConversionHelper helper)
1768        throws DBException, ConversionException {
1769
1770        ColumnElement aCol = sourceTableEl.getColumn(sourceColumnName);
1771        if (null == aCol && !helper.ensureValidation()) {
1772            aCol = new ColumnElement();
1773            aCol.setName(DBIdentifier.create(sourceTableEl.getName().toString()+"."+sourceColumnName.toString())); // NOI18N
1774
aCol.setDeclaringTable(sourceTableEl);
1775            aCol.setNullable(true);
1776        }
1777        if (aCol == null) {
1778            throw new ConversionException(
1779                I18NHelper.getMessage(
1780                messages,
1781                "ERR_INVALID_COLUMN", //NOI18N
1782
new Object JavaDoc [] {sourceColumnName, sourceTableEl}));
1783        }
1784        return aCol;
1785    }
1786
1787    private MappingFieldElement createUnmappedField(MappingClassElement mce,
1788        String JavaDoc beanName, String JavaDoc fieldName)
1789        throws ModelException {
1790
1791        PersistenceClassElement pce = ((MappingClassElementImpl)mce).
1792            getPersistenceElement();
1793        PersistenceFieldElementImpl pfei =
1794            new PersistenceFieldElementImpl(fieldName);
1795        PersistenceFieldElement pfe =
1796            new PersistenceFieldElement(pfei, pce);
1797
1798        pfe.setKey(helper.isKey(beanName,fieldName,false));
1799        pce.addField(pfe);
1800        MappingFieldElement mfe = new MappingFieldElementImpl(fieldName, mce);
1801        return mfe;
1802    }
1803
1804    /**
1805     * Set fetch group level for mapping field and mapping relationship
1806     * element. If there is fetch level information, then set mapping field
1807     * element with the level. If there is no fetch group level information,
1808     * set mapping field element to GROUP_NONE if it is mapping relationship
1809     * element or blob type field otherwise set to GROUP_DEFAULT.
1810     * @param fw An object having fetch group level information
1811     * @param mfe An mapping field or mapping relationship element to be set
1812     * fetch group level
1813     * @param fieldMappedToABlob boolean type to indicate that field is blob
1814     * type or not
1815     * @throws ModelException
1816     * @throws ConversionException
1817     */

1818    private void setFetchGroup(FetchedWith fw, MappingFieldElement mfe,
1819        String JavaDoc beanName, boolean fieldMappedToABlob)
1820        throws ModelException, ConversionException {
1821        if (null != fw) {
1822            boolean tryLevel = false;
1823            int level = 0;
1824            try {
1825                level = fw.getLevel();
1826                tryLevel = true;
1827            }
1828            catch (RuntimeException JavaDoc e) {
1829                // If there is no level set, schema2beans throws
1830
// RuntimeException.
1831
// Need to do more investigation on why throws this exception.
1832
// it is very likely that there is no level set, which would
1833
// throw an exception here.. Which we are going to ignore
1834
}
1835            if (tryLevel) {
1836                if (level < 1) {
1837                    throw new ConversionException(
1838                        I18NHelper.getMessage(
1839                        messages,
1840                        "ERR_INVALID_FG_LEVEL", //NOI18N
1841
beanName, mfe.getName(), ""+level)); //NOI18N
1842
}
1843                mfe.setFetchGroup(level+1);
1844            }
1845            String JavaDoc ig = fw.getNamedGroup();
1846            if (null != ig) {
1847                Integer JavaDoc fgval = (Integer JavaDoc) namedGroups.get(ig);
1848                if (null == fgval) {
1849                    fgval = new Integer JavaDoc(groupCount--);
1850                    namedGroups.put(ig,fgval);
1851                }
1852                mfe.setFetchGroup(fgval.intValue());
1853            }
1854            if (fw.isNone())
1855                mfe.setFetchGroup(MappingFieldElement.GROUP_NONE);
1856            if (fw.isDefault())
1857                mfe.setFetchGroup(MappingFieldElement.GROUP_DEFAULT);
1858        }
1859        else {
1860            if (mfe instanceof MappingRelationshipElement)
1861                mfe.setFetchGroup(MappingFieldElement.GROUP_NONE);
1862            else {
1863                if (fieldMappedToABlob)
1864                    mfe.setFetchGroup(MappingFieldElement.GROUP_NONE);
1865                else
1866                    mfe.setFetchGroup(MappingFieldElement.GROUP_DEFAULT);
1867            }
1868        }
1869    }
1870
1871    private PersistenceFieldElement createPersistenceField(
1872        MappingClassElement mce, String JavaDoc fieldName) throws ModelException {
1873        PersistenceClassElement pce =
1874            ((MappingClassElementImpl)mce).getPersistenceElement();
1875        PersistenceFieldElementImpl pfei =
1876            new PersistenceFieldElementImpl(fieldName);
1877        PersistenceFieldElement pfe =
1878            new PersistenceFieldElement(pfei, pce);
1879        pce.addField(pfe);
1880        return pfe;
1881    }
1882
1883    private MappingFieldElement createMappingField(MappingClassElement mce,
1884        String JavaDoc fieldName, ColumnElement col) throws ModelException {
1885        MappingFieldElement mfe =
1886            new MappingFieldElementImpl(fieldName, mce);
1887        mce.addField(mfe);
1888        if (col != null)
1889            mfe.addColumn(col);
1890        return mfe;
1891    }
1892}
1893
1894
Popular Tags