Package org.objectweb.speedo

Source Code of org.objectweb.speedo.AbstractSpeedo

/**
* Speedo: an implementation of JDO compliant personality on top of JORM generic
* I/O sub-system.
* Copyright (C) 2001-2004 France Telecom R&D
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
*
*
* Contact: speedo@objectweb.org
*
* Authors: S.Chassande-Barrioz.
*
*/
package org.objectweb.speedo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.objectweb.fractal.adl.Factory;
import org.objectweb.fractal.adl.FactoryFactory;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.fractal.api.control.ContentController;
import org.objectweb.fractal.util.Fractal;
import org.objectweb.jorm.api.PMapper;
import org.objectweb.jorm.mapper.rdb.lib.ConnectionSpecJDBC;
import org.objectweb.perseus.cache.api.CacheAttributeController;
import org.objectweb.perseus.concurrency.pessimistic.PessimisticConcurrencyManagerAC;
import org.objectweb.perseus.dependency.api.DependencyGraph;
import org.objectweb.perseus.persistence.concurrency.PConcurrencyManager;
import org.objectweb.perseus.persistence.api.TransactionalPersistenceManagerAttributeController;
import org.objectweb.perseus.persistence.api.WorkingSetFilter;
import org.objectweb.perseus.pool.api.PoolAttributes;
import org.objectweb.speedo.api.Debug;
import org.objectweb.speedo.api.SpeedoException;
import org.objectweb.speedo.api.SpeedoProperties;
import org.objectweb.speedo.api.SpeedoVersion;
import org.objectweb.speedo.api.TransactionListener;
import org.objectweb.speedo.jmx.JMXConfigurator;
import org.objectweb.speedo.jmx.api.MX4J_HtmlAdaptorCA;
import org.objectweb.speedo.lib.BooleanHelper;
import org.objectweb.speedo.lib.FractalHelper;
import org.objectweb.speedo.lib.Personality;
import org.objectweb.speedo.locale.LocaleHelper;
import org.objectweb.speedo.mapper.api.JormFactoryAttributes;
import org.objectweb.speedo.mapper.api.MapperAttributes;
import org.objectweb.speedo.mapper.rdb.JDBCMapperAttributes;
import org.objectweb.speedo.mim.api.MemoryInstanceManagerAttribute;
import org.objectweb.speedo.pm.api.POManagerFactoryItf;
import org.objectweb.speedo.pm.api.POManagerInstanciatorAC;
import org.objectweb.speedo.pm.api.POManagerItf;
import org.objectweb.speedo.query.api.QueryManager;
import org.objectweb.speedo.query.api.QueryManagerAttribute;
import org.objectweb.speedo.sequence.api.SequenceManager;
import org.objectweb.speedo.workingset.lib.AbstractTransaction;
import org.objectweb.util.monolog.Monolog;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Loggable;
import org.objectweb.util.monolog.api.Logger;
import org.objectweb.util.monolog.api.LoggerFactory;

/**
* This class is a client helper which permits to create a new speedo
* instance. Due to the personality constraint the POManagerFactoryItf
* implementation must have a public empty contructor. But the use of
* the fractal components (www.objectweb.org/fractal) needs to use a
* fractal implementation (Julia) to initialize the speedo component.
*
* This class is an implementation of the POManagerFactoryItf interface which
* delegates all calls on a delegate, the real component.
* This class is responsible of the Speedo configuration from a set of property
* specified by a Map (String optionName, Object value). Configuring Speedo
* means to assign parameter to some components or maybe change the architecture
* of Speedo (change some component).
*
* This class must be subclassed for each personality of Speedo.
*
* @author S.Chassande-Barrioz
*/
public abstract class AbstractSpeedo
  implements POManagerFactoryItf, SpeedoProperties {

    private static final long serialVersionUID = 8894700146086754547L;

    private final static String LOGGER_NAME = SpeedoProperties.LOGGER_NAME + ".init";

    private final static String OPTIMISTIC_CONCURRENCY_TEMPLATE =
    "org.objectweb.perseus.concurrency.optimistic.OptimisticConcurrencyManager";
    private final static String DBDELEGATE_CONCURRENCY_TEMPLATE =
    "org.objectweb.perseus.persistence.concurrency.PDbDelegateConcurrencyManager";
  public final static String PM_POOL_PATH = "po-manager-pool";
    public final static String PMI_PATH = "po-manager-instanciator";
    public final static String MIM_PATH = "memory-instance-manager";
    public final static String MEMORY_CACHE_PATH = "tpm.cache-manager";
    public final static String DEPENDENCY_GRAPH_PATH = "tpm.dependency-graph";
    public final static String QUERY_CACHE_PATH = "compiled-query-cache";
    public final static String QUERY_MANAGER = "query-manager";
    public final static String CONNECTION_POOL_PATH = "mapper.pool";
    public final static String MONOLOG_FACTORY_PATH = "monolog-factory";
    public final static String PRIMITIVE_MAPPER_PATH = "mapper.mapper";
    public final static String JORM_FACTORY_PATH = "mapper.jorm-factory";
    public final static String COMPOSITE_TPM_PATH = "tpm";
    public final static String TPM_PATH = "tpm.transactional-persistence-manager";
    public final static String PMF_PATH = "po-manager-factory";
    public final static String JMX_AGENT_PATH = "agent";
    public final static String HTML_JMX_AGENT_PATH = JMX_AGENT_PATH + ".html";


    private final static String FRACTAL_PROVIDER = "fractal.provider";
    private final static String DEFAULT_FRACTAL_PROVIDER
            = "org.objectweb.fractal.julia.Julia";

    private final static String JULIA_LOADER = "julia.loader";
    private final static String DEFAULT_JULIA_LOADER
            = "org.objectweb.fractal.julia.loader.DynamicLoader";

    private final static String JULIA_CONFIG = "julia.config";
    private final static String DEFAULT_JULIA_CONFIG = "julia.cfg";
   
    private static Factory factory = null;

    private static Factory getADLFactory () throws Exception {
        if (factory == null) {
            factory = FactoryFactory.getFactory(FactoryFactory.FRACTAL_BACKEND);
        }
        return factory;
    }

    /**
     * The persistence manager factory delegate
     */
    protected POManagerFactoryItf delegate = null;
    protected Logger logger = null;
    protected Component speedo = null;
  protected boolean isPropertiesInitialized = false;

  protected boolean jmxOn = false;
 
  public AbstractSpeedo() {
  }
   
    /**
     * It creates and initializes a real POManagerFactory with
     * Julia (Fractal implementation).
     */
    public AbstractSpeedo(Map props) throws Throwable {
    try {
      init(props);
      isPropertiesInitialized = true;
    } catch(Throwable e) {
      System.err.println("Error during the instanciation of the Speedo " +
          "persistence manager factory:");
      e.printStackTrace(System.err);
      throw e;
    }
  }
   
  public abstract Personality getPersonality();

    protected abstract void throwUserException(String msg);
  protected abstract boolean isOptimisticTransaction(Map props);
 
    public void stopComponent() {
        logger.log(BasicLevel.INFO, "Stopping Speedo");
        try {
            Fractal.getLifeCycleController(speedo).stopFc();
        } catch (Exception e) {
            logger.log(BasicLevel.ERROR, "Cannot stop Speedo: ", e);
        }
    }

  public POManagerFactoryItf getPMFComponent() throws Exception {
    return delegate;
  }

  public Object getConcurrencyManagerComponent() throws Exception {
    return getSubComponent(speedo, "tpm.concurrency-manager");
  }
 
  public DependencyGraph getDependencyGraph() throws Exception {
      Component cmC = (Component) getConcurrencyManagerComponent();
      Object dg = Fractal.getBindingController(cmC).lookupFc("dependency-graph");
      return (DependencyGraph) dg;
  }
 
  public Collection getMemoryCacheEntries() throws Exception {
      Component cm = getSubComponent(speedo, MEMORY_CACHE_PATH);
    Component cmC = getSubComponent(cm, "cache-manager");
    CacheAttributeController cacheAttr = (CacheAttributeController)
      Fractal.getAttributeController(cmC);
    return cacheAttr.getCurrentEntryIdentifiers();
  }
 
    public POManagerFactoryItf getDelegate() {
        return delegate;
    }

    // IMPLEMENTATION OF THE POManagerFactoryItf INTERFACE //
    //-----------------------------------------------------//

    public POManagerItf getPOManager() {
        return delegate.getPOManager();
    }
    public POManagerItf lookup() {
        return delegate.lookup();
    }
    public SequenceManager getSequenceManager() {
        return delegate.getSequenceManager();
    }
    public void setSequenceManager(SequenceManager sequenceManager) {
        delegate.setSequenceManager(sequenceManager);
    }
    public QueryManager getQueryManager() {
        return delegate.getQueryManager();
    }
    public void setQueryManager(QueryManager queryManager) {
        delegate.setQueryManager(queryManager);
    }
    public void unbindPM() {
        delegate.unbindPM();
    }
    public void bindPM2Thread(POManagerItf pm) {
        delegate.bindPM2Thread(pm);
    }
    public void poManagerClosed(POManagerItf pr) {
        delegate.poManagerClosed(pr);
    }
    public void clean() {
        delegate.clean();
    }
    public Properties getProperties() {
        return delegate.getProperties();
    }

    // methods for speedo configuration //
    //----------------------------------//


  protected Component getSpeedoComponent(Map props) throws Throwable {
    if (speedo == null) {
      //use Julia as Fractal implementation
      System.setProperty(FRACTAL_PROVIDER, DEFAULT_FRACTAL_PROVIDER);
      System.setProperty(JULIA_LOADER, DEFAULT_JULIA_LOADER);
      System.setProperty(JULIA_CONFIG, DEFAULT_JULIA_CONFIG);

      //Allocate a Logger through the LoggerFactory component
      Monolog.initialize();
      LoggerFactory loggerFactory = Monolog.monologFactory;
      logger = loggerFactory.getLogger(LOGGER_NAME);

      //Choose the fractal template according to the JMX option
      String templateName;
      if (props != null && BooleanHelper.parse(
                    getProperty(props, JMX, "false", false), false)) {
                templateName = "SpeedoJMX";
      } else {
                templateName = "Speedo";               
            }
      //Choose the fractal template corresponding to the personality
            templateName = getPersonality()
              .getPersonalityClassName("org.objectweb.speedo", templateName);
           
      //instanciate the Speedo component
            Component speedoTemplate = null;
      try {
        speedoTemplate = (Component)getADLFactory().newComponent(
                  templateName,
                  Collections.singletonMap("template", "true"));
        speedo = Fractal.getFactory(speedoTemplate).newFcInstance();
      } catch (Throwable e) {
        System.err.println("Error during the template loading or the " +
            "component instanciation '" + speedoTemplate + "': ");
        throw e;
      }
      Fractal.getNameController(speedo).setFcName("org.objectweb.speedo");
      delegate = (POManagerFactoryItf)
                speedo.getFcInterface("po-manager-factory")
    }
    return speedo;
  }
 
  public void init(Map pmfProps) throws Throwable {
        getSpeedoComponent(pmfProps);
      logger.log(BasicLevel.INFO, "Speedo " + SpeedoVersion.SPEEDO_VERSION
              + LocaleHelper.getSpeedoRB().getString("start"));
    configure(pmfProps);
    delegate.getProperties().putAll(pmfProps);
        Fractal.getLifeCycleController(speedo).startFc();
    if (jmxOn) {
        new JMXConfigurator(speedo, logger).init();
    }
      logger.log(BasicLevel.INFO, "Speedo " + SpeedoVersion.SPEEDO_VERSION
              + LocaleHelper.getSpeedoRB().getString("ready"));
    }

  protected void configure(Map pmfProps) throws Throwable {
      Map props = new HashMap(pmfProps);
      applyProperties(props, pmfProps);
        //Warn the unknwon properties
    for (Iterator it = props.entrySet().iterator(); it.hasNext();) {
      Map.Entry me = (Map.Entry) it.next();
      String key = (String) me.getKey();
      if (key.startsWith(CACHE_CLASS_POLICY+"(")
              || key.startsWith(USER_CACHE_CLASS_POLICY+"(")
              || key.startsWith(PREFETCH_ON_GENCLASS+"(")
              || key.startsWith(PREFETCH_ON_QUERY+"(")
                    || key.startsWith(PREFETCH_ON_EXTENT+"(")
                    || key.startsWith(SHAREABLE)
              ) {
          continue;
      }
      String value = (String) me.getValue();
      logger.log(BasicLevel.WARN, "The (" + key + ", " + value
        + ") property is not managed");
    }
    }
 
    protected void applyProperties(Map props, Map pmfProps) throws Throwable {
    //Debug Mode
    String strval = getProperty(props, SpeedoProperties.DEBUG, null, true);
    if (strval != null) {
      Debug.ON = Boolean.valueOf(strval).booleanValue();
      logger.log(BasicLevel.INFO, SpeedoProperties.DEBUG + ": " + Debug.ON);
    }
    configureMIM(getSubComponent(speedo, MIM_PATH), props);
    configurePOMI(getSubComponent(speedo, PMI_PATH), props);
    boolean useConnectionFactory = configureMapper(props);
    configurePool(getSubComponent(speedo, PM_POOL_PATH),
            "PersistenceManager pool: ",
        PM_POOL_MIN,
        PM_POOL_MAX,
        PM_POOL_TTL,
        PM_POOL_INACTIVETTL,
        PM_POOL_TIMEOUT,
        props);
      configureCache(getSubComponent(speedo, MEMORY_CACHE_PATH),
              "Persistent objects cache: ",
              CACHE_SIZE,
              CACHE_AUTO_CLEAN_SIZE,
              CACHE_AUTO_CLEAN_THRESHOLD,
              CACHE_REPLCAEMENT,
              props);
      configureCache(getSubComponent(speedo, QUERY_CACHE_PATH),
              "Compiled query cache: ",
              COMPILED_QUERY_CACHE_SIZE,
              COMPILED_QUERY_CACHE_AUTO_CLEAN_SIZE,
              COMPILED_QUERY_CACHE_AUTO_CLEAN_THRESHOLD,
              COMPILED_QUERY_CACHE_POLICY,
              props);
     configureTPM(getSubComponent(speedo, TPM_PATH),
          "Transactionnal persistence manager: ",
        TRANSACTION_FILTERS,
        props);

    strval = getProperty(props, IMRICATED_PM_ALLOWED, "false", true);
    boolean imbricatedPM = Boolean.valueOf(strval).booleanValue();
    if (imbricatedPM) {
        logger.log(BasicLevel.INFO, LocaleHelper.getSpeedoRB().getString("pmreused"));
    }


    configurePrefetching(props);
    configureConcurrencyManager(props);
    configureTransaction(props, pmfProps, useConnectionFactory);
    jmxOn = configureJMX(props);
    }   
   
    protected String getProperty(Map m,
        String propName,
        String defaultValue,
        boolean remove) {
        Object res = remove ? m.remove(propName) : m.get(propName);
        if (res instanceof String) {
            return (String) res;
        } else  {
            return defaultValue;
        }
    }

    protected boolean removeProps(Map props, String[] wanted) {
      boolean found = false;
      for (int i = 0; i < wanted.length; i++) {
            found |= props.remove(wanted[i]) != null;
        }
      return found;
  }
   
    private Component getSubComponent(Component parent,
            String path) throws Exception {
        return FractalHelper.getSubComponent(parent, path, logger);
    }
   
    private void configureMIM(Component mimC, Map props) throws Exception {
      MemoryInstanceManagerAttribute mima = (MemoryInstanceManagerAttribute)
        Fractal.getAttributeController(mimC);
      mima.setPersonality(getPersonality());
    }

    private void configurePOMI(Component pomiC, Map props) throws Exception {
      POManagerInstanciatorAC pomiac = (POManagerInstanciatorAC)
        Fractal.getAttributeController(pomiC);
      pomiac.setPOManagerTemplateName("org.objectweb.speedo.pm."
          + getPersonality().getName() + ".lib."
            + getPersonality().getName().toUpperCase() + "POManager");
      pomiac.setTransactionTemplateName("org.objectweb.speedo.workingset."
          + getPersonality().getName() + ".lib."
            + getPersonality().getName().toUpperCase() + "TransactionImpl");
    }

    private void configurePool(Component pool,
                       String poolLabel,
                 String minProp,
                 String maxProp,
                 String ttlProp,
                 String inactivettlProp,
                 String timeoutProp,
                 Map props) throws Exception {
    String strval = null;
    int poolMinSize = -2;
    int poolMaxSize = -2;
    long poolTTL = -2;
    long poolInactiveTTL = -2;
    long poolTimeout = -2;
    boolean conf = false;
    StringBuffer sb = new StringBuffer(poolLabel);
    final String sep = ", ";
    if (minProp != null) {
      strval = getProperty(props, minProp, "", true);
      if (strval.length() > 0) {
        poolMinSize = Integer.parseInt(strval);
        if (conf) {
            sb.append(sep);
        }
        sb.append("min=" + strval);
        conf = true;
      }
    }
    if (maxProp != null) {
      strval = getProperty(props, maxProp, "", true);
      if (strval.length() > 0) {
        if (strval.equalsIgnoreCase("nolimit")) {
          poolMaxSize = -1;
        } else {
          poolMaxSize = Integer.parseInt(strval);
        }
        if (conf) {
            sb.append(sep);
        }
        sb.append("max=" + strval);
        conf = true;
      }
    }
    if (ttlProp != null) {
      strval = getProperty(props, ttlProp, "", true);
      if (strval.length() > 0) {
        try {
          poolTTL = 1000 * Long.parseLong(strval);
        } catch (NumberFormatException e) {
          poolTTL = -1;
          strval = "NOTTL";
        }
        if (conf) {
            sb.append(sep);
        }
        sb.append("ttl=" + strval);
        conf = true;
      }
    }
    if (inactivettlProp != null) {
      strval = getProperty(props, inactivettlProp, "", true);
      if (strval.length() > 0) {
        try {
          poolInactiveTTL = 1000 * Long.parseLong(strval);
        } catch (NumberFormatException e) {
            poolInactiveTTL = -1;
          strval = "NOTTL";
        }
        if (conf) {
            sb.append(sep);
        }
        sb.append("inactivettlProp=" + strval);
        conf = true;
      }
    }
    if (timeoutProp != null) {
      strval = getProperty(props, timeoutProp, "", true);
      if (strval.length() > 0) {
        try {
          poolTimeout = Long.parseLong(strval);
        } catch (NumberFormatException e) {
          poolTimeout = -1;
          strval = "WAIT";
        }
        if (conf) {
            sb.append(sep);
        }
        sb.append("timeout=" + strval);
        conf = true;
      }
    }
    if (conf) {
      logger.log(BasicLevel.INFO, sb.toString());
          PoolAttributes poolAttr;
          try {
            poolAttr = (PoolAttributes)
              Fractal.getAttributeController(pool);
          } catch (Exception e) {
            Component[] children = Fractal.getContentController(speedo).getFcSubComponents();
            String[] strs= new String[children.length];
            for (int i = 0; i < strs.length; ++i) {
              strs[i] = Fractal.getNameController(children[i]).getFcName();
            }
            throw new RuntimeException("" + Arrays.asList(strs));
          }
      if (poolMaxSize > -2) {
        poolAttr.setMaxSize(poolMaxSize);
      }
      if (poolMinSize > -2) {
        poolAttr.setMinSize(poolMinSize);
      }
      if (poolTTL > -2) {
        poolAttr.setTTL(poolTTL);
      }
      if (poolInactiveTTL > -2) {
        poolAttr.setInactiveTTL(poolInactiveTTL);
      }
      if (poolTimeout > -2) {
        poolAttr.setTimeout(poolTimeout);
      }
    }
  }

  /**
   * Configures the memory cache.
   * @param cm is the cache composite component
   * @param props is the speedo initialisation properties
   */
  private void configureCache(Component cm,
          String cacheLabel,
          String sizeProp,
          String autoCleanSizeProp,
          String autoCleanThresholdProp,
          String policyProp,
          Map props)
      throws Exception {
    int cacheSize = -2;
    String autoCleanSize = null;
    String autoCleanThreshold = null;
    String policy = null;
    //configure the cache size
    StringBuffer sb = new StringBuffer(cacheLabel);
    final String sep = ", ";
    boolean conf = false;
    String strval = getProperty(props, sizeProp, "", true);
    if (strval.length()>0) {
      if (strval.equalsIgnoreCase("nolimit")) {
        cacheSize = CacheAttributeController.NO_LIMIT;
      } else {
        cacheSize = Integer.parseInt(strval);
      }
      if (conf) {
          sb.append(sep);
      }
      sb.append("max size=" + strval);
      conf = true;
    }

    //configure the cache auto clean size
    strval = getProperty(props, autoCleanSizeProp, "", true);
    if (strval.length() > 0) {
      autoCleanSize = strval;
      if (conf) {
          sb.append(sep);
      }
      sb.append("auto replacement size=" + strval);
      conf = true;
    }

    //configure the cache auto clean size
    strval = getProperty(props, autoCleanThresholdProp, "", true);
    if (strval.length() > 0) {
      autoCleanThreshold = strval;
      if (conf) {
          sb.append(sep);
      }
      sb.append("auto replacement threshold=" + strval);
      conf = true;
    }

    //configure the replacement policy of the cache (Replacement manager)
    strval = getProperty(props, policyProp, "", true);
    if (strval.length() > 0) {
      policy = strval;
      if (conf) {
          sb.append(sep);
      }
      sb.append("replacement policy=" + strval);
      conf = true;
    }
    if (!conf) {
        return;
    }
      logger.log(BasicLevel.INFO, sb.toString());
    Component cmC = getSubComponent(cm, "cache-manager");
    CacheAttributeController cacheAttr = (CacheAttributeController)
      Fractal.getAttributeController(cmC);
    if (cacheSize > -2) {
      cacheAttr.setMaxObjects(cacheSize);
    }
    if (autoCleanSize != null) {
      cacheAttr.setAutoCleanSize(autoCleanSize);
    }
    if (autoCleanThreshold != null) {
      cacheAttr.setAutoCleanThreshold(autoCleanThreshold);
    }
    if (policy != null) {
      String tempName = null;
      if (CACHE_REPLCAEMENT_LRU.equalsIgnoreCase(policy)) {
      } else if (CACHE_REPLCAEMENT_MRU.equalsIgnoreCase(policy)) {
        tempName = "org.objectweb.perseus.cache.replacement.lib.MRUReplacementManager";
      } else if (CACHE_REPLCAEMENT_FIFO.equalsIgnoreCase(policy)) {
        tempName = "org.objectweb.perseus.cache.replacement.lib.FIFOReplacementManager";
      } else {
        logger.log(BasicLevel.ERROR, new SpeedoException(
            "Unmanaged cache replacement policy: " + policy));
      }
      if (tempName != null) {
        //unbind the rm from the composite
        Fractal.getBindingController(cm).unbindFc("replacement-manager");
        //unbind the rm from the primitive cm
        Fractal.getBindingController(cmC).unbindFc("replacement-manager");
        //unbind the primitive cm from the old rm
        Fractal.getBindingController(
            getSubComponent(cm, "replacement-manager"))
            .unbindFc("unbind-manager");

        //remove the old rm from the composite
        Fractal.getContentController(cm).removeFcSubComponent(
            getSubComponent(cm, "replacement-manager"));

        //instanciate the new component
        Component new_rm = (Component)getADLFactory().newComponent(tempName, null);
        Fractal.getNameController(new_rm).setFcName("replacement-manager");

        //Add the new rm in the composite
        Fractal.getContentController(cm).addFcSubComponent(new_rm);

        Object rm = new_rm.getFcInterface("replacement-manager");
        //bind the rm to the composite
        Fractal.getBindingController(cm).bindFc("replacement-manager", rm);
        //bind the rm to the primitive cm
        Fractal.getBindingController(cmC).bindFc("replacement-manager", rm);
        //bind the primitive cm to the new rm
        Fractal.getBindingController(new_rm).bindFc("unbind-manager",
            cmC.getFcInterface("unbind-manager"));
      }
    }
  }


  /**
   * Configures the transactional persistence manager
   * @param tpm is the component
   * @param props is the speedo initialisation properties
   */
  private void configureTPM(Component tpm,
      String tpmLabel,
          String filtersProp,
          Map props)
      throws Exception {
    String strval = getProperty(props, filtersProp, "", true);
    Collection filters = new ArrayList(1);
    //configure the list of filters (separated by ",")
    if (strval.length()>0) {
      filters = new ArrayList();
      String filterClassName;
      while (strval.length() > 0) {
        int coma = strval.indexOf(",");
        if (coma != -1) {
          filterClassName = strval.substring(0, coma);
          strval = strval.substring(coma + 1);
        } else {
          filterClassName = strval;
          strval = "";
        }
        try {
          //instanciate a filter class
          WorkingSetFilter filter = (WorkingSetFilter) Class.forName(filterClassName).newInstance();
          //add it to the list
          filters.add(filter);
        } catch (Exception e) {
          System.err.println("Error during the configuration of the tpm");
          e.printStackTrace(System.err);
          throw e;
        }
      }
    }
    //add the filters to the tpm
    if (!filters.isEmpty()) {
      TransactionalPersistenceManagerAttributeController tpmAttr = (TransactionalPersistenceManagerAttributeController)
        Fractal.getAttributeController(tpm);
      tpmAttr.setFilters(filters);
    }
  }
 
  private void configureTransaction(Map props, Map pmfProps, boolean useConnectionFactory) throws Exception {
    //deprecated properties
    final String TM_NAME_old = "org.objectweb.perseus.connector.ra.jdo.TMName";
    String strval = getProperty(props, TM_NAME_old, "", true);
    if (strval.length()>0) {
      logger.log(BasicLevel.WARN, "Property " + TM_NAME_old
          + " is deprecated, you must use " + TM_NAME);
      if (getProperty(props, TM_NAME, null, true) == null) {
        pmfProps.put(TM_NAME, strval);
      }
    }

    // Transaction managed by an application server
    strval = getProperty(props, MANAGED, "", false);
    if (strval.length()>0) {
      boolean b = BooleanHelper.parse(strval, false);
      if (!useConnectionFactory && b) {
        String msg = "In a managed environnement, a connection factory is required";
        logger.log(BasicLevel.ERROR, msg);
        throwUserException(msg);
      }
      logger.log(BasicLevel.INFO, MANAGED + LocaleHelper.getSpeedoRB().getString("speedused")
          + (b
          ? LocaleHelper.getSpeedoRB().getString("managed")
          : LocaleHelper.getSpeedoRB().getString("standalone")));

      //TransactionManager JNDI name
      strval = getProperty(props, TM_NAME, "", true);
      logger.log(BasicLevel.INFO, TM_NAME + "="
          + (strval.length()>0
          ? strval
          :  LocaleHelper.getSpeedoRB().getString("tmspec")));
    } else {
      props.remove(TM_NAME);
    }

    //Listener of Transaction life cycle (statistic)
    strval = getProperty(props, TX_LISTENER, "", true);
    if (strval.length()>0) {
      try {
        AbstractTransaction.txListener = (TransactionListener)
            Class.forName(strval).newInstance();
        if (AbstractTransaction.txListener instanceof Loggable) {
          ((Loggable) AbstractTransaction.txListener)
              .setLoggerFactory(Monolog.monologFactory);
        }
        logger.log(BasicLevel.INFO, "Transaction listener: " + strval);
      } catch (Exception e) {
        logger.log(BasicLevel.WARN,
            LocaleHelper.getSpeedoRB().getString("txlisten")
            + " ('" + strval + "'): ", e);
      }
    }
  }

  private void configureConcurrencyManager(Map props) throws Exception {
    String tempName;
    StringBuffer sb = new StringBuffer(LocaleHelper.getSpeedoRB().getString("txconcmgt"));
        String strval = getProperty(props, TRANSACTION_LOCKING,
              SPEEDO_TRANSACTION_LOCKING, true);
    boolean dbLocking = strval.equals(DB_TRANSACTION_LOCKING);
        boolean optimistic = isOptimisticTransaction(props);;
        if (dbLocking && optimistic) {
          logger.log(BasicLevel.WARN, sb.toString()
              + LocaleHelper.getSpeedoRB().getString("dbpessim"));
          optimistic = false;
        }
        sb.append("mode=").append((optimistic ? LocaleHelper.getSpeedoRB().getString("optim")
            : LocaleHelper.getSpeedoRB().getString("pessim")));
    //fetch the composite TPM
    Component composite_tpm = getSubComponent(speedo, COMPOSITE_TPM_PATH);
    Component cm = getSubComponent(composite_tpm, "concurrency-manager");
      if (dbLocking) {
          tempName = DBDELEGATE_CONCURRENCY_TEMPLATE;
          sb.append(LocaleHelper.getSpeedoRB().getString("concdeleg"));
      } else {
          sb.append(LocaleHelper.getSpeedoRB().getString("concspeed"));
          if (!optimistic) {
              //Configure the pessimistic concurrency manager
           
            //policy= mutex | rw-fifo | rw-reader
            strval = getProperty(props,
                    TRANSACTION_LOCKING_PESSIMISTIC_POLICY,
                    TRANSACTION_LOCKING_PESSIMISTIC_POLICY_RW_FIFO, true);
            PessimisticConcurrencyManagerAC pcmAC = null;
            if (!strval.equals(TRANSACTION_LOCKING_PESSIMISTIC_POLICY_RW_FIFO)) {
                pcmAC = (PessimisticConcurrencyManagerAC)
                    Fractal.getAttributeController(cm);
                    strval = strval.toUpperCase();
                    if (!strval.startsWith("POLICY_")) {
                        strval = "POLICY_" + strval;
                    }
                pcmAC.setPolicy(strval);
                sb.append(LocaleHelper.getSpeedoRB().getString("lockpol")).append(strval);
            }

            //locking level = instance | field
            strval = getProperty(props,
                    TRANSACTION_LOCKING_LEVEL_ENABLETHIN,
                    "false", true);
            boolean b = BooleanHelper.parse(strval, false);
            if (b) {
              logger.log(BasicLevel.INFO, LocaleHelper.getSpeedoRB().getString("thinlock"));
                pcmAC = (PessimisticConcurrencyManagerAC)
                    Fractal.getAttributeController(cm);
                pcmAC.setThinkLockAllowed(true);
                sb.append(LocaleHelper.getSpeedoRB().getString("thlklvl"));
            }
          logger.log(BasicLevel.INFO, sb.toString());
              return;
          }
      tempName = OPTIMISTIC_CONCURRENCY_TEMPLATE;
      }
      //optimistic or dblocking
      logger.log(BasicLevel.INFO, sb.toString());

        ContentController tpmCC = Fractal.getContentController(composite_tpm);
    //fetch the primitive concurrency manager
    BindingController tpmBC = Fractal.getBindingController(
        getSubComponent(composite_tpm, "transactional-persistence-manager"));
    tpmBC.unbindFc("concurrency-manager");

    //Remove the old pessimistic concurrency manager
    BindingController cmBC = Fractal.getBindingController(cm);
        String[] bds = cmBC.listFc();
        for (int i = 0; i < bds.length; i++) {
            cmBC.unbindFc(bds[i]);
        }
    tpmCC.removeFcSubComponent(cm);


    //instanciate the new ConcurrencyManager
    cm = (Component)getADLFactory().newComponent(tempName, null);
    //Add the new concurrency manager into the composite
    tpmCC.addFcSubComponent(cm);
    //bind the server interface of the new concurrency manager
    cmBC = Fractal.getBindingController(cm);
    if (dbLocking) {
            cmBC.bindFc(PConcurrencyManager.STATE_MANAGER_BINDING,
                    tpmCC.getFcInternalInterface("state-manager"));
            cmBC.bindFc(PConcurrencyManager.STORAGE_MANAGER_BINDING,
                    tpmCC.getFcInternalInterface("storage-manager"));
        } else {//optimistic
      cmBC.bindFc(PConcurrencyManager.DEPENDENCY_GRAPH_BINDING,
        getSubComponent(composite_tpm, "dependency-graph")
        .getFcInterface("dependency-graph"));
    }

    //bind the client interface of the new ConcurrencyManager
    tpmBC.bindFc("concurrency-manager", cm.getFcInterface("concurrency-manager"));
  }

  private void configurePrefetching(Map props) throws Throwable {
    //Data prefetching on queries
    boolean prefetch = true;
    StringBuffer sb = new StringBuffer(LocaleHelper.getSpeedoRB().getString("prefetch"));
    String strval = getProperty(props, PREFETCH, "", true);
    if (strval.length()>0) {
      prefetch = BooleanHelper.parse(strval, false);
    }
    Component qm = getSubComponent(speedo, QUERY_MANAGER);
    QueryManagerAttribute qma = ((QueryManagerAttribute) Fractal.getAttributeController(qm));
    if (!prefetch) {
      qma.setPrefetchActivatedOnQuery(false);
      qma.setPrefetchActivatedOnExtent(false);
      logger.log(BasicLevel.INFO, sb.append(LocaleHelper.getSpeedoRB().getString("NONE")).toString());
        return;
    }
    boolean prefetchOnQuery = qma.getPrefetchActivatedOnQuery();
    boolean prefetchOnExtent = qma.getPrefetchActivatedOnExtent();
    boolean prefetchOnGenClass = true;
    String sep = ", ";

    boolean oneOf = false;
      strval = getProperty(props, PREFETCH_ON_QUERY, "", true);
    if (strval.length()>0) {
      prefetchOnQuery = BooleanHelper.parse(strval, false);
    }
    if (prefetchOnQuery) {
      if (oneOf) {
          sb.append(sep);
      }
        sb.append(LocaleHelper.getSpeedoRB().getString("QUERY"));
    }
    oneOf |= prefetchOnQuery;
    qma.setPrefetchActivatedOnQuery(prefetchOnQuery);

    strval = getProperty(props, PREFETCH_ON_EXTENT, "", true);
    if (strval.length()>0) {
      prefetchOnExtent = BooleanHelper.parse(strval, false);
    }
    if (prefetchOnExtent) {
      if (oneOf) {
          sb.append(sep);
      }
        sb.append(LocaleHelper.getSpeedoRB().getString("EXTENT"));
    }
    oneOf |= prefetchOnExtent;
    qma.setPrefetchActivatedOnExtent(prefetchOnExtent);

    strval = getProperty(props, PREFETCH_ON_GENCLASS, "", true);
    if (strval.length()>0) {
      prefetchOnGenClass= BooleanHelper.parse(strval, false);
    }
    if (prefetchOnGenClass) {
      if (oneOf) {
          sb.append(sep);
      }
        sb.append(LocaleHelper.getSpeedoRB().getString("COLLECTION"));
    }
    oneOf |= prefetchOnGenClass;
   
    logger.log(BasicLevel.INFO, sb.toString());
  }

  /**
   * Configures the mapper component
   * @param props is the properties of Speedo
   * @return true if a connection factory is used, false if the JDBC driver is
   * used directly.
   * @throws Throwable if an error or an exception occurs
   */
  private boolean configureMapper(Map props) throws Throwable {
    boolean useConnectionFactory;
    String mapperName = getProperty(props, MAPPER_NAME, "rdb.automatic", true);

    Component component = getSubComponent(speedo, PRIMITIVE_MAPPER_PATH);
    String strval = null;
    //Choose the mapper in according to the connection factory (JCA or JDBC)
    String cfName = getProperty(props, JDO_OPTION_CONNECTION_FACTORY_NAME, null, true);
    useConnectionFactory = cfName != null && cfName.length() > 0;
        Object o = Fractal.getAttributeController(component);
    MapperAttributes ma = (MapperAttributes) o;
    if (useConnectionFactory) {
      Object cf = null;
      //There is a connection factory
      try {
        InitialContext ic = new InitialContext();
        cf = ic.lookup(cfName);
      } catch (NamingException e) {
        throw new SpeedoException(
            "Problem to get the connection factory in JNDI ("
            + cfName + ")", e);
      }
      if (cf == null) {
        throw new SpeedoException(
            "No connection factory registered in JNDI with the name "
            + cfName);
      } else if (cf instanceof ConnectionSpecJDBC) {
        // Use the JDBC Mapper ==> nothing to do
      } else if (cf instanceof javax.sql.DataSource) {
        // Use the JDBC Mapper ==> nothing to do
      } else if (cf instanceof javax.resource.cci.ConnectionFactory) {
        throw new SpeedoException("JCA datasource no yet supported");
      } else {
        throw new SpeedoException("The connection factory registered "
            + "in JNDI is not supported by Speedo " + cfName + " => "
            + cf);
      }
      boolean ignoring = removeProps(props, new String[]{
              JDO_OPTION_CONNECTION_DRIVER_NAME_OLD,
              JDO_OPTION_CONNECTION_DRIVER_NAME_OLD2,
              JDO_OPTION_CONNECTION_DRIVER_NAME,
              JDO_OPTION_CONNECTION_URL,
              JDO_OPTION_CONNECTION_USER_NAME,
              JDO_OPTION_CONNECTION_PASSWORD});
      if (ignoring) {
          logger.log(BasicLevel.WARN,
              LocaleHelper.getSpeedoRB().getString("ignjdbcinfo"));
      }
      ignoring = removeProps(props, new String[]{
              CONNECTION_POOL_MIN,
              CONNECTION_POOL_MAX,
              CONNECTION_POOL_TTL,
              CONNECTION_POOL_TIMEOUT});
      if (ignoring) {
          logger.log(BasicLevel.WARN,
              LocaleHelper.getSpeedoRB().getString("ignconninfo"));
      }

      //Assign the connection factory to the mapper
      logger.log(BasicLevel.INFO, LocaleHelper.getSpeedoRB().getString("connfact")
          + LocaleHelper.getSpeedoRB().getString("jndinm") + cfName
          + LocaleHelper.getSpeedoRB().getString("factfound") + cf
          + LocaleHelper.getSpeedoRB().getString("mappernm") + mapperName);
      PMapper mapper = (PMapper) component.getFcInterface("mapper");
      mapper.setMapperName(mapperName);
      mapper.setConnectionFactory(cf);

    } else {
      JDBCMapperAttributes jdbcma = (JDBCMapperAttributes) ma;

      //deprecated properties
      strval = getProperty(props, JDO_OPTION_CONNECTION_DRIVER_NAME_OLD, "", true);
      if (strval.length()>0) {
        logger.log(BasicLevel.WARN, LocaleHelper.getSpeedoRB().getString("property")
            + " " + JDO_OPTION_CONNECTION_DRIVER_NAME_OLD
            + LocaleHelper.getSpeedoRB().getString("deprecuse") + JDO_OPTION_CONNECTION_DRIVER_NAME);
        if (getProperty(props, JDO_OPTION_CONNECTION_DRIVER_NAME, null, false) == null) {
                    props.put(JDO_OPTION_CONNECTION_DRIVER_NAME, strval);
        }
      }
      strval = getProperty(props, JDO_OPTION_CONNECTION_DRIVER_NAME_OLD2, "", true);
      if (strval.length()>0) {
        logger.log(BasicLevel.WARN, LocaleHelper.getSpeedoRB().getString("property")
            + " " + JDO_OPTION_CONNECTION_DRIVER_NAME_OLD2
            + LocaleHelper.getSpeedoRB().getString("deprecuse") + JDO_OPTION_CONNECTION_DRIVER_NAME);
        if (getProperty(props, JDO_OPTION_CONNECTION_DRIVER_NAME, null, false) == null) {
                    props.put(JDO_OPTION_CONNECTION_DRIVER_NAME, strval);
        }
      }
      String jdbcDriverCN = getProperty(props, JDO_OPTION_CONNECTION_DRIVER_NAME, null, true);
      String jdbcUser = getProperty(props, JDO_OPTION_CONNECTION_USER_NAME, null, true);
      String jdbcUrl = getProperty(props, JDO_OPTION_CONNECTION_URL, null, true);
      String jdbcPass = getProperty(props, JDO_OPTION_CONNECTION_PASSWORD, null, true);
      logger.log(BasicLevel.INFO, LocaleHelper.getSpeedoRB().getString("jdbcdrv")
          + LocaleHelper.getSpeedoRB().getString("driver") + jdbcDriverCN
          + LocaleHelper.getSpeedoRB().getString("url") + jdbcUrl
          + LocaleHelper.getSpeedoRB().getString("user") + jdbcUser
          + LocaleHelper.getSpeedoRB().getString("mappernm") + mapperName);
      jdbcma.setMapperName(mapperName);
      jdbcma.setDriverClassName(jdbcDriverCN);
      jdbcma.setURL(jdbcUrl);
      jdbcma.setUserName(jdbcUser);
      jdbcma.setPassword(jdbcPass);
      jdbcma.setPoolConnection(true);

      //configure the pool of connection
      configurePool(getSubComponent(speedo, CONNECTION_POOL_PATH),
              "Connection pool: ",
          CONNECTION_POOL_MIN,
          CONNECTION_POOL_MAX,
          CONNECTION_POOL_TTL,
          CONNECTION_POOL_INACTIVETTL,
          CONNECTION_POOL_TIMEOUT,
          props);
    }
    strval = (String) props.remove(CONNECTION_CHECK);
    if (strval != null) {
        boolean v = BooleanHelper.parse(strval, false);
        ma.setCheckConnectivityAtStartup(v);
        if (!v) {
        logger.log(BasicLevel.INFO, LocaleHelper.getSpeedoRB().getString("noconnchk"));
        }
    }   

    //initialize the JormFactory with the mappingStructureRule attribute
    byte mappingStructureRule = JormFactoryAttributes.CREATE_IF_REQUIRED;
    strval = getProperty(props, MAPPING_STRUCTURE, "", true);
    if (strval.length()>0) {
      mappingStructureRule = getMappingStructure(strval);
      if (mappingStructureRule == -1) {
          mappingStructureRule = JormFactoryAttributes.CREATE_IF_REQUIRED;
        logger.log(BasicLevel.WARN,
            LocaleHelper.getSpeedoRB().getString("unexpprop")
            + MAPPING_STRUCTURE
            + LocaleHelper.getSpeedoRB().getString("pfound")
            + strval
            + LocaleHelper.getSpeedoRB().getString("pexpect")
            + MAPPING_STRUCTURE_DN
            + " | " + MAPPING_STRUCTURE_DD
            + " | " + MAPPING_STRUCTURE_CIR
            + " | " + MAPPING_STRUCTURE_FC
            + "]");
      }
    }
    component = getSubComponent(speedo, JORM_FACTORY_PATH);
    JormFactoryAttributes jfa = (JormFactoryAttributes)
                    Fractal.getAttributeController(component);
    jfa.setMappingStructureRule(mappingStructureRule);
    logger.log(BasicLevel.INFO, LocaleHelper.getSpeedoRB().getString("datast")
        + getMappingStructureString(mappingStructureRule));
    jfa.setPersonality(getPersonality());

    Properties jormFactoryProperties = new Properties();
        for (Iterator it = props.entrySet().iterator(); it.hasNext();) {
            Map.Entry me = (Map.Entry) it.next();
            String key = (String) me.getKey();
            String value = (String) me.getValue();
      boolean knownProperty = true;
          if (key.indexOf('(') != -1) {
              jormFactoryProperties.put(key, value);
            } else {
        knownProperty = false;
            }
      if (knownProperty) {
        logger.log(BasicLevel.INFO, key + ": " + value);
        it.remove();
      }
        }
        jfa.setSpeedoProperties(jormFactoryProperties);
   
    return useConnectionFactory;
  }

  private boolean configureJMX(Map props) throws Throwable {
      String val = (String) props.remove(JMX);
      if (!BooleanHelper.parse(val, false)) {
          return false;
      }
      //JMX must me configured
      if (Monolog.monologFactory.getLogger(JMX)
              .isLoggable(BasicLevel.DEBUG)) {
          //active MX4J logging
      System.setProperty("mx4j.log.priority", "debug");
      }
      val = (String) props.remove(JMX_HTTP_PORT);
      int port = 0;
      if (val != null) {
          try {
                port = Integer.parseInt(val);
            } catch (NumberFormatException e) {
                logger.log(BasicLevel.WARN, LocaleHelper.getSpeedoRB().getString("badhttp") + val);
                port = -1;
            }
      }
    Component component = getSubComponent(speedo, HTML_JMX_AGENT_PATH);
      if (port < 0) {
          //unbind the html sub component
          Fractal.getBindingController(component).unbindFc("adminAtt");
          // remove the html sub component from the agent component.
      Fractal.getContentController(
              getSubComponent(speedo, JMX_AGENT_PATH))
                .removeFcSubComponent(component);
      logger.log(BasicLevel.INFO, LocaleHelper.getSpeedoRB().getString("jmxactiv"));
      } else {
          if (port == 0) {
            //TODO: find a free port for the http console
              port = 8000;
          }
          //get the host
          String host = (String) props.remove(JMX_HTTP_HOST);
        if (host == null || host.length() == 0) {
          host = JMX_HTTP_DEFAULT_HOST;
        }
          //Assign the port and the host to the component
      MX4J_HtmlAdaptorCA att = (MX4J_HtmlAdaptorCA)
        Fractal.getAttributeController(component);
          att.setPort(port);
          att.setHost(host);
      logger.log(BasicLevel.INFO, LocaleHelper.getSpeedoRB().getString("jmxhttp")
          +  port
          + LocaleHelper.getSpeedoRB().getString("forhost")
          + host
          + LocaleHelper.getSpeedoRB().getString("activated"));
      }
      return true;
  }
   
  public static String getMappingStructureString(byte b) {
    switch(b) {
    case JormFactoryAttributes.DO_NOTHING:
      return MAPPING_STRUCTURE_DN;
    case JormFactoryAttributes.DELETE_DATA:
      return MAPPING_STRUCTURE_DD;
    case JormFactoryAttributes.FORCE_CREATE:
      return MAPPING_STRUCTURE_FC;
    case JormFactoryAttributes.CREATE_IF_REQUIRED:
      return MAPPING_STRUCTURE_CIR;
    default:
      return "UNKNOWN";
    }
  }
 
  public static byte getMappingStructure(String strval) {
    if (MAPPING_STRUCTURE_DN.equals(strval)) {
      return JormFactoryAttributes.DO_NOTHING;
    } else if (MAPPING_STRUCTURE_DD.equals(strval)) {
      return JormFactoryAttributes.DELETE_DATA;
    } else if (MAPPING_STRUCTURE_CIR.equals(strval)) {
      return JormFactoryAttributes.CREATE_IF_REQUIRED;
    } else if (MAPPING_STRUCTURE_FC.equals(strval)) {
      return JormFactoryAttributes.FORCE_CREATE;
    } else {
        return -1;
    }
     
  }
}
TOP

Related Classes of org.objectweb.speedo.AbstractSpeedo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.