1 29 30 package com.caucho.ejb.cfg; 31 32 import com.caucho.amber.field.AmberField; 33 import com.caucho.amber.field.DependentEntityOneToOneField; 34 import com.caucho.amber.field.EntityManyToOneField; 35 import com.caucho.amber.field.Id; 36 import com.caucho.amber.field.IdField; 37 import com.caucho.amber.field.KeyManyToOneField; 38 import com.caucho.amber.manager.AmberPersistenceUnit; 39 import com.caucho.amber.table.Column; 40 import com.caucho.amber.table.ForeignColumn; 41 import com.caucho.amber.table.LinkColumns; 42 import com.caucho.amber.type.EntityType; 43 import com.caucho.bytecode.JClass; 44 import com.caucho.bytecode.JMethod; 45 import com.caucho.config.ConfigException; 46 import com.caucho.util.L10N; 47 import com.caucho.util.Log; 48 49 import java.util.ArrayList ; 50 import java.util.logging.Logger ; 51 52 55 public class CmrManyToOne extends CmrRelation { 56 private static final L10N L = new L10N(CmrManyToOne.class); 57 private static final Logger log = Log.open(CmrManyToOne.class); 58 59 private final EjbEntityBean _targetBean; 60 61 private SqlRelation []_sqlColumns; 62 63 private EntityManyToOneField _amberManyToOne; 64 private DependentEntityOneToOneField _amberDependentOneToOne; 65 66 private boolean _isDependent; 67 private boolean _isSourceCascadeDelete; 68 private boolean _isTargetCascadeDelete; 69 70 73 public CmrManyToOne(EjbEntityBean entityBean, 74 String fieldName, 75 EjbEntityBean targetBean) 76 throws ConfigException 77 { 78 super(entityBean, fieldName); 79 80 _targetBean = targetBean; 81 82 JMethod getter = getGetter(); 83 84 if (! getter.getReturnType().equals(_targetBean.getLocal())) 85 throw new ConfigException(L.l("{0}: '{1}' must return the local interface '{2}' of the EJB bean '{3}'.", 86 entityBean.getEJBClass().getName(), 87 getter.getFullName(), 88 _targetBean.getLocal().getName(), 89 _targetBean.getEJBName())); 90 } 91 92 95 public EjbEntityBean getTargetBean() 96 { 97 return _targetBean; 98 } 99 100 103 public JClass getTargetType() 104 { 105 return _targetBean.getLocal(); 106 } 107 108 111 public void setSQLColumns(SqlRelation []columns) 112 { 113 _sqlColumns = columns; 114 } 115 116 119 public SqlRelation []getSQLColumns() 120 { 121 return _sqlColumns; 122 } 123 124 127 public void setDependent(boolean isDependent) 128 { 129 _isDependent = isDependent; 130 } 131 132 135 public void setSourceCascadeDelete(boolean isCascadeDelete) 136 { 137 _isSourceCascadeDelete = isCascadeDelete; 138 } 139 140 143 public void setTargetCascadeDelete(boolean isCascadeDelete) 144 { 145 _isTargetCascadeDelete = isCascadeDelete; 146 } 147 148 151 public boolean isCascadeDelete() 152 { 153 return _isSourceCascadeDelete; 154 } 155 156 159 public EntityManyToOneField getAmberManyToOne() 160 { 161 162 if (_amberManyToOne == null) { 163 try { 164 EntityType sourceType = getEntity().getEntityType(); 165 166 _amberManyToOne = new EntityManyToOneField(sourceType, getName()); 167 168 EntityType targetType = _targetBean.getEntityType(); 169 _amberManyToOne.setType(targetType); 170 171 _amberManyToOne.setLinkColumns(calculateColumns(sourceType, 172 targetType)); 173 174 if (! _isDependent) { 175 _amberManyToOne.setSourceCascadeDelete(_isSourceCascadeDelete); 176 _amberManyToOne.setTargetCascadeDelete(_isTargetCascadeDelete); 177 } 178 179 _amberManyToOne.init(); 180 } catch (RuntimeException e) { 181 throw e; 182 } catch (Exception e) { 183 throw new RuntimeException (e); 184 } 185 } 186 187 return _amberManyToOne; 188 } 189 190 193 public DependentEntityOneToOneField getAmberOneToOne() 194 { 195 return _amberDependentOneToOne; 196 } 197 198 201 public IdField createId(AmberPersistenceUnit amberPersistenceUnit, EntityType type) 202 throws ConfigException 203 { 204 String fieldName = getName(); 205 206 EntityType sourceType = getEntity().getEntityType(); 207 EntityType targetType = getTargetBean().getEntityType(); 208 209 212 213 KeyManyToOneField keyField = new KeyManyToOneField(type, fieldName); 214 keyField.setType(targetType); 215 216 keyField.setLinkColumns(calculateColumns(sourceType, targetType)); 217 218 keyField.init(); 219 220 return keyField; 221 } 222 223 226 public AmberField assembleAmber(EntityType type) 227 throws ConfigException 228 { 229 AmberPersistenceUnit manager = type.getPersistenceUnit(); 230 EntityType targetType = getTargetBean().getEntityType(); 231 232 if (_isDependent) { 233 DependentEntityOneToOneField oneToOne; 234 oneToOne = new DependentEntityOneToOneField(type, getName()); 235 236 _amberDependentOneToOne = oneToOne; 237 238 241 return oneToOne; 242 } 243 else { 244 EntityManyToOneField manyToOne; 245 manyToOne = new EntityManyToOneField(type, getName()); 246 247 _amberManyToOne = manyToOne; 248 249 manyToOne.setType(_targetBean.getEntityType()); 250 251 manyToOne.setLinkColumns(calculateColumns(type, targetType)); 252 253 manyToOne.setSourceCascadeDelete(_isSourceCascadeDelete); 254 manyToOne.setTargetCascadeDelete(_isTargetCascadeDelete); 255 256 return manyToOne; 257 } 258 } 259 260 private LinkColumns calculateColumns(EntityType type, 261 EntityType targetType) 262 throws ConfigException 263 { 264 ArrayList <ForeignColumn> columns = new ArrayList <ForeignColumn>(); 265 266 Id id = targetType.getId(); 267 ArrayList <Column> keys = id.getColumns(); 268 269 if (_sqlColumns != null && _sqlColumns.length == keys.size()) { 270 for (Column key : keys) { 271 String sqlColumn = getColumn(_sqlColumns, key.getName()); 272 ForeignColumn column = 273 type.getTable().createForeignColumn(sqlColumn, key); 274 275 columns.add(column); 276 } 277 } 278 else if (_sqlColumns != null && _sqlColumns.length == 1) { 279 String baseSqlColumn = _sqlColumns[0].getSQLColumn(); 280 281 for (Column key : keys) { 282 String sqlColumn = baseSqlColumn + "_" + key.getName(); 283 284 ForeignColumn column = 285 type.getTable().createForeignColumn(sqlColumn, key); 286 columns.add(column); 287 } 288 } 289 else if (_sqlColumns != null && _sqlColumns.length > 0) { 290 throw new IllegalStateException ("Mismatched SQL columns"); 291 } 292 else if (keys.size() == 1) { 293 String sqlColumn = toSqlName(getName()); 294 295 ForeignColumn column = 296 type.getTable().createForeignColumn(sqlColumn, keys.get(0)); 297 columns.add(column); 298 } 299 else { 300 String baseSqlColumn = toSqlName(getName()); 301 for (Column key : keys) { 302 String sqlColumn = baseSqlColumn + "_" + key.getName(); 303 304 ForeignColumn column = 305 type.getTable().createForeignColumn(sqlColumn, key); 306 columns.add(column); 307 } 308 } 309 310 return new LinkColumns(type.getTable(), targetType.getTable(), columns); 311 } 312 313 private String getColumn(SqlRelation []sqlColumns, String sqlName) 314 throws ConfigException 315 { 316 String fieldName = getFieldName(_targetBean.getEntityType(), sqlName); 317 318 if (sqlColumns.length == 1) 319 return sqlColumns[0].getSQLColumn(); 320 321 for (int i = 0; i < sqlColumns.length; i++) { 322 String ref = sqlColumns[i].getReferences(); 323 324 if (ref == null) 325 throw new ConfigException(L.l("sql-column '{0}' needs a references attribute.", 326 sqlColumns[i].getSQLColumn())); 327 328 if (ref.equals(fieldName)) 329 return sqlColumns[i].getSQLColumn(); 330 } 331 332 throw new ConfigException(L.l("key '{0}' has no matching sql-column", 333 fieldName)); 334 } 335 336 private String getFieldName(EntityType type, String sqlName) 337 throws ConfigException 338 { 339 for (IdField field : type.getId().getKeys()) { 340 ArrayList <Column> columns = field.getColumns(); 341 342 for (int i = 0; i < columns.size(); i++) 343 if (columns.get(i).getName().equals(sqlName)) 344 return field.getName(); 345 } 346 347 return sqlName; 348 } 349 350 353 public void linkAmber() 354 throws ConfigException 355 { 356 CmrRelation targetRelation = getTargetRelation(); 357 358 if (targetRelation == null) 359 return; 360 else if (! (targetRelation instanceof CmrManyToOne)) 361 return; 362 else if (_isDependent) { 363 CmrManyToOne targetManyToOne = (CmrManyToOne) targetRelation; 364 365 EntityManyToOneField amberTarget = targetManyToOne.getAmberManyToOne(); 366 367 if (_amberDependentOneToOne == null) { 368 EntityType type = getEntity().getEntityType(); 369 370 DependentEntityOneToOneField oneToOne; 371 oneToOne = new DependentEntityOneToOneField(type, getName()); 372 373 _amberDependentOneToOne = oneToOne; 374 } 375 376 _amberDependentOneToOne.setTargetField(amberTarget); 377 } 378 else { 379 CmrManyToOne targetManyToOne = (CmrManyToOne) targetRelation; 380 381 DependentEntityOneToOneField amberTarget; 382 amberTarget = targetManyToOne.getAmberOneToOne(); 383 384 EntityManyToOneField manyToOne = getAmberManyToOne(); 385 386 if (amberTarget != null && manyToOne != null) { 387 manyToOne.setTargetField(amberTarget); 388 amberTarget.setTargetField(manyToOne); 389 } 390 } 391 } 392 } 393 | Popular Tags |