1 2 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 ; 23 24 import com.versant.core.common.BindingSupportImpl; 25 26 31 public class JdbcRefMetaDataBuilder implements JdoExtensionKeys { 32 33 private JdbcMetaDataBuilder mdb; 34 private ClassMetaData targetClass; 35 private JdoElement context; 36 private String fieldName; 37 38 private ArrayList colsList = new ArrayList (); 39 40 private boolean doNotCreateConstraint; 41 private String constraintName; 42 private int useJoin; 43 private JdbcColumn[] cols; 44 45 public JdbcRefMetaDataBuilder(ClassMetaData cmd, JdbcMetaDataBuilder mdb, 46 ClassMetaData targetClass, JdoElement context, 47 String 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 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 { colsList.add(mdb.createColumn(extensions, 92 fieldName, String .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 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 break; 132 133 default: 134 if (e.isJdbc()) { 135 MetaDataBuilder.throwUnexpectedExtension(e); 136 } 137 break; 138 } 139 } 140 } 141 142 int nc = colsList.size(); 144 if (target == null && nc == 0) { 145 colsList.add( 146 mdb.createColumn(null, fieldName, String .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) { 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 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 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 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 getColsList() { 224 return colsList; 225 } 226 227 } 228 229 | Popular Tags |