1 22 package org.jboss.ejb.plugins.cmp.jdbc2.schema; 23 24 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCEntityMetaData; 25 import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCEntityBridge2; 26 import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCCMRFieldBridge2; 27 import org.jboss.deployment.DeploymentException; 28 import org.jboss.tm.TransactionLocal; 29 30 import javax.ejb.EJBException ; 31 import javax.transaction.Synchronization ; 32 import javax.transaction.RollbackException ; 33 import javax.transaction.SystemException ; 34 import javax.transaction.Status ; 35 import javax.transaction.Transaction ; 36 import java.sql.SQLException ; 37 38 42 public class Schema 43 { 44 private EntityTable[] entityTables; 45 private RelationTable[] relationTables; 46 47 private TransactionLocal localViews = new TransactionLocal() 48 { 49 protected Object initialValue() 50 { 51 Transaction tx = getTransaction(); 52 53 if(tx == null) 54 { 55 throw new IllegalStateException ("An operation requires an active transaction!"); 56 } 57 58 Views views = new Views(tx); 59 Synchronization sync = new SchemaSynchronization(views); 60 61 try 62 { 63 tx.registerSynchronization(sync); 64 } 65 catch(RollbackException e) 66 { 67 throw new EJBException ("Transaction already marked to roll back: " + e.getMessage(), e); 68 } 69 catch(SystemException e) 70 { 71 e.printStackTrace(); 72 throw new IllegalStateException ("Failed to register transaction synchronization: " + e.getMessage()); 73 } 74 75 return views; 76 } 77 }; 78 79 public EntityTable createEntityTable(JDBCEntityMetaData metadata, JDBCEntityBridge2 entity) 80 throws DeploymentException 81 { 82 if(entityTables == null) 83 { 84 entityTables = new EntityTable[1]; 85 } 86 else 87 { 88 EntityTable[] tmp = entityTables; 89 entityTables = new EntityTable[tmp.length + 1]; 90 System.arraycopy(tmp, 0, entityTables, 0, tmp.length); 91 } 92 93 EntityTable table = new EntityTable(metadata, entity, this, entityTables.length - 1); 94 entityTables[entityTables.length - 1] = table; 95 return table; 96 } 97 98 public RelationTable createRelationTable(JDBCCMRFieldBridge2 leftField, JDBCCMRFieldBridge2 rightField) 99 throws DeploymentException 100 { 101 if(relationTables == null) 102 { 103 relationTables = new RelationTable[1]; 104 } 105 else 106 { 107 RelationTable[] tmp = relationTables; 108 relationTables = new RelationTable[tmp.length + 1]; 109 System.arraycopy(tmp, 0, relationTables, 0, tmp.length); 110 } 111 112 RelationTable table = new RelationTable(leftField, rightField, this, relationTables.length - 1); 113 relationTables[relationTables.length - 1] = table; 114 return table; 115 } 116 117 public Table.View getView(EntityTable table) 118 { 119 Views views = (Views) localViews.get(); 120 Table.View view = views.entityViews[table.getTableId()]; 121 if(view == null) 122 { 123 view = table.createView(views.tx); 124 views.entityViews[table.getTableId()] = view; 125 } 126 return view; 127 } 128 129 public Table.View getView(RelationTable table) 130 { 131 Views views = (Views) localViews.get(); 132 Table.View view = views.relationViews[table.getTableId()]; 133 if(view == null) 134 { 135 view = table.createView(views.tx); 136 views.relationViews[table.getTableId()] = view; 137 } 138 return view; 139 } 140 141 public void flush() 142 { 143 Views views = (Views) localViews.get(); 144 145 Table.View[] relationViews = views.relationViews; 146 if(relationViews != null) 147 { 148 for(int i = 0; i < relationViews.length; ++i) 149 { 150 final Table.View view = relationViews[i]; 151 if(view != null) 152 { 153 try 154 { 155 view.flushDeleted(views); 156 } 157 catch(SQLException e) 158 { 159 throw new EJBException ("Failed to delete many-to-many relationships: " + e.getMessage(), e); 160 } 161 } 162 } 163 } 164 165 final Table.View[] entityViews = views.entityViews; 166 for(int i = 0; i < entityViews.length; ++i) 167 { 168 Table.View view = entityViews[i]; 169 if(view != null) 170 { 171 try 172 { 173 view.flushDeleted(views); 174 } 175 catch(SQLException e) 176 { 177 throw new EJBException ("Failed to delete instances: " + e.getMessage(), e); 178 } 179 } 180 } 181 182 for(int i = 0; i < entityViews.length; ++i) 183 { 184 Table.View view = entityViews[i]; 185 if(view != null) 186 { 187 try 188 { 189 view.flushCreated(views); 190 } 191 catch(SQLException e) 192 { 193 throw new EJBException ("Failed to create instances: " + e.getMessage(), e); 194 } 195 } 196 } 197 198 for(int i = 0; i < entityViews.length; ++i) 199 { 200 Table.View view = entityViews[i]; 201 if(view != null) 202 { 203 try 204 { 205 view.flushUpdated(); 206 } 207 catch(SQLException e) 208 { 209 throw new EJBException ("Failed to update instances: " + e.getMessage(), e); 210 } 211 } 212 } 213 214 if(relationViews != null) 215 { 216 for(int i = 0; i < relationViews.length; ++i) 217 { 218 final Table.View view = relationViews[i]; 219 if(view != null) 220 { 221 try 222 { 223 view.flushCreated(views); 224 } 225 catch(SQLException e) 226 { 227 throw new EJBException ("Failed to create many-to-many relationships: " + e.getMessage(), e); 228 } 229 } 230 } 231 } 232 } 233 234 236 public class Views 237 { 238 public final Transaction tx; 239 public final Table.View[] entityViews; 240 public final Table.View[] relationViews; 241 242 public Views(Transaction tx) 243 { 244 this.tx = tx; 245 this.entityViews = new Table.View[entityTables.length]; 246 this.relationViews = relationTables == null ? null : new Table.View[relationTables.length]; 247 } 248 } 249 250 private class SchemaSynchronization implements Synchronization 251 { 252 private final Views views; 253 254 public SchemaSynchronization(Views views) 255 { 256 this.views = views; 257 } 258 259 public void beforeCompletion() 260 { 261 flush(); 262 263 for(int i = 0; i < views.entityViews.length; ++i) 264 { 265 Table.View view = views.entityViews[i]; 266 if(view != null) 267 { 268 view.beforeCompletion(); 269 } 270 } 271 } 272 273 public void afterCompletion(int status) 274 { 275 if(status == Status.STATUS_MARKED_ROLLBACK || 276 status == Status.STATUS_ROLLEDBACK || 277 status == Status.STATUS_ROLLING_BACK) 278 { 279 for(int i = 0; i < views.entityViews.length; ++i) 280 { 281 Table.View view = views.entityViews[i]; 282 if(view != null) 283 { 284 view.rolledback(); 285 } 286 } 287 } 288 else 289 { 290 for(int i = 0; i < views.entityViews.length; ++i) 291 { 292 Table.View view = views.entityViews[i]; 293 if(view != null) 294 { 295 view.committed(); 296 } 297 } 298 } 299 } 300 } 301 } 302 | Popular Tags |