1 22 23 package org.xquark.mapper.mapping; 24 25 26 import java.sql.SQLException ; 27 import java.util.*; 28 29 import org.xml.sax.SAXException ; 30 import org.xquark.mapper.RepositoryException; 31 import org.xquark.mapper.dbms.AbstractConnection; 32 import org.xquark.mapper.metadata.Repository; 33 import org.xquark.xpath.XTree; 34 35 36 39 public class RepositoryMapping extends XTree 40 implements MappingSet 41 { 42 private static final String RCSRevision = "$Revision: 1.1 $"; 43 private static final String RCSName = "$Name: $"; 44 45 48 52 55 private ArrayList tableMappingList = new ArrayList(); 56 57 61 private TableMapping[] tableMappings; 62 63 66 private TableMapping[] mostDependantFirst; 67 68 71 73 74 private HashMap tableMetadata = new HashMap(); 75 76 77 private HashMap typeMappings = null; 78 private Repository rep; 79 80 public RepositoryMapping(Repository rep) 81 { 82 this.rep = rep; 83 } 84 85 public Repository getRepository() 86 { 87 return rep; 88 } 89 90 public MappingNode addTypeNode(MappingNode node) 91 { 92 if (typeMappings == null) 93 typeMappings = new HashMap(); 94 typeMappings.put(node.getSchemaComponent(), node); 95 return node; } 97 98 public MappingNode getTypeNode(org.xquark.schema.Type type) 99 { 100 if (typeMappings == null) 101 return null; 102 return (MappingNode)typeMappings.get(type); 103 } 104 105 public void addTableMapping(TableMapping tm) 106 { 107 tableMappingList.add(tm); 108 } 109 110 public TableMapping getTableMapping(int index) 111 { 112 return tableMappings[index]; 113 } 114 115 public int getTableCount() 116 { 117 if (tableMappings == null) 118 return tableMappingList.size(); 119 else 120 return tableMappings.length; 121 } 122 123 125 public void register(MappingNode wNode, Mapping mapping) 126 { 127 if (mapping instanceof TableMapping) 129 { 130 for (MappingNode elt = wNode; 131 (elt != null) && elt.addMappingInScope((TableMapping)mapping); 132 elt = (MappingNode)elt.getParent()); 133 } 134 if (mapping instanceof ColumnMapping) 136 { 137 ColumnMapping column = (ColumnMapping)mapping; 138 if (column.getGenerator() instanceof ValueGenerator) { 140 MappingNode elt; 141 for ( elt = wNode; 142 (elt.getTableMappings() == null) || !elt.getTableMappings().contains(column.getTableMapping()); 143 elt = (MappingNode)elt.getParent()) 144 { 145 elt.setBuildable(false); 146 } 147 int tableAncestorDepth = elt.getDepth(); 148 for ( elt = wNode; 151 elt.getDepth() > tableAncestorDepth; elt = (MappingNode)elt.getParent()) 153 { 154 if ((elt.getBuilder() == null) || (tableAncestorDepth < elt.getBuilder().getDepth())) 155 elt.setBuilderDiff(elt.getDepth() - tableAncestorDepth); 156 } 157 } 158 } 159 160 wNode.register(mapping); 161 } 162 163 public String toString() 164 { 165 String ret = super.toString(); 166 if (typeMappings != null) 167 ret += "\nTable mappings list:\n" + tableMappings.toString(); 168 return ret; 169 } 170 171 172 177 public void checkRedundantTables() throws RepositoryException 178 { 179 MappingSetIterator it = new MappingSetIteratorImpl(tableMappings); 181 while (it.hasNext()) 182 { 183 BaseTableMappingImpl tm = (BaseTableMappingImpl)it.next().getTableMapping(); 184 185 if (!it.isTableFirstOccurence()) 187 { 188 TableMapping tf = tableMappings[it.getFirstOccurenceTableIndex()]; 189 190 tm.setTableShared(); 192 193 if (!areColumnArraysEquivalent( 195 tf.getJoinColumns(), 196 tm.getJoinColumns() 197 )) 198 throw new RepositoryException( 199 RepositoryException.NOT_ALLOWED, 200 "Multiple mappings defined on the same table(" 201 + tm.getTableName() 202 + ") must have the same key specification."); 203 204 if (tm.isShareable() && !( 206 areColumnArraysEquivalent(tm.getColumnMappings(), tf.getColumnMappings()) 207 && areColumnArraysEquivalent(tm.getSelectColumns(), tf.getSelectColumns()) 208 && areColumnArraysEquivalent(tm.getUpdateColumns(), tf.getUpdateColumns()))) 209 tm.setStatementsNotShareable(); 210 } 211 } 212 } 213 214 219 public Iterator joinTableIterator() 220 { 221 return new TableIterator(true); 222 } 223 224 public int getMappingStatementsCount() 228 { 229 return getTableCount(); 230 } 231 232 public MappingInfo getMappingStatements(int index) 233 { 234 return getTableMapping(index); 235 } 236 237 public MappingSetIterator getSortedTableMappingSetIterator(boolean mostDependantFirst) 238 { 239 return new MappingSetIteratorImpl(this.mostDependantFirst, !mostDependantFirst); 240 } 241 242 public MappingSetIterator getMappingSetIterator() 243 { 244 return new MappingSetIteratorImpl(tableMappings); 245 } 246 247 void initialize(AbstractConnection conn) throws SAXException 251 { 252 initializeArrays(conn); 253 } 254 255 TableMetaData getTableMetaData(String tableName, AbstractConnection conn) 256 throws SAXException 257 { 258 TableMetaData ret = (TableMetaData) tableMetadata.get(tableName); 259 if (ret == null) 260 { 261 try 262 { 263 if (conn.checkTable(tableName)) 264 { 265 ret = new TableMetaDataImpl(tableName, conn); 266 tableMetadata.put(tableName, ret); 267 } 268 } 269 catch (SQLException ex) 270 { 271 throw new SAXException ( 272 "Error while fetching table " + tableName + " metadata", 273 ex); 274 } 275 } 276 return ret; 277 } 278 private void initializeArrays(AbstractConnection conn) throws SAXException 282 { 283 tableMappings = (TableMapping[])tableMappingList.toArray(new TableMapping[tableMappingList.size()]); 285 tableMappingList = null; 286 287 288 TableMappingImpl tm = null; 290 for (int i = 0; i < tableMappings.length; i++) { 291 tm = (TableMappingImpl)tableMappings[i]; 292 if (!tm.isInitialized()) 295 tm.initialize(conn); 296 tm.initializeDependencies(); 297 } 298 299 mostDependantFirst = new TableMapping[tableMappings.length]; 301 System.arraycopy(tableMappings, 0, mostDependantFirst, 0, tableMappings.length); 302 Arrays.sort(mostDependantFirst, new Comparator() 303 { 304 public int compare(Object o1, Object o2) 305 { 306 BaseTableMappingImpl tm1 = (BaseTableMappingImpl)((MappingInfo)o1).getTableMapping(); 307 BaseTableMappingImpl tm2 = (BaseTableMappingImpl)((MappingInfo)o2).getTableMapping(); 308 return tm2.getDependencies().size() 309 - tm1.getDependencies().size(); 310 } 311 }); 312 } 313 314 319 private class TableIterator implements Iterator 320 { 321 MappingSetIterator iterator; 322 MappingInfo next = null; 323 boolean unclusteredOnly; 324 325 public TableIterator(boolean unclusteredOnly) 326 { 327 iterator = new MappingSetIteratorImpl(tableMappings); 328 this.unclusteredOnly = unclusteredOnly; 329 } 330 331 public TableIterator() 332 { 333 this(false); 334 } 335 336 public boolean hasNext() 337 { 338 while (next == null && iterator.hasNext()) 339 { 340 next = iterator.next(); 341 if (!keepCondition()) 342 next = null; 343 } 344 return next != null; 345 } 346 347 private boolean keepCondition() 348 { 349 return iterator.isTableFirstOccurence() 350 && (!unclusteredOnly || !next.getTableMapping().isClustered()); 351 } 352 353 public Object next() 354 { 355 MappingInfo ret = null; 356 if (hasNext()) 357 { 358 ret = next; 359 next = null; 360 } 361 return ret; 362 } 363 364 public void remove() 365 { 366 throw new UnsupportedOperationException (); 367 } 368 369 } 370 371 private boolean areColumnArraysEquivalent( 372 ColumnMapping[] t1, 373 ColumnMapping[] t2) 374 { 375 boolean equivalent = true; 376 if (t1 != null && t2 != null) 377 { 378 if (t1.length != t2.length) 379 equivalent = false; 380 381 for (int j = 0; j < t2.length; j++) 383 { 384 if (!t1[j] 385 .getColumnName() 386 .equals(t2[j].getColumnName())) 387 equivalent = false; 388 } 389 } 390 else if (t1 != t2) 391 equivalent = false; 392 return equivalent; 393 } 394 395 } 396 | Popular Tags |