| 1 18 package org.objectweb.speedo.mapper.lib; 19 20 import java.math.BigDecimal ; 21 import java.math.BigInteger ; 22 import java.util.Date ; 23 import java.util.HashMap ; 24 import java.util.Iterator ; 25 import java.util.Map ; 26 import java.util.Properties ; 27 import java.util.Set ; 28 import java.util.StringTokenizer ; 29 import java.util.regex.Pattern ; 30 31 import javax.jdo.JDOException; 32 import javax.jdo.JDOFatalInternalException; 33 import javax.jdo.JDOUserException; 34 import javax.jdo.datastore.Sequence; 35 import javax.jdo.spi.JDOImplHelper; 36 import javax.jdo.spi.RegisterClassEvent; 37 import javax.jdo.spi.RegisterClassListener; 38 39 import org.objectweb.fractal.api.control.BindingController; 40 import org.objectweb.fractal.api.control.IllegalLifeCycleException; 41 import org.objectweb.fractal.api.control.LifeCycleController; 42 import org.objectweb.jorm.api.PClassMapping; 43 import org.objectweb.jorm.api.PClassMappingCtrl; 44 import org.objectweb.jorm.api.PException; 45 import org.objectweb.jorm.api.PMapCluster; 46 import org.objectweb.jorm.api.PMapper; 47 import org.objectweb.jorm.lib.JormPathHelper; 48 import org.objectweb.jorm.mapper.rdb.genclass.RdbGenClassProp; 49 import org.objectweb.jorm.mapper.rdb.lib.RdbPrefetchablePCM; 50 import org.objectweb.jorm.metainfo.api.Package; 51 import org.objectweb.jorm.metainfo.lib.BasicClass; 52 import org.objectweb.jorm.metainfo.lib.BasicCompositeName; 53 import org.objectweb.jorm.metainfo.lib.JormManager; 54 import org.objectweb.jorm.naming.api.PBinder; 55 import org.objectweb.jorm.naming.api.PExceptionNaming; 56 import org.objectweb.jorm.naming.api.PName; 57 import org.objectweb.jorm.naming.api.PNameCoder; 58 import org.objectweb.jorm.naming.api.PNameManager; 59 import org.objectweb.jorm.naming.api.PNamingContext; 60 import org.objectweb.jorm.naming.lib.KFPNCManager; 61 import org.objectweb.jorm.type.api.PType; 62 import org.objectweb.perseus.cache.api.CacheManager; 63 import org.objectweb.perseus.persistence.api.ConnectionHolder; 64 import org.objectweb.perseus.persistence.api.TransactionalPersistenceManager; 65 import org.objectweb.speedo.api.SpeedoProperties; 66 import org.objectweb.speedo.genclass.SpeedoGenClassHome; 67 import org.objectweb.speedo.generation.lib.NamingRules; 68 import org.objectweb.speedo.mapper.api.JormFactory; 69 import org.objectweb.speedo.mapper.api.JormFactoryAttributes; 70 import org.objectweb.speedo.mim.api.SpeedoHome; 71 import org.objectweb.speedo.naming.api.NamingManager; 72 import org.objectweb.speedo.naming.lib.NamingManagerFactory; 73 import org.objectweb.speedo.naming.lib.NamingManagerHelper; 74 import org.objectweb.speedo.pm.api.ProxyManagerFactory; 75 import org.objectweb.speedo.tools.StringReplace; 76 import org.objectweb.util.monolog.api.BasicLevel; 77 import org.objectweb.util.monolog.api.Logger; 78 import org.objectweb.util.monolog.api.LoggerFactory; 79 80 88 public class BasicJormFactory 89 implements JormFactory, 90 PNameCoder, 91 BindingController, 92 LifeCycleController, 93 JormFactoryAttributes, 94 RegisterClassListener { 95 96 99 public final static String MAPPER_BINDING = "mapper"; 100 103 public final static String CACHE_MANAGER_BINDING = "cache-manager"; 104 public final static String TPM_BINDING = "transactional-persistence-manager"; 105 public final static String PMF_BINDING = "proxy-manager-factory"; 106 107 protected TransactionalPersistenceManager tpm; 108 109 protected ProxyManagerFactory pmf; 110 111 114 protected PMapper mapper = null; 115 116 119 protected CacheManager cache = null; 120 121 125 protected Map binders = null; 126 127 131 protected Map pnamingContexts = null; 132 135 protected Map cn2pcm = null; 136 137 140 private NamingManagerFactory nmf; 141 142 145 private byte mappingStructuresRule = JormFactoryAttributes.CREATE_IF_REQUIRED; 146 147 protected Logger logger = null; 148 149 private KFPNCManager kfpncManager; 150 151 private boolean mappingOnClassRegistration = false; 152 153 private Properties speedoProperties; 154 155 159 public BasicJormFactory() { 160 pnamingContexts = new HashMap (); 161 binders = new HashMap (); 162 cn2pcm = new HashMap (); 163 nmf = new NamingManagerFactory(); 164 kfpncManager = new KFPNCManager(pnamingContexts); 165 } 166 167 170 public byte getMappingStructureRule() { 171 return mappingStructuresRule; 172 } 173 174 public void setMappingStructureRule(byte rule) { 175 mappingStructuresRule = rule; 176 } 177 178 public boolean getMappingOnClassRegistration() { 179 return mappingOnClassRegistration; 180 } 181 182 public void setMappingOnClassRegistration(boolean val) { 183 mappingOnClassRegistration = val; 184 } 185 186 189 public String [] listFc() { 190 return new String []{ 191 MAPPER_BINDING, 192 CACHE_MANAGER_BINDING, 193 TPM_BINDING, 194 PMF_BINDING 195 }; 196 } 197 198 public Object lookupFc(String s) { 199 if (MAPPER_BINDING.equals(s)) 200 return mapper; 201 else if (CACHE_MANAGER_BINDING.equals(s)) 202 return cache; 203 else if (TPM_BINDING.equals(s)) 204 return tpm; 205 else if (PMF_BINDING.equals(s)) 206 return pmf; 207 else 208 return null; 209 } 210 211 public void bindFc(String s, Object o) { 212 if ("logger".equals(s)) { 213 logger = (Logger) o; 214 } else if ("monolog-factory".equals(s)) { 215 nmf.setLogger(((LoggerFactory) o).getLogger(logger.getName() + ".naming-mmanager-factory")); 216 kfpncManager.setLogger(((LoggerFactory) o).getLogger(logger.getName() + ".kfpncmanager")); 217 } else if (MAPPER_BINDING.equals(s)) { 218 mapper = (PMapper) o; 219 } else if (CACHE_MANAGER_BINDING.equals(s)) { 220 cache = (CacheManager) o; 221 } else if (TPM_BINDING.equals(s)) { 222 tpm = (TransactionalPersistenceManager) o; 223 } else if (PMF_BINDING.equals(s)) { 224 pmf = (ProxyManagerFactory) o; 225 } 226 } 227 228 public void unbindFc(String s) { 229 if (MAPPER_BINDING.equals(s)) { 230 mapper = null; 231 nmf.setMapper(null); 232 } else if (CACHE_MANAGER_BINDING.equals(s)) { 233 cache = null; 234 } else if (TPM_BINDING.equals(s)) { 235 tpm = null; 236 } else if (PMF_BINDING.equals(s)) { 237 pmf = null; 238 nmf.setPmf(null); 239 } 240 } 241 242 private boolean started = false; 243 244 public String getFcState() { 245 return started ? STARTED : STOPPED; 246 } 247 248 public void startFc() throws IllegalLifeCycleException { 249 if (!started) { 250 mapper.addMapperEventListener(kfpncManager); 251 nmf.setMapper(mapper); 252 nmf.setCache(cache); 253 nmf.setPmf(pmf); 254 JDOImplHelper.getInstance().addRegisterClassListener(this); 255 started = true; 256 } 257 } 258 259 public void stopFc() throws IllegalLifeCycleException { 260 if (started) { 261 mapper.removeMapperEventListener(kfpncManager); 262 JDOImplHelper.getInstance().removeRegisterClassListener(this); 263 started = false; 264 } 265 } 266 267 270 public PBinder getPBinder(Class clazz) throws PException { 271 String clName = clazz.getName(); 272 PClassMapping pcm = mapper.lookup(clName); 273 if (pcm != null) 274 return pcm.getPBinder(); 275 return getPClassMapping(clazz).getPBinder(); 276 } 277 278 public PBinder getPBinder(String classname, ClassLoader cl) throws PException { 279 PClassMapping pcm = mapper.lookup(classname); 280 if (pcm != null) 281 return pcm.getPBinder(); 282 return getPClassMapping(getClass(classname, cl)).getPBinder(); 283 } 284 285 public ClassLoader getClassLoader(String className) { 286 Object o = mapper.lookup(className); 287 if (o == null) { 288 return null; 289 } 290 return getClassLoader(o.getClass()); 291 } 292 293 public PClassMapping getGenClassMapping(String path) { 294 return JormPathHelper.getPClassMapping(path, mapper); 295 } 296 297 public PClassMapping getPClassMapping(Class clazz) throws PException { 298 PClassMapping pcm = mapper.lookup(clazz.getName()); 299 if (pcm == null) { 300 pcm = getPClassMapping(clazz.getName(), 301 clazz.getClassLoader()); 302 } 303 return pcm; 304 } 305 306 316 public PNamingContext getPNamingContext(String classname, ClassLoader cl) throws PException { 317 return getPNamingContext(getClass(classname, cl)); 318 } 319 320 public PNamingContext getPNamingContext(Class clazz) throws PException { 321 PClassMapping pcm = getPClassMapping(clazz); 322 String className = clazz.getName(); 323 String path = JormPathHelper.getPath(className); 324 Properties classProperties = getClassProperties(clazz); 325 String jormConf = classProperties.getProperty(path); 326 if (jormConf != null) { 327 return (PNamingContext) findPNameManager( 328 className, clazz.getClassLoader(), pcm, jormConf); 329 } else { 330 throw new PException( 331 "Impossible to find the PNamingContext for the class " 332 + className); 333 } 334 } 335 336 public Properties getSpeedoProperties() { 337 return speedoProperties; 338 } 339 340 HashMap pattern2prop; 341 public void setSpeedoProperties(Properties p) { 342 speedoProperties = p; 343 if (speedoProperties == null) { 344 return; 345 } 346 for(Iterator it=speedoProperties.keySet().iterator(); it.hasNext();) { 347 String key = (String ) it.next(); 348 if (key.indexOf('*') != -1 || key.indexOf('?') != -1) { 349 if (logger != null) { 351 logger.log(BasicLevel.DEBUG, "Pattern " + key); 352 } 353 Pattern pa = Pattern.compile(StringReplace.toJavaPattern(key)); 354 if (pattern2prop == null) { 355 pattern2prop = new HashMap (); 356 } 357 pattern2prop.put(pa, key); 358 } 359 } 360 } 361 362 365 368 public void registerClass(RegisterClassEvent event) { 369 if (mappingOnClassRegistration) { 370 try { 371 getPClassMapping(event.getRegisteredClass()); 372 } catch (PException e) { 373 throw new JDOException( 374 "Impossible to initialize the persistent class '" 375 + event.getRegisteredClass().getName() + "':", e); 376 } 377 } 378 } 379 380 381 public boolean codingSupported(int codingtype) { 384 return (codingtype & CTCOMPOSITE) != 0; 385 } 386 387 public PName decode(byte[] en) throws PExceptionNaming { 388 return null; 389 } 390 391 public PName decodeAbstract(Object oid, Object context) 392 throws PExceptionNaming, UnsupportedOperationException { 393 Class clazz = null; 394 ConnectionHolder conn = null; 395 if (context != null) { 396 if (!(context instanceof ConnectionHolder)) { 397 clazz = (Class ) context; 398 } else { 399 conn = (ConnectionHolder) context; 400 } 401 } 402 if (oid instanceof PName) { 403 try { 404 return ((PName) oid).resolve(conn); 405 } catch (PException e) { 406 throw new JDOUserException("Impossible to decode the identifier " 407 + oid + (clazz == null 408 ? "" : " of the class " + clazz.getName()), e); 409 } 410 } 411 PBinder binder = null; 412 PName pn = null; 413 try { 414 if (clazz != null) { 415 binder = getPBinder(clazz); 416 } 417 pn = nmf.decode(binder, oid, clazz, this); 418 } catch (PException e) { 419 throw new JDOUserException("Impossible to decode the identifier " 420 + oid + (clazz == null 421 ? "" : " of the class " + clazz.getName()), e); 422 } 423 if (pn != null) { 424 return pn; 425 } 426 if (binder != null) { 427 return binder.decodeAbstract(oid, null); 428 } 429 throw new JDOUserException("Impossible to decode the identifier " 430 + oid + (clazz == null 431 ? "" : " of the class " + clazz.getName())); 432 } 433 434 public PName decodeByte(byte en) throws PExceptionNaming, UnsupportedOperationException { 435 return decodeAbstract(new Byte (en), null); 436 } 437 438 public PName decodeObyte(Byte en) throws PExceptionNaming, UnsupportedOperationException { 439 return decodeAbstract(en, null); 440 } 441 442 public PName decodeChar(char en) throws PExceptionNaming, UnsupportedOperationException { 443 return decodeAbstract(new Character (en), null); 444 } 445 446 public PName decodeOchar(Character en) throws PExceptionNaming, UnsupportedOperationException { 447 return decodeAbstract(en, null); 448 } 449 450 public PName decodeInt(int en) throws PExceptionNaming, UnsupportedOperationException { 451 return decodeAbstract(new Integer (en), null); 452 } 453 454 public PName decodeOint(Integer en) throws PExceptionNaming, UnsupportedOperationException { 455 return decodeAbstract(en, null); 456 } 457 458 public PName decodeLong(long en) throws PExceptionNaming, UnsupportedOperationException { 459 return decodeAbstract(new Long (en), null); 460 } 461 462 public PName decodeOlong(Long en) throws PExceptionNaming, UnsupportedOperationException { 463 return decodeAbstract(en, null); 464 } 465 466 public PName decodeShort(short en) throws PExceptionNaming, UnsupportedOperationException { 467 return decodeAbstract(new Short (en), null); 468 } 469 470 public PName decodeOshort(Short en) throws PExceptionNaming, UnsupportedOperationException { 471 return decodeAbstract(en, null); 472 } 473 474 public PName decodeString(String en) throws PExceptionNaming { 475 return decodeAbstract(en, null); 476 } 477 478 public PName decodeCharArray(char[] en) throws PExceptionNaming { 479 return decodeAbstract(en, null); 480 } 481 482 public PName decodeDate(Date en) throws PExceptionNaming { 483 return decodeAbstract(en, null); 484 } 485 486 public PName decodeBigInteger(BigInteger en) throws PExceptionNaming { 487 return decodeAbstract(en, null); 488 } 489 490 public PName decodeBigDecimal(BigDecimal en) throws PExceptionNaming { 491 return decodeAbstract(en, null); 492 } 493 494 public byte[] encode(PName pn) throws PExceptionNaming { 495 return pn.encode(); 496 } 497 498 public Object encodeAbstract(PName pn) throws PExceptionNaming, UnsupportedOperationException { 499 try { 500 return nmf.encode(pn); 501 } catch (PException e) { 502 throw new JDOUserException( 503 "Impossible to encode the identifier :" + pn); 504 } 505 } 506 507 public byte encodeByte(PName pn) throws PExceptionNaming, UnsupportedOperationException { 508 throw new UnsupportedOperationException ("Impossible to encode to a byte"); 509 } 510 511 public Byte encodeObyte(PName pn) throws PExceptionNaming, UnsupportedOperationException { 512 throw new UnsupportedOperationException ("Impossible to encode to a Byte"); 513 } 514 515 public char encodeChar(PName pn) throws PExceptionNaming, UnsupportedOperationException { 516 throw new UnsupportedOperationException ("Impossible to encode to a char"); 517 } 518 519 public Character encodeOchar(PName pn) throws PExceptionNaming, UnsupportedOperationException { 520 throw new UnsupportedOperationException ("Impossible to encode to a Character"); 521 } 522 523 public int encodeInt(PName pn) throws PExceptionNaming, UnsupportedOperationException { 524 throw new UnsupportedOperationException ("Impossible to encode to a int"); 525 } 526 527 public Integer encodeOint(PName pn) throws PExceptionNaming, UnsupportedOperationException { 528 throw new UnsupportedOperationException ("Impossible to encode to a Integer"); 529 } 530 531 public long encodeLong(PName pn) throws PExceptionNaming, UnsupportedOperationException { 532 throw new UnsupportedOperationException ("Impossible to encode to a long"); 533 } 534 535 public Long encodeOlong(PName pn) throws PExceptionNaming, UnsupportedOperationException { 536 throw new UnsupportedOperationException ("Impossible to encode to a Long"); 537 } 538 539 public short encodeShort(PName pn) throws PExceptionNaming, UnsupportedOperationException { 540 throw new UnsupportedOperationException ("Impossible to encode to a short"); 541 } 542 543 public Short encodeOshort(PName pn) throws PExceptionNaming, UnsupportedOperationException { 544 throw new UnsupportedOperationException ("Impossible to encode to a Short"); 545 } 546 547 public String encodeString(PName pn) throws PExceptionNaming { 548 throw new UnsupportedOperationException ("Impossible to encode to a String"); 549 } 550 551 public char[] encodeCharArray(PName pn) throws PExceptionNaming { 552 throw new UnsupportedOperationException ("Impossible to encode to a char[]"); 553 } 554 555 public Date encodeDate(PName pn) throws PExceptionNaming { 556 throw new UnsupportedOperationException ("Impossible to encode to a Date"); 557 } 558 559 public BigInteger encodeBigInteger(PName pn) throws PExceptionNaming { 560 throw new UnsupportedOperationException ("Impossible to encode to a BigInteger"); 561 } 562 563 public BigDecimal encodeBigDecimal(PName pn) throws PExceptionNaming { 564 throw new UnsupportedOperationException ("Impossible to encode to a BigDecimal"); 565 } 566 567 public PName getNull() { 568 return null; 569 } 570 571 public void setNullPName(Object o) throws PException { 572 } 573 574 public boolean supportDynamicComposite() { 575 return false; 576 } 577 578 public boolean supportCompositeField(String fn, PType ft) { 579 return false; 580 } 581 582 public boolean supportStaticComposite() { 583 return false; 584 } 585 586 public PType getPType() { 587 return null; 588 } 589 590 public void setPType(PType pt) { 591 } 592 593 596 597 607 private Properties getClassProperties(Class clazz) throws PException { 608 PClassMapping pcm = getPClassMapping( 609 clazz.getName(), clazz.getClassLoader()); 610 return ((SpeedoHome) pcm).getClassProperties(); 611 } 612 613 631 public synchronized PClassMapping getPClassMapping(String className, 632 ClassLoader classLoader) 633 throws PException { 634 boolean debug = logger.isLoggable(BasicLevel.DEBUG); 635 SpeedoHome pcm = (SpeedoHome) cn2pcm.get(className); 636 if (pcm != null) { 637 if (debug) 638 logger.log(BasicLevel.DEBUG, "PClassMapping for class " + className 639 + " is being configured:" + pcm); 640 return pcm; 641 } 642 643 pcm = (SpeedoHome) mapper.lookup(className); 644 if (pcm != null) { 645 if (debug) 646 logger.log(BasicLevel.DEBUG, "PClassMapping for class " + className 647 + " already exist:" + pcm); 648 return pcm; 649 } 650 651 if (debug) { 653 logger.log(BasicLevel.DEBUG, 654 "Looking for the PClassMapping of the class " + className); 655 } 656 String pcmcn = NamingRules.fqMappingName(className); 657 try { 658 pcm = (SpeedoHome) classLoader.loadClass(pcmcn).newInstance(); 659 } catch (Exception e) { 660 throw new PException(e, 661 "Impossible to instanciate the PClassMapping of the class " 662 + className + ": " + pcmcn); 663 } 664 pcm.setTransactionalPersistenceManager(tpm); 665 pcm.setProxyManagerFactory(pmf); 666 Properties classProperties = pcm.getClassProperties(); 667 if (debug) { 668 logger.log(BasicLevel.DEBUG, "Jorm config:" + classProperties); 669 } 670 loadJormSpeedoMI(className, classProperties, classLoader); 672 673 PBinder binder = findPBinder(className, classLoader, 675 classProperties.getProperty(JormPathHelper.getPath(className))); 676 pcm.setPBinder(binder); 677 binder.setPClassMapping(pcm); 678 679 PNameCoder classPnc = findPNameManager( 681 className, classLoader, pcm, classProperties.getProperty(JormPathHelper.getPath(className)) 682 ); 683 ((PClassMappingCtrl) pcm).setClassPNameCoder(classPnc); 684 RefConfig refConfig = new RefConfig(classProperties, classLoader); 686 cn2pcm.put(className, pcm); pcm.configureRefFields(refConfig); 688 cn2pcm.remove(className); 689 if (debug) { 690 logger.log(BasicLevel.DEBUG, "PClassMapping/PBinder/PNC created for the class " + className); 691 logger.log(BasicLevel.DEBUG, "- pcm: " + pcm); 692 logger.log(BasicLevel.DEBUG, "- binder: " + binder); 693 logger.log(BasicLevel.DEBUG, "-pnc: " + classPnc); 694 } 695 696 applySpeedoProperties(pcm); 697 698 <
|