KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdbc > JdbcRefMetaDataBuilder


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdbc;
13
14 import com.versant.core.metadata.parser.JdoExtension;
15 import com.versant.core.metadata.parser.JdoElement;
16 import com.versant.core.metadata.parser.JdoExtensionKeys;
17 import com.versant.core.metadata.ClassMetaData;
18 import com.versant.core.metadata.MetaDataBuilder;
19 import com.versant.core.metadata.MDStatics;
20 import com.versant.core.jdbc.metadata.*;
21
22 import java.util.ArrayList JavaDoc;
23
24 import com.versant.core.common.BindingSupportImpl;
25
26 /**
27  * This will analyze meta data for a reference to a PC class from an
28  * array of extensions. It is used for simple reference fields and for link
29  * tables. Instances of this class may only be used once.
30  */

31 public class JdbcRefMetaDataBuilder implements JdoExtensionKeys {
32
33     private JdbcMetaDataBuilder mdb;
34     private ClassMetaData targetClass;
35     private JdoElement context;
36     private String JavaDoc fieldName;
37
38     private ArrayList JavaDoc colsList = new ArrayList JavaDoc();
39
40     private boolean doNotCreateConstraint;
41     private String JavaDoc constraintName;
42     private int useJoin;
43     private JdbcColumn[] cols;
44
45     public JdbcRefMetaDataBuilder(ClassMetaData cmd, JdbcMetaDataBuilder mdb,
46             ClassMetaData targetClass, JdoElement context,
47             String JavaDoc fieldName, JdoExtension[] extensions, boolean quiet) {
48         this.mdb = mdb;
49         this.targetClass = targetClass;
50         this.context = context;
51         this.fieldName = fieldName;
52         try {
53             process(extensions);
54         } catch (RuntimeException JavaDoc e) {
55             cmd.addError(e, quiet);
56         }
57     }
58
59     private void process(JdoExtension[] extensions) {
60         JdbcClass target = (JdbcClass)targetClass.storeClass;
61         int pklen = 1;
62         if (target != null) {
63             JdbcTable table = target.table;
64             if (table != null) {
65                 JdbcColumn[] pk = table.pk;
66                 if (pk != null) {
67                     pklen = pk.length;
68                 }
69             }
70         }
71
72         boolean hadJdbcColumn = false;
73         if (extensions != null) {
74             JdbcColumn col;
75             int ne = extensions.length;
76             for (int i = 0; i < ne; i++) {
77                 JdoExtension e = extensions[i];
78                 switch (e.key) {
79
80                     case JDBC_COLUMN:
81                         if (hadJdbcColumn) break;
82                         if (pklen > 1) {
83                             throw BindingSupportImpl.getInstance().runtime("jdbc-column extensions must be nested in jdbc-ref " +
84                                     "extensions as " + targetClass.qname + " has " +
85                                     "composite primary key\n" + e.getContext());
86                         }
87                         if (target != null) {
88                             colsList.add(mdb.createColumn(extensions,
89                                     target.table.pk[0]));
90                         } else { // not a jdbc class
91
colsList.add(mdb.createColumn(extensions,
92                                     fieldName, String JavaDoc.class));
93                         }
94                         hadJdbcColumn = true;
95                         break;
96
97                     case JDBC_REF:
98                         if (targetClass.top.identityType != MDStatics.IDENTITY_TYPE_APPLICATION) {
99                             throw BindingSupportImpl.getInstance().runtime(
100                                     "The jdbc-ref extension may only be used here " +
101                                     "when referencing an application identity class\n" +
102                                     e.getContext());
103                         }
104                         String JavaDoc fname = e.getString();
105                         JdbcSimpleField pkf = target.findPkField(fname);
106                         if (pkf == null) {
107                             throw BindingSupportImpl.getInstance().runtime("Primary key field '" + fname + "' not found on " +
108                                     target.cmd.qname + "\n" + e.getContext());
109                         }
110                         col = mdb.findColumn(colsList, pkf);
111                         if (col != null) {
112                             throw BindingSupportImpl.getInstance().runtime(
113                                     "Duplicate jdbc-ref extension\n" + e.getContext());
114                         }
115                         col = mdb.createColumn(e.nested,
116                                 findColForPkField(pkf));
117                         col.refField = pkf;
118                         colsList.add(col);
119                         break;
120
121                     case JDBC_USE_JOIN:
122                         useJoin = e.getEnum(mdb.jdbcMDE.USE_JOIN_ENUM);
123                         break;
124
125                     case JDBC_CONSTRAINT:
126                         constraintName = e.value;
127                         if (e.isNoValue()) doNotCreateConstraint = true;
128                         break;
129                     case JDBC_INDEX:
130                         //Handled
131
break;
132
133                     default:
134                         if (e.isJdbc()) {
135                             MetaDataBuilder.throwUnexpectedExtension(e);
136                         }
137                         break;
138                 }
139             }
140         }
141
142         // check the columns (if specified) or generate them if not
143
int nc = colsList.size();
144         if (target == null && nc == 0) {
145             colsList.add(
146                     mdb.createColumn(null, fieldName, String JavaDoc.class));
147             nc = 1;
148         }
149         if (nc == 0) {
150             JdbcColumn[] pks = target.table.pk;
151             if (pks != null) {
152                 int n = pks.length;
153                 for (int i = 0; i < n; i++) {
154                     JdbcColumn c = pks[i].copy();
155                     c.refField = pks[i].refField;
156                     colsList.add(c);
157                 }
158             }
159         } else {
160             if (pklen != nc) {
161                 throw BindingSupportImpl.getInstance().runtime("Class " + targetClass.qname + " has " + pklen +
162                         " primary key column(s) but only " + nc + " column(s) " +
163                         "have been declared\n" +
164                         context.getContext());
165             }
166             if (pklen > 1) { // make sure order of colsList matches ref table
167
cols = new JdbcColumn[nc];
168                 for (int i = 0; i < nc; i++) {
169                     JdbcColumn col = (JdbcColumn)colsList.get(i);
170                     cols[((JdbcClass)targetClass.top.storeClass).findPkFieldIndex(
171                             col.refField)] = col;
172                 }
173             }
174         }
175
176         if (cols == null) {
177             nc = colsList.size();
178             cols = new JdbcColumn[nc];
179             colsList.toArray(cols);
180         }
181
182         // make sure all the cols have pk=false and foreignKey=true
183
for (int i = cols.length - 1; i >= 0; i--) {
184             JdbcColumn c = cols[i];
185             c.pk = false;
186             c.foreignKey = true;
187         }
188     }
189
190     /**
191      * If pkf belongs to targetClass then return its column. Otherwise
192      * return the corresponding column from the tableClass for targetClass
193      * (i.e. the class that owns the table that targetClass is mapped to
194      * for vertical inheritance).
195      */

196     private JdbcColumn findColForPkField(JdbcSimpleField pkf) {
197         if (pkf.fmd.classMetaData == targetClass) return pkf.col;
198         JdbcColumn[] pk = ((JdbcClass)targetClass.storeClass).table.pk;
199         for (int i = pk.length - 1; i >= 0; i--) {
200             System.out.println("pk[" + i + "] = " + pk[i]);
201             if (pk[i].refField == pkf) return pk[i];
202         }
203         throw BindingSupportImpl.getInstance().internal("No column found in table " +
204                 "for " + targetClass.qname + " to match " + pkf.fmd.name);
205     }
206
207     public boolean isDoNotCreateConstraint() {
208         return doNotCreateConstraint;
209     }
210
211     public String JavaDoc getConstraintName() {
212         return constraintName;
213     }
214
215     public int getUseJoin() {
216         return useJoin;
217     }
218
219     public JdbcColumn[] getCols() {
220         return cols;
221     }
222
223     public ArrayList JavaDoc getColsList() {
224         return colsList;
225     }
226
227 }
228  
229
Popular Tags