Save This Page
Home » openejb-3.1.2-src » org.apache » openejb » core » stateful » [javadoc | source]
    1   /**
    2    *
    3    * Licensed to the Apache Software Foundation (ASF) under one or more
    4    * contributor license agreements.  See the NOTICE file distributed with
    5    * this work for additional information regarding copyright ownership.
    6    * The ASF licenses this file to You under the Apache License, Version 2.0
    7    * (the "License"); you may not use this file except in compliance with
    8    * the License.  You may obtain a copy of the License at
    9    *
   10    *     http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    *  Unless required by applicable law or agreed to in writing, software
   13    *  distributed under the License is distributed on an "AS IS" BASIS,
   14    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15    *  See the License for the specific language governing permissions and
   16    *  limitations under the License.
   17    */
   18   package org.apache.openejb.core.stateful;
   19   
   20   import java.io.Serializable;
   21   import java.io.ObjectStreamException;
   22   import java.util.Map;
   23   import java.util.HashMap;
   24   import java.util.Stack;
   25   import java.util.concurrent.locks.Lock;
   26   import java.util.concurrent.locks.ReentrantLock;
   27   import javax.persistence.EntityManagerFactory;
   28   import javax.persistence.EntityManager;
   29   import javax.transaction.Transaction;
   30   
   31   import org.apache.openejb.core.CoreDeploymentInfo;
   32   import org.apache.openejb.core.transaction.BeanTransactionPolicy.SuspendedTransaction;
   33   import org.apache.openejb.loader.SystemInstance;
   34   import org.apache.openejb.spi.ContainerSystem;
   35   import org.apache.openejb.util.Index;
   36   import org.apache.openejb.util.PojoSerialization;
   37   
   38   public class Instance implements Serializable {
   39       private static final long serialVersionUID = 2862563626506556542L;
   40       public final CoreDeploymentInfo deploymentInfo;
   41       public final Object primaryKey;
   42       public final Object bean;
   43       public final Map<String, Object> interceptors;
   44   
   45       private boolean inUse;
   46       private SuspendedTransaction beanTransaction;
   47       private Stack<Transaction> transaction = new Stack<Transaction>();
   48       private final Lock lock = new ReentrantLock();
   49   
   50       // todo if we keyed by an entity manager factory id we would not have to make this transient and rebuild the index below
   51       // This would require that we crete an id and that we track it
   52       // alternatively, we could use ImmutableArtifact with some read/write replace magic
   53       private Map<EntityManagerFactory, EntityManager> entityManagers;
   54       private final EntityManager[] entityManagerArray;
   55   
   56       public Instance(CoreDeploymentInfo deploymentInfo, Object primaryKey, Object bean, Map<String, Object> interceptors, Map<EntityManagerFactory, EntityManager> entityManagers) {
   57           this.deploymentInfo = deploymentInfo;
   58           this.primaryKey = primaryKey;
   59           this.bean = bean;
   60           this.interceptors = interceptors;
   61           this.entityManagers = entityManagers;
   62           this.entityManagerArray = null;
   63       }
   64   
   65       public Instance(Object deploymentId, Object primaryKey, Object bean, Map<String, Object> interceptors, EntityManager[] entityManagerArray) {
   66           this.deploymentInfo = (CoreDeploymentInfo) SystemInstance.get().getComponent(ContainerSystem.class).getDeploymentInfo(deploymentId);
   67           if (deploymentInfo == null) {
   68               throw new IllegalArgumentException("Unknown deployment " + deploymentId);
   69           }
   70           this.primaryKey = primaryKey;
   71           this.bean = bean;
   72           this.interceptors = interceptors;
   73           this.entityManagerArray = entityManagerArray;
   74       }
   75   
   76       public synchronized boolean isInUse() {
   77           return inUse;
   78       }
   79   
   80       public synchronized void setInUse(boolean inUse) {
   81           this.inUse = inUse;
   82       }
   83   
   84       public synchronized SuspendedTransaction getBeanTransaction() {
   85           return beanTransaction;
   86       }
   87   
   88       public synchronized void setBeanTransaction(SuspendedTransaction beanTransaction) {
   89           this.beanTransaction = beanTransaction;
   90       }
   91   
   92       public synchronized Transaction getTransaction() {
   93           return (transaction.size() > 0)? transaction.peek(): null;
   94       }
   95   
   96       public Lock getLock() {
   97           return lock;
   98       }
   99   
  100       public synchronized void setTransaction(Transaction transaction) {
  101           if (this.transaction.size() == 0 && transaction != null) {
  102               lock.lock();
  103               this.transaction.push(transaction);
  104           } else if (this.transaction.size() != 0 && transaction == null) {
  105               this.transaction.pop();
  106               lock.unlock();
  107           } else if (transaction != null){
  108               this.transaction.push(transaction);
  109           }
  110   
  111       }
  112   
  113       public synchronized Map<EntityManagerFactory, EntityManager> getEntityManagers(Index<EntityManagerFactory, Map> factories) {
  114           if (entityManagers == null && entityManagerArray != null) {
  115               entityManagers = new HashMap<EntityManagerFactory, EntityManager>();
  116               for (int i = 0; i < entityManagerArray.length; i++) {
  117                   EntityManagerFactory entityManagerFactory = factories.getKey(i);
  118                   EntityManager entityManager = entityManagerArray[i];
  119                   entityManagers.put(entityManagerFactory, entityManager);
  120               }
  121           }
  122           return entityManagers;
  123       }
  124   
  125       protected Object writeReplace() throws ObjectStreamException {
  126           if (inUse) {
  127               throw new IllegalStateException("Bean is still in use");
  128           }
  129           if (beanTransaction != null) {
  130               throw new IllegalStateException("Bean is associated with a bean-managed transaction");
  131           }
  132           return new Serialization(this);
  133       }
  134   
  135       private static class Serialization implements Serializable {
  136           private static final long serialVersionUID = 6002078080752564395L;
  137           public final Object deploymentId;
  138           public final Object primaryKey;
  139           public final Object bean;
  140           public final Map<String, Object> interceptors;
  141           public final EntityManager[] entityManagerArray;
  142   
  143           public Serialization(Instance i) {
  144               deploymentId = i.deploymentInfo.getDeploymentID();
  145               primaryKey = i.primaryKey;
  146               if (i.bean instanceof Serializable) {
  147                   bean = i.bean;
  148               } else {
  149                   bean = new PojoSerialization(i.bean);
  150               }
  151   
  152               interceptors = new HashMap(i.interceptors.size());
  153               for (Map.Entry<String, Object> e : i.interceptors.entrySet()) {
  154                   if (e.getValue() == i.bean) {
  155                       // need to use the same wrapped reference or well get two copies.
  156                       interceptors.put(e.getKey(), bean);
  157                   } else if (!(e.getValue() instanceof Serializable)) {
  158                       interceptors.put(e.getKey(), new PojoSerialization(e.getValue()));
  159                   }
  160               }
  161   
  162               if (i.entityManagerArray != null) {
  163                   entityManagerArray = i.entityManagerArray;
  164               } else if (i.entityManagers != null) {
  165                   entityManagerArray = i.entityManagers.values().toArray(new EntityManager[i.entityManagers.values().size()]);
  166               } else {
  167                   entityManagerArray = null;
  168               }
  169           }
  170   
  171           protected Object readResolve() throws ObjectStreamException {
  172               // Anything wrapped with PojoSerialization will have been automatically
  173               // unwrapped via it's own readResolve so passing in the raw bean
  174               // and interceptors variables is totally fine.
  175               return new Instance(deploymentId, primaryKey, bean, interceptors, entityManagerArray);
  176           }
  177       }
  178   }

Save This Page
Home » openejb-3.1.2-src » org.apache » openejb » core » stateful » [javadoc | source]