Package org.objectweb.speedo.pm.lib

Source Code of org.objectweb.speedo.pm.lib.AbstractPOManager

/**
* Copyright (C) 2001-2005 France Telecom R&D
*/
package org.objectweb.speedo.pm.lib;

import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.Interface;
import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.util.Fractal;
import org.objectweb.jorm.api.PClassMapping;
import org.objectweb.jorm.api.PException;
import org.objectweb.jorm.naming.api.PBinder;
import org.objectweb.jorm.naming.api.PName;
import org.objectweb.jorm.naming.api.PNameCoder;
import org.objectweb.jorm.util.api.Loggable;
import org.objectweb.perseus.cache.api.CacheEntry;
import org.objectweb.perseus.concurrency.lib.Semaphore;
import org.objectweb.perseus.persistence.api.PersistenceException;
import org.objectweb.perseus.persistence.api.RolledBackPersistenceException;
import org.objectweb.perseus.persistence.api.State;
import org.objectweb.perseus.persistence.api.StateFilter;
import org.objectweb.perseus.persistence.api.TransactionalPersistenceManager;
import org.objectweb.perseus.persistence.api.TransactionalWorkingSet;
import org.objectweb.perseus.persistence.api.VirtualState;
import org.objectweb.speedo.api.ExceptionHelper;
import org.objectweb.speedo.api.SpeedoRuntimeException;
import org.objectweb.speedo.genclass.api.SpeedoGenClassPO;
import org.objectweb.speedo.mapper.api.JormFactory;
import org.objectweb.speedo.mim.api.FetchPlanItf;
import org.objectweb.speedo.mim.api.HomeItf;
import org.objectweb.speedo.mim.api.PersistentObjectItf;
import org.objectweb.speedo.mim.api.StateItf;
import org.objectweb.speedo.pm.api.POManagerFactoryItf;
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.workingset.api.TransactionItf;
import org.objectweb.speedo.workingset.jdo.api.JDOTransactionItf;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;
import org.objectweb.util.monolog.api.LoggerFactory;

import java.util.Collection;
import java.util.Map;

import javax.jdo.listener.InstanceLifecycleEvent;
import javax.transaction.Status;

public abstract class AbstractPOManager implements POManagerItf {
    public final static String PO_MANAGER_FACTORY_BINDING = "po-manager-factory";
    public final static String TRANSACTIONAL_PERSISTENCE_MANAGER_BINDING = "transactional-persistence-manager";
    public final static String QUERY_MANAGER_BINDING = "query-manager";
    public final static String TRANSACTION_BINDING = "transaction";
    public final static String JORM_FACTORY_BINDING = "jorm-factory";
    public final static String PNAME_CODER_BINDING = "pname-coder";
    public final static String COMPONENT_BINDING = "component";

  protected Logger logger;
  protected LoggerFactory loggerFactory;

    /**
   * The POManagedFactory managing this POManagerItf
   */
  protected POManagerFactoryItf pmf = null;

    /**
     * The transaction associated to this po manager.
     */
  protected TransactionItf tx;

    /**
     * The manager of Query. It contains the optimized queries already
     * used.
     */
  protected QueryManager queryManager = null;

  /**
   * The TransactionalPersistenceManager (Perseus)
   */
  protected TransactionalPersistenceManager tpm = null;

  /**
   * The JormFactory able to initialize the Persistent of classes
   */
  protected JormFactory jf = null;

  /**
   * The PNameCoder able to encode/decode all PName
   */
  protected PNameCoder pnc = null;

  /**
   * is the information permiting the access to the data store
   */
  protected Object connectionSpec = null;

    /**
     * Indicates if number of po manager user. O means the POManagerItf
   * is closed.
     */
  protected short nbUse = 0;

    /**
   * The fractal reference to this
   */
  protected POManagerItf thisPM = null;

    /**
   * The lastest thread associated to the current POManagerItf
   */
  protected Thread currentThread = null;

    /**
   * A semaphore object used to support the multithread mode
   */
  protected Semaphore semaphore;

  protected boolean prefetchOnExtent = true;
  protected boolean prefetchOnQuery = true;
 
  protected FetchPlanItf fetchPlan;
 

  /**
   *
   */
  public AbstractPOManager() {
        semaphore = new Semaphore(false);
  }

    // IMPLEMENTATION OF THE UserBindingController INTERFACE //
    //-------------------------------------------------------//

    public String[] listFc() {
        return new String[] {
            PO_MANAGER_FACTORY_BINDING,
            QUERY_MANAGER_BINDING,
            TRANSACTIONAL_PERSISTENCE_MANAGER_BINDING,
            TRANSACTION_BINDING,
            JORM_FACTORY_BINDING,
            PNAME_CODER_BINDING
        };
    }

    public Object lookupFc(String s) {
    if (PO_MANAGER_FACTORY_BINDING.equals(s)) {
            return pmf;
        } else if (QUERY_MANAGER_BINDING.equals(s)) {
            return queryManager;
        } else if (TRANSACTIONAL_PERSISTENCE_MANAGER_BINDING.equals(s)) {
            return tpm;
        } else if (TRANSACTION_BINDING.equals(s)) {
            return tx;
        } else if (PNAME_CODER_BINDING.equals(s)) {
            return pnc;
        } else if (JORM_FACTORY_BINDING.equals(s)) {
            return jf;
        } else {
            return null;
        }
    }

    public void bindFc(String s, Object o) {
        if ("monolog-factory".equals(s)) {
      loggerFactory = (LoggerFactory) o;
    } else if ("logger".equals(s)) {
      logger = (Logger) o;
        } else if (PO_MANAGER_FACTORY_BINDING.equals(s)) {
            pmf = (POManagerFactoryItf) o;
        } else if (QUERY_MANAGER_BINDING.equals(s)) {
            queryManager = (QueryManager) o;
      if (queryManager != null) {
        try {
          QueryManagerAttribute qma = (QueryManagerAttribute)
          Fractal.getAttributeController(
              ((Interface) queryManager).getFcItfOwner()) ;
          prefetchOnExtent = qma.getPrefetchActivatedOnExtent();
          prefetchOnQuery = qma.getPrefetchActivatedOnQuery();
        } catch (Exception e) {
          logger.log(BasicLevel.WARN,
            "impossible to fetch the attribute prefetchActivatedOnExtent: ", e);
        }
      }
        } else if (TRANSACTIONAL_PERSISTENCE_MANAGER_BINDING.equals(s)) {
            tpm = (TransactionalPersistenceManager) o;
        } else if (TRANSACTION_BINDING.equals(s)) {
            tx = (TransactionItf) o;
        } else if (PNAME_CODER_BINDING.equals(s)) {
            pnc = (PNameCoder) o;
        } else if (JORM_FACTORY_BINDING.equals(s)) {
            jf = (JormFactory) o;
        } else if (COMPONENT_BINDING.equals(s)) {
      try {
        thisPM = (POManagerItf) ((Component) o).getFcInterface("po-manager");
      } catch (NoSuchInterfaceException e) {
       
      }
    }
    }

    public void unbindFc(String s) {
        if (PO_MANAGER_FACTORY_BINDING.equals(s))
            pmf = null;
        else if (TRANSACTIONAL_PERSISTENCE_MANAGER_BINDING.equals(s))
            tpm = null;
        else if (TRANSACTION_BINDING.equals(s))
            tx = null;
        else if (QUERY_MANAGER_BINDING.equals(s))
            queryManager = null;
        else if (PNAME_CODER_BINDING.equals(s))
            pnc = null;
        else if (JORM_FACTORY_BINDING.equals(s))
            jf = null;
    }

    // IMPLEMENTATION OF THE POManagerItf INTERFACE //
    //----------------------------------------------//

    public abstract FetchPlanItf speedoGetFetchPlan();
   
    public TransactionalPersistenceManager getTransactionalPersistenceManager() {
        return tpm;
    }

    public void open(Object connectionspec) {
      resetPMOnOpen(connectionspec);
        try {
            tx.activate();
        } catch (PersistenceException e) {
            throw new SpeedoRuntimeException(
                    "Impossible to open this persistence manager", e);
        }
    }

    public Object getConnectionSpec() {
        return connectionSpec;
    }

    public void addUse() {
        nbUse++;
        logger.log(BasicLevel.DEBUG, "POManagerItf used: " + nbUse);
    }

    /**
     * A POManager instance can be used until it is closed.
     * @return true if this POManager has been closed
     * @see #closePOManager()
     */
    public boolean isPOMClosed() {
        bindPMThread();
        return nbUse == 0;
    }

    public void closePOManager() {
        if (semaphore.on) {
            semaphore.P();
        }
    if (nbUse == 0) {
      return;
    } else if (nbUse > 1) {
      nbUse--;
            logger.log(BasicLevel.DEBUG, "Imbricated POManager closed ("
                    + nbUse + ")");
            return;
        }
        bindPMThread();
        try {
            tpm.close(tx);
        } catch (PersistenceException e) {
            throw new SpeedoRuntimeException(
                    "Impossible to close the persistence manager",
                    ExceptionHelper.getNested(e));
        } finally {
      nbUse--;
            //Forget the information to access to the data store.
            connectionSpec = null;
      currentThread = null;
            try {
        pmf.poManagerClosed(thisPM);
            } finally {
                if (semaphore.on) {
                    semaphore.V();
                }
        if (logger.isLoggable(BasicLevel.INFO))
          logger.log(BasicLevel.INFO, "Persistence Manager closed");
            }
        }
    }

    public TransactionItf getSpeedoTransaction() {
        return tx;
    }

    public POManagerFactoryItf getPOManagerFactory() {
        return pmf;
    }
   
    public Object getEncodedPName(PersistentObjectItf o) {
        try {
            assertIsPO(o, "");
        } catch (Exception e) {
            return null;
        }
        PersistentObjectItf po = (PersistentObjectItf) o;
        assertPOManager(po);
        if (!po.speedoIsActive()) {
            throw new SpeedoRuntimeException("Non persistent object does not have identifier: " + o);
        }
        try {
            return pnc.encodeAbstract(po.getPName());
        } catch (PException e) {
            throw new SpeedoRuntimeException(
                    "Problem while encoding persistent name.",
                    new Exception[]{ExceptionHelper.getNested(e)});
        }
    }
    public PName decodeIdentifier(Class aClass, Object s) {
        assertIsOpen();
        bindPMThread();
        try {
            return pnc.decodeAbstract(s, aClass);
        } catch (PException e) {
            throw new SpeedoRuntimeException("Invalid persistent object identifier "
                    + s + " for the class " + aClass, new Exception[]{e});
        }
    }

    public void speedoDeletePersistentAll(Object[] o) {
      if (o == null || o.length == 0) {
        return;
      }
      for (int i = 0; i < o.length; i++) {
      speedoDeletePersistent(o[i]);
    }
    }

  // IMPLEMENTATION OF THE Synchronization INTERFACE //
  //-------------------------------------------------//

    public void beforeCompletion() {
    byte stat = tx.getStatus();
    if (stat == TransactionalWorkingSet.CTX_PREPARED_FAIL
      || stat == TransactionalWorkingSet.CTX_PREPARED_OK) {
      /**
       * The PersistenceManager has been registered several times as a
       * Synchronization and the beforeCompletion method is call several
       * times.
       */
      return;
    }
    bindPMThread();
    logger.log(BasicLevel.INFO, "beforeCompletion of the transaction: ");
    try {
      tpm.prepare(tx);
    } catch (PersistenceException e) {
      Exception ie = ExceptionHelper.getNested(e);
      logger.log(BasicLevel.ERROR,
          "Error during the preparation of the transaction:", ie);
      throw new SpeedoRuntimeException("", ie);
    }
  }

  public void afterCompletion(int i) {
    if (nbUse == 0) {
      /**
       * The PersistenceManager has been registered several times as a
       * Synchronization and the afterCompletion method is call several
       * times.
       */
      return;
    }
    bindPMThread();
    boolean commit = (i == Status.STATUS_COMMITTED);
    try {
      if (commit) {
        logger.log(BasicLevel.DEBUG, "afterCompletion(STATUS_COMMITTED) of the transaction: ");
        tpm.commit(tx);
      } else {
        logger.log(BasicLevel.DEBUG, "afterCompletion(STATUS_ROLLEDBACK) of the transaction: ");
        tpm.rollback(tx);
      }
    } catch (PersistenceException e) {
      Exception ie = ExceptionHelper.getNested(e);
      logger.log(BasicLevel.ERROR, "Error during the "
          + (commit ? "commit" : "rollback")
          + " of the transaction:", ie);
      throw new SpeedoRuntimeException("", ie);
    } finally {
      closePOManager();
    }
  }
 
 
    // OTHER METHODS //
    //---------------//
    public Object speedoGetObject(PName pn, boolean validate)  {
        if (pn.isNull()) {
            return null;
        }
        try {
            if (!(pn.getPNameManager() instanceof PBinder)) {
                pn = pnc.decodeAbstract(pn, tx.getConnectionHolder());               
            }
            if (validate) {
                State s = tx.lookup(pn);
                if (s != null && s != VirtualState.instance) {
                    return s.getCacheEntry();
                } else {
                    //Fetch an instance (new or from the cache)
                    CacheEntry ce = tpm.getObjectById(tx, pn);
                    //clear the state
                    tpm.refresh(tx, ce);
                    //if it exists then object loading else exception
                    tpm.readIntention(tx, ce, null);
                    return ce;
                }
            } else {
                //do not reload if present in the cache
                return tpm.readIntention(tx, pn, null).getCacheEntry();
            }
        } catch (PersistenceException e) {
            throw new SpeedoRuntimeException(e);
        } catch (PException e) {
            throw new SpeedoRuntimeException(e);
        }
    }
 
  public Object speedoGetObject(Object id, Class poc, boolean validate)
    throws PException, PersistenceException {
    Object oid = id;
    if (poc != null) {
      oid = pnc.decodeAbstract(oid, poc);
    }
    PName pn = pnc.decodeAbstract(oid, tx.getConnectionHolder());
        return speedoGetObject(pn, validate);
  }
 
  protected Object speedoPersist(PersistentObjectItf po, Map map)
    throws PException, PersistenceException {
    //initialize the PBinding of the persistent object
    PClassMapping pcm;
    if (po instanceof SpeedoGenClassPO) {
      pcm = jf.getGenClassMapping(
        ((SpeedoGenClassPO) po).speedoGetGenClassId());
      //Assign the PBinding
      ((SpeedoGenClassPO) po).speedoSetPBinding(pcm.createPBinding());
      if (po instanceof Loggable) {
        ((Loggable) po).setLogger(logger);
      }
    } else {
      pcm = jf.getPClassMapping(po.getClass());
    }
    po.init(pcm);
        po.speedoGetHome().sendEvent(HomeItf.PRE_NEW, po, null);
    Object hints = po.speedoGetPNameHints();
    final StateItf state;
        if (hints == null) {
            state = (StateItf) tpm.export(tx, po);
        } else {
          state = (StateItf) tpm.export(tx, po, hints);
        }
        if (logger.isLoggable(BasicLevel.DEBUG)) {
            logger.log(BasicLevel.DEBUG,
                    "New persistent instance, identifier=" + po.getPName());
        }
        if (map == null) {
          //call the po to make persistent the reference field
          state.makePersistent(this);
        } else {
          //call the po to make persistent the reference field, with the map context
          state.makePersistentOnAttach(this, map);
        }
        po.speedoGetHome().sendEvent(HomeItf.POST_NEW, po, null);
        return po;
  }
 
    public void speedoFlush() throws PersistenceException {
        tpm.flush(tx, (StateFilter) null);
    }

  protected void resetPMOnOpen(Object connectionspec) {
        connectionSpec = connectionspec;
        nbUse = 0;
        //??? init the transaction mode Optimistic or not ?
        //??? init the ignoreCache property or not ?
        //??? init the multithread property or not ?
  }
 
    public Semaphore getSemaphore() {
        return semaphore;
    }

    protected void bindPMThread() {
        if (currentThread != Thread.currentThread()) {
            currentThread = Thread.currentThread();
            pmf.bindPM2Thread(thisPM);
            currentThread = null;
        }
    }

    /**
     * Verify the persistence manager is open.
     * @exception SpeedoRuntimeException if the pomanager is closed.
     */
    protected void assertIsOpen() {
        if (nbUse == 0)
            throw new SpeedoRuntimeException("The persistent manager is closed.");
    }

    /**
     * Verify that an instance is persistence object.
     * @param pc the object to test.
     * @exception SpeedoRuntimeException if the object is not persistence capable.
     */
    protected void assertIsPO(Object pc, String cmd) {
        if (!(pc instanceof PersistentObjectItf)) {
      if (pc == null) {
        throw new SpeedoRuntimeException("Null persistent object instance specified");
      } else if (pc.getClass().isArray()
        || pc instanceof Collection) {
        throw new SpeedoRuntimeException("You must use the " + cmd
          + "All method with a multivalued parameter: " + pc);
      } else {
              throw new SpeedoRuntimeException("The object is not a PersistentObjectItf, beware to : " + pc);
      }
    }
    }
    /**
     * Verify the instance is managed by this persistence manager.
     * @param sp a speedo po instance.
     * @exception SpeedoRuntimeException if the instance is managed by
     * another persistence manager.
     */
    protected void assertPOManager(PersistentObjectItf sp) {
        POManagerItf pm = (POManagerItf) sp.speedoGetPOManager();
        if (!thisPM.equals(pm)) {           
            if (pm == null) {
                try {
                    tpm.readIntention(tx, sp, null);
                } catch (RolledBackPersistenceException e) {
                    throw ((JDOTransactionItf) tx).rollBackOnInternalError(e);
                } catch (PersistenceException e) {
                    throw new SpeedoRuntimeException("Impossible to add the " +
                            "persistent object into the working set", e);
                }
            } else {
                throw new SpeedoRuntimeException(
                    "Object not managed by this persistence manager, object: "
                    + sp);
            }
        }
    }
   
}
TOP

Related Classes of org.objectweb.speedo.pm.lib.AbstractPOManager

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.