| 1 27 package org.objectweb.speedo; 28 29 import java.util.Arrays ; 30 import java.util.Collection ; 31 import java.util.Collections ; 32 import java.util.HashMap ; 33 import java.util.Iterator ; 34 import java.util.Map ; 35 import java.util.Properties ; 36 37 import javax.jdo.JDOUserException; 38 import javax.jdo.PersistenceManager; 39 import javax.jdo.PersistenceManagerFactory; 40 import javax.jdo.datastore.DataStoreCache; 41 import javax.jdo.listener.InstanceLifecycleListener; 42 import javax.naming.InitialContext ; 43 import javax.naming.NamingException ; 44 45 import org.objectweb.fractal.adl.Factory; 46 import org.objectweb.fractal.adl.FactoryFactory; 47 import org.objectweb.fractal.api.Component; 48 import org.objectweb.fractal.api.Interface; 49 import org.objectweb.fractal.api.control.BindingController; 50 import org.objectweb.fractal.api.control.ContentController; 51 import org.objectweb.fractal.jmx.comm.CommunicatorAttributes; 52 import org.objectweb.fractal.util.Fractal; 53 import org.objectweb.jorm.api.PMapper; 54 import org.objectweb.jorm.mapper.rdb.lib.ConnectionSpecJDBC; 55 import org.objectweb.perseus.cache.api.CacheAttributeController; 56 import org.objectweb.perseus.concurrency.pessimistic.PessimisticConcurrencyManagerAC; 57 import org.objectweb.perseus.dependency.api.DependencyGraph; 58 import org.objectweb.perseus.pool.api.PoolAttributes; 59 import org.objectweb.speedo.api.Debug; 60 import org.objectweb.speedo.api.SpeedoException; 61 import org.objectweb.speedo.api.SpeedoProperties; 62 import org.objectweb.speedo.api.SpeedoVersion; 63 import org.objectweb.speedo.api.TransactionListener; 64 import org.objectweb.speedo.jmx.JMXConfigurator; 65 import org.objectweb.speedo.lib.FractalHelper; 66 import org.objectweb.speedo.mapper.api.JormFactoryAttributes; 67 import org.objectweb.speedo.mapper.api.MapperAttributes; 68 import org.objectweb.speedo.mapper.rdb.JDBCMapperAttributes; 69 import org.objectweb.speedo.pm.api.ProxyManager; 70 import org.objectweb.speedo.pm.api.ProxyManagerFactory; 71 import org.objectweb.speedo.query.api.QueryManagerAttribute; 72 import org.objectweb.speedo.sequence.api.SequenceManager; 73 import org.objectweb.speedo.workingset.lib.SpeedoTransaction; 74 import org.objectweb.util.monolog.Monolog; 75 import org.objectweb.util.monolog.api.BasicLevel; 76 import org.objectweb.util.monolog.api.Loggable; 77 import org.objectweb.util.monolog.api.Logger; 78 import org.objectweb.util.monolog.api.LoggerFactory; 79 80 93 public class Speedo implements PersistenceManagerFactory, ProxyManagerFactory { 94 95 public final static String CONNECTION_SPEC_FACTORY = 96 "org.objectweb.speedo.connectionSpecFactory"; 97 98 private final static String LOGGER_NAME = SpeedoProperties.LOGGER_NAME + ".init"; 99 private final static String SPEEDO_TEMPLATE = "org.objectweb.speedo.Speedo"; 100 private final static String SPEEDO_JMX_TEMPLATE = "org.objectweb.speedo.SpeedoJMX"; 101 private final static String OPTIMISTIC_CONCURRENCY_TEMPLATE = 102 "org.objectweb.perseus.persistence.concurrency.POptimisticConcurrencyManager"; 103 private final static String PESSIMISTIC_CONCURRENCY_TEMPLATE = 104 "org.objectweb.perseus.persistence.concurrency.PPessimisticConcurrencyManager"; 105 private final static String DBDELEGATE_CONCURRENCY_TEMPLATE = 106 "org.objectweb.perseus.persistence.concurrency.PDbDelegateConcurrencyManager"; 107 public final static String PM_POOL_PATH = "proxy-manager-pool"; 108 public final static String MEMORY_CACHE_PATH = "tpm.cache-manager"; 109 public final static String DEPENDENCY_GRAPH_PATH = "tpm.dependency-graph"; 110 public final static String QUERY_CACHE_PATH = "compiled-query-cache"; 111 public final static String QUERY_MANAGER = "query-manager"; 112 public final static String CONNECTION_POOL_PATH = "mapper.pool"; 113 public final static String MONOLOG_FACTORY_PATH = "monolog-factory"; 114 public final static String PRIMITIVE_MAPPER_PATH = "mapper.mapper"; 115 public final static String JORM_FACTORY_PATH = "mapper.jorm-factory"; 116 public final static String PMF_PATH = "proxy-manager-factory"; 117 public final static String JMX_AGENT_PATH = "agent"; 118 public final static String HTML_JMX_AGENT_PATH = JMX_AGENT_PATH + ".html"; 119 120 121 private static Map INSTANCES = new HashMap (); 122 private final static String FRACTAL_PROVIDER = "fractal.provider"; 123 private final static String DEFAULT_FRACTAL_PROVIDER 124 = "org.objectweb.fractal.julia.Julia"; 125 126 private final static String JULIA_LOADER = "julia.loader"; 127 private final static String DEFAULT_JULIA_LOADER 128 = "org.objectweb.fractal.julia.loader.DynamicLoader"; 129 130 private final static String JULIA_CONFIG = "julia.config"; 131 private final static String DEFAULT_JULIA_CONFIG = "julia.cfg"; 132 133 private static Factory factory = null; 134 private static Component speedoTemplate = null; 135 136 public static PersistenceManagerFactory getPersistenceManagerFactory( 138 Properties props) throws Throwable { 139 return getPersistenceManagerFactory((Map ) props); 140 } 141 public static PersistenceManagerFactory getPersistenceManagerFactory( 143 Map m) throws Throwable { 144 Object instance; 145 synchronized (INSTANCES) { 146 instance = INSTANCES.get(m); 147 if (instance == null) { 148 instance = new Speedo(m); 149 INSTANCES.put(m, instance); 150 } 151 } 152 return (PersistenceManagerFactory) instance; 153 } 154 155 public static void clearInstances() { 156 INSTANCES.clear(); 157 } 158 159 162 private PersistenceManagerFactory delegate = null; 163 ProxyManagerFactory pmfComponent = null; 164 private Logger logger = null; 165 private Component speedo = null; 166 boolean isPropertiesInitialized = false; 167 168 public Speedo() throws Throwable { 169 getSpeedoComponent(null); 170 isPropertiesInitialized = false; 171 } 172 176 public Speedo(Map props) throws Throwable { 177 try { 178 init(getSpeedoComponent(props), props); 179 isPropertiesInitialized = true; 180 } catch(Throwable e) { 181 System.err.println("Error during the instanciation of the Speedo " + 182 "persistence manager factory:"); 183 e.printStackTrace(System.err); 184 throw e; 185 } 186 } 187 188 public ProxyManagerFactory getPMFComponent() throws Exception { 189 return pmfComponent; 190 } 191 192 private Factory getADLFactory () throws Exception { 193 if (factory == null) { 194 factory = FactoryFactory.getFactory(FactoryFactory.FRACTAL_BACKEND); 195 } 196 return factory; 197 } 198 199 private static Object getProperty(Map m, String propName) { 200 return m.get(propName); 201 } 202 203 private static String getProperty(Map m, String propName, String defaultValue) { 204 Object res = m.get(propName); 205 if (res instanceof String ) { 206 return (String ) res; 207 } else { 208 return defaultValue; 209 } 210 } 211 private Component getSpeedoComponent(Map props) throws Throwable { 212 213 if (speedo == null) { 214 System.setProperty(FRACTAL_PROVIDER, DEFAULT_FRACTAL_PROVIDER); 216 System.setProperty(JULIA_LOADER, DEFAULT_JULIA_LOADER); 217 System.setProperty(JULIA_CONFIG, DEFAULT_JULIA_CONFIG); 218 219 221 Monolog.initialize(); 222 223 LoggerFactory loggerFactory = Monolog.monologFactory; 224 logger = loggerFactory.getLogger(LOGGER_NAME); 225 String templateName = SPEEDO_TEMPLATE; 226 if (props != null 227 && isTrue(getProperty(props, SpeedoProperties.JMX, "false"))) { 228 templateName = SPEEDO_JMX_TEMPLATE; 229 } 230 try { 232 if (speedoTemplate == null) { 233 speedoTemplate = (Component)getADLFactory().newComponent( 234 templateName, 235 Collections.singletonMap("template", "true")); 236 } 237 speedo = Fractal.getFactory(speedoTemplate).newFcInstance(); 239 } catch (Throwable e) { 240 System.err.println("Error during the template loading or the " + 241 "component instanciation '" + SPEEDO_TEMPLATE + "': "); 242 throw e; 243 } 244 Fractal.getNameController(speedo).setFcName("org.objectweb.speedo"); 245 delegate = (PersistenceManagerFactory) speedo.getFcInterface("persistence-manager-factory"); 246 } 247 return speedo; 248 } 249 250 public void init(Component speedo, Map pmfProps) throws Throwable { 251 logger.log(BasicLevel.INFO, "Speedo " + SpeedoVersion.SPEEDO_VERSION 252 + " is starting ..."); 253 254 Map props = new HashMap (); 257 props.putAll(pmfProps); 258 String strval; 259 260 props.remove(SpeedoProperties.JDO_PERSISTENCE_MANAGER_FACTORY_CLASS); 261 262 strval = getProperty(props, SpeedoProperties.IMRICATED_PM_ALLOWED, "false"); 263 props.remove(SpeedoProperties.IMRICATED_PM_ALLOWED); 264 boolean imbricatedPM = Boolean.valueOf(strval).booleanValue(); 265 if (imbricatedPM) { 266 logger.log(BasicLevel.INFO, "PM reused on imbricated PMF.getPM()"); 267 } 268 269 strval = getProperty(props, SpeedoProperties.DEBUG, null); 271 props.remove(SpeedoProperties.DEBUG); 272 if (strval != null) { 273 Debug.ON = Boolean.valueOf(strval).booleanValue(); 274 logger.log(BasicLevel.INFO, SpeedoProperties.DEBUG + ": " + Debug.ON); 275 } 276 277 boolean useConnectionFactory = configureMapper(speedo, props); 278 configurePool(getSubComponent(speedo, PM_POOL_PATH), 279 "PersistenceManager pool: ", 280 SpeedoProperties.PM_POOL_MIN, 281 SpeedoProperties.PM_POOL_MAX, 282 SpeedoProperties.PM_POOL_TTL, 283 SpeedoProperties.PM_POOL_INACTIVETTL, 284 SpeedoProperties.PM_POOL_TIMEOUT, 285 props); 286 configureCache(getSubComponent(speedo, MEMORY_CACHE_PATH), 287 "Persistent objects cache: ", 288 SpeedoProperties.CACHE_SIZE, 289 SpeedoProperties.CACHE_AUTO_CLEAN_SIZE, 290 SpeedoProperties.CACHE_AUTO_CLEAN_THRESHOLD, 291 SpeedoProperties.CACHE_REPLCAEMENT, 292 props); 293 configureCache(getSubComponent(speedo, QUERY_CACHE_PATH), 294 "Compiled query cache: ", 295 SpeedoProperties.COMPILED_QUERY_CACHE_SIZE, 296 SpeedoProperties.COMPILED_QUERY_CACHE_AUTO_CLEAN_SIZE, 297 SpeedoProperties.COMPILED_QUERY_CACHE_AUTO_CLEAN_THRESHOLD, 298 SpeedoProperties.COMPILED_QUERY_CACHE_POLICY, 299 props); 300 301 final String TM_NAME_old = "org.objectweb.perseus.connector.ra.jdo.TMName"; 303 strval = getProperty(props, TM_NAME_old, ""); 304 if (strval.length()>0) { 305 logger.log(BasicLevel.WARN, "Property " + TM_NAME_old 306 + " is deprecated, you must use " + SpeedoProperties.TM_NAME); 307 props.remove(TM_NAME_old); 308 pmfProps.remove(TM_NAME_old); 309 if (getProperty(props, SpeedoProperties.TM_NAME) == null) { 310 props.put(SpeedoProperties.TM_NAME, strval); 311 pmfProps.put(SpeedoProperties.TM_NAME, strval); 312 } 313 } 314 315 strval = getProperty(props, SpeedoProperties.MANAGED, ""); 317 if (strval.length()>0) { 318 boolean b = isTrue(strval); 319 if (!useConnectionFactory && b) { 320 String msg = "In a managed environnement, a connection factory is required"; 321 logger.log(BasicLevel.ERROR, msg); 322 throw new JDOUserException(msg); 323 } 324 logger.log(BasicLevel.INFO, SpeedoProperties.MANAGED + ": Speedo is used " 325 + (b 326 ? "in a managed environnement" 327 : "in stand alone")); 328 329 strval = getProperty(props, SpeedoProperties.TM_NAME, ""); 331 props.remove(SpeedoProperties.TM_NAME); 332 logger.log(BasicLevel.INFO, SpeedoProperties.TM_NAME + ": " 333 + (strval.length()>0 334 ? strval 335 : ": no value specified, use a well known application server")); 336 } else { 337 props.remove(SpeedoProperties.TM_NAME); 338 } 339 340 strval = getProperty(props, SpeedoProperties.TX_LISTENER, ""); 342 if (strval.length()>0) { 343 try { 344 SpeedoTransaction.txListener = (TransactionListener) 345 Class.forName(strval).newInstance(); 346 if (SpeedoTransaction.txListener instanceof Loggable) { 347 ((Loggable) SpeedoTransaction.txListener) 348 .setLoggerFactory(Monolog.monologFactory); 349 } 350 logger.log(BasicLevel.INFO, "Transaction listener: " + strval); 351 } catch (Exception e) { 352 logger.log(BasicLevel.WARN, 353 "Impossible to instanciate the TransactionListener specified '" 354 + strval + "': ", e); 355 } 356 } 357 358 configurePrefetching(speedo, props); 359 configureConcurrencyManager(speedo, props); 360 boolean jmxOn = configureJMX(speedo, props); 361 362 for (Iterator it = props.entrySet().iterator(); it.hasNext();) { 364 Map.Entry me = (Map.Entry ) it.next(); 365 String key = (String ) me.getKey(); 366 String value = (String ) me.getValue(); 367 boolean knownProperty = true; 368 if (SpeedoProperties.JDO_OPTION_RETAIN_VALUES.equals(key)) { 369 delegate.setRetainValues(Boolean.valueOf(value).booleanValue()); 370 371 } else if (SpeedoProperties.JDO_OPTION_RESTORE_VALUES.equals(key)) { 372 delegate.setRestoreValues(Boolean.valueOf(value).booleanValue()); 373 374 } else if (SpeedoProperties.JDO_OPTION_IGNORE_CACHE.equals(key)) { 375 delegate.setIgnoreCache(Boolean.valueOf(value).booleanValue()); 376 377 } else if (SpeedoProperties.JDO_OPTION_NON_TRANSACTIONAL_READ.equals(key)) { 378 delegate.setNontransactionalRead(Boolean.valueOf(value).booleanValue()); 379 380 } else if (SpeedoProperties.JDO_OPTION_NON_TRANSACTIONAL_WRITE.equals(key)) { 381 delegate.setNontransactionalWrite(Boolean.valueOf(value).booleanValue()); 382 383 } else if (SpeedoProperties.JDO_OPTION_MULTITREADED.equals(key)) { 384 delegate.setMultithreaded(Boolean.valueOf(value).booleanValue()); 385 386 } else { 387 knownProperty = false; 388 } 389 if (knownProperty) { 390 logger.log(BasicLevel.INFO, key + ": " + value); 391 it.remove(); 392 } 393 } 394 395 for (Iterator it = props.entrySet().iterator(); it.hasNext();) { 397 Map.Entry me = (Map.Entry ) it.next(); 398 String key = (String ) me.getKey(); 399 if (key.startsWith(SpeedoProperties.CACHE_CLASS_POLICY+"(") 400 || key.startsWith(SpeedoProperties.USER_CACHE_CLASS_POLICY+"(") 401 || key.startsWith(SpeedoProperties.PREFETCH_ON_GENCLASS+"(") 402 || key.startsWith(SpeedoProperties.PREFETCH_ON_QUERY+"(") 403 || key.startsWith(SpeedoProperties.PREFETCH_ON_EXTENT+"(") 404 ) { 405 continue; 406 } 407 String value = (String ) me.getValue(); 408 logger.log(BasicLevel.WARN, "The (" + key + ", " + value 409 + ") property is not managed"); 410 } 411 412 delegate.getProperties().putAll(pmfProps); 413 Fractal.getLifeCycleController(speedo).startFc(); 414 pmfComponent = (ProxyManagerFactory) getSubComponent( 415 ((Interface) delegate).getFcItfOwner(), PMF_PATH) 416 .getFcInterface("proxy-manager-factory"); 417 if (jmxOn) { 418 new JMXConfigurator(speedo, logger).init(); 419 } 420 } 421 private Component getSubComponent(Component parent, 422 String path) throws Exception { 423 return FractalHelper.getSubComponent(parent, path, logger); 424 } 425 426 private void configurePool(Component pool, 427 String poolLabel, 428 String minProp, 429 String maxProp, 430 String ttlProp, 431 String inactivettlProp, 432 String timeoutProp, 433 Map props) throws Exception { 434 String strval = null; 435 int poolMinSize = -2; 436 int poolMaxSize = -2; 437 long poolTTL = -2; 438 long poolInactiveTTL = -2; 439 long poolTimeout = -2; 440 boolean conf = false; 441 StringBuffer sb = new StringBuffer (poolLabel); 442 final String sep = ", "; 443 if (minProp != null) { 444 strval = getProperty(props, minProp, ""); 445 if (strval.length() > 0) { 446 props.remove(minProp); 447 poolMinSize = Integer.parseInt(strval); 448 if (conf) { 449 sb.append(sep); 450 } 451 sb.append("min=" + strval); 452 conf = true; 453 } 454 } 455 if (maxProp != null) { 456 strval = getProperty(props, maxProp, ""); 457 if (strval.length() > 0) { 458 props.remove(maxProp); 459 if (strval.equalsIgnoreCase("nolimit")) { 460 poolMaxSize = -1; 461 } else { 462 poolMaxSize = Integer.parseInt(strval); 463 } 464 if (conf) { 465 sb.append(sep); 466 } 467 sb.append("max=" + strval); 468 conf = true; 469 } 470 } 471 if (ttlProp != null) { 472 strval = getProperty(props, ttlProp, ""); 473 if (strval.length() > 0) { 474 props.remove(ttlProp); 475 try { 476 poolTTL = 1000 * Long.parseLong(strval); 477 } catch (NumberFormatException e) { 478 poolTTL = -1; 479 strval = "NOTTL"; 480 } 481 if (conf) { 482 sb.append(sep); 483 } 484 sb.append("ttl=" + strval); 485 conf = true; 486 } 487 } 488 if (inactivettlProp != null) { 489 strval = getProperty(props, inactivettlProp, ""); 490 if (strval.length() > 0) { 491 props.remove(inactivettlProp); 492 try { 493 poolInactiveTTL = 1000 * Long.parseLong(strval); 494 } catch (NumberFormatException e) { 495 poolInactiveTTL = -1; 496 strval = "NOTTL"; 497 } 498 if (conf) { 499 sb.append(sep); 500 } 501 sb.append("inactivettlProp=" + strval); 502 conf = true; 503 } 504 } 505 if (timeoutProp != null) { 506 strval = getProperty(props, timeoutProp, ""); 507 if (strval.length() > 0) { 508 props.remove(timeoutProp); 509 try { 510 poolTimeout = Long.parseLong(strval); 511 } catch (NumberFormatException e) { 512 poolTimeout = -1; 513 strval = "WAIT"; 514 } 515 if (conf) { 516 sb.append(sep); 517 } 518 sb.append("timeout=" + strval); 519 conf = true; 520 } 521 } 522 if (conf) { 523 logger.log(BasicLevel.INFO, sb.toString()); 524 PoolAttributes poolAttr; 525 try { 526 poolAttr = (PoolAttributes) 527 Fractal.getAttributeController(pool); 528 } catch (Exception e) { 529 Component[] children = Fractal.getContentController(speedo).getFcSubComponents(); 530 String [] strs= new String [children.length]; 531 for (int i = 0; i < strs.length; ++i) { 532 strs[i] = Fractal.getNameController(children[i]).getFcName(); 533 } 534 throw new RuntimeException ("" + Arrays.asList(strs)); 535 } 536 if (poolMaxSize > -2) { 537 poolAttr.setMaxSize(poolMaxSize); 538 } 539 if (poolMinSize > -2) { 540 poolAttr.setMinSize(poolMinSize); 541 } 542 if (poolTTL > -2) { 543 poolAttr.setTTL(poolTTL); 544 } 545 if (poolInactiveTTL > -2) { 546 poolAttr.setInactiveTTL(poolInactiveTTL); 547 } 548 if (poolTimeout > -2) { 549 poolAttr.setTimeout(poolTimeout); 550 } 551 } 552 } 553 554 559 private void configureCache(Component cm, 560 String cacheLabel, 561 String sizeProp, 562 String autoCleanSizeProp, 563 String autoCleanThresholdProp, 564 String policyProp, 565 Map props) 566 throws Exception { 567 int cacheSize = -2; 568 String autoCleanSize = null; 569 String autoCleanThreshold = null; 570 String policy = null; 571 StringBuffer sb = new StringBuffer (cacheLabel); 573 final String sep = ", "; 574 boolean conf = false; 575 String strval = getProperty(props, sizeProp, ""); 576 if (strval.length()>0) { 577 props.remove(sizeProp); 578 if (strval.equalsIgnoreCase("nolimit")) { 579 cacheSize = CacheAttributeController.NO_LIMIT; 580 } else { 581 cacheSize = Integer.parseInt(strval); 582 } 583 if (conf) { 584 sb.append(sep); 585 } 586 sb.append("max size=" + strval); 587 conf = true; 588 } 589 590 strval = getProperty(props, autoCleanSizeProp, ""); 592 if (strval.length() > 0) { 593 props.remove(autoCleanSizeProp); 594 autoCleanSize = strval; 595 if (conf) { 596 sb.append(sep); 597 } 598 sb.append("auto replacement size=" + strval); 599 conf = true; 600 } 601 602 strval = getProperty(props, autoCleanThresholdProp, ""); 604 if (strval.length() > 0) { 605 props.remove(autoCleanThresholdProp); 606 autoCleanThreshold = strval; 607 if (conf) { 608 sb.append(sep); 609 } 610 sb.append("auto replacement threshold=" + strval); 611 conf = true; 612 } 613 614 strval = getProperty(props, policyProp, ""); 616 if (strval.length() > 0) { 617 props.remove(policyProp); 618 policy = strval; 619 if (conf) { 620 sb.append(sep); 621 } 622 sb.append("replacement policy=" + strval); 623 conf = true; 624 } 625 if (!conf) { 626 return; 627 } 628 logger.log(BasicLevel.INFO, sb.toString()); 629 Component cmC = getSubComponent(cm, "cache-manager"); 630 CacheAttributeController cacheAttr = (CacheAttributeController) 631 Fractal.getAttributeController(cmC); 632 if (cacheSize > -2) { 633 cacheAttr.setMaxObjects(cacheSize); 634 } 635 if (autoCleanSize != null) { 636 cacheAttr.setAutoCleanSize(autoCleanSize); 637 } 638 if (autoCleanThreshold != null) { 639 cacheAttr.setAutoCleanThreshold(autoCleanThreshold); 640 } 641 if (policy != null) { 642 String tempName = null; 643 if (SpeedoProperties.CACHE_REPLCAEMENT_LRU.equalsIgnoreCase(policy)) { 644 } else if (SpeedoProperties.CACHE_REPLCAEMENT_MRU.equalsIgnoreCase(policy)) { 645 tempName = "org.objectweb.perseus.cache.replacement.lib.MRUReplacementManager"; 646 } else if (SpeedoProperties.CACHE_REPLCAEMENT_FIFO.equalsIgnoreCase(policy)) { 647 tempName = "org.objectweb.perseus.cache.replacement.lib.FIFOReplacementManager"; 648 } else { 649 logger.log(BasicLevel.ERROR, new SpeedoException( 650 "Unmanaged cache replacement policy: " + policy)); 651 } 652 if (tempName != null) { 653 Fractal.getBindingController(cm).unbindFc("replacement-manager"); 655 Fractal.getBindingController(cmC).unbindFc("replacement-manager"); 657 Fractal.getBindingController( 659 getSubComponent(cm, "replacement-manager")) 660 .unbindFc("unbind-manager"); 661 662 Fractal.getContentController(cm).removeFcSubComponent( 664 getSubComponent(cm, "replacement-manager")); 665 666 Component new_rm = (Component)getADLFactory().newComponent(tempName, null); 668 Fractal.getNameController(new_rm).setFcName("replacement-manager"); 669 670 Fractal.getContentController(cm).addFcSubComponent(new_rm); 672 673 Object rm = new_rm.getFcInt
|