Package org.jboss.ejb.plugins.cmp.jdbc2.schema

Source Code of org.jboss.ejb.plugins.cmp.jdbc2.schema.Schema$SchemaSynchronization

/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This 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.1 of
* the License, or (at your option) any later version.
*
* This software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.ejb.plugins.cmp.jdbc2.schema;

import org.jboss.ejb.EntityContainer;
import org.jboss.ejb.GlobalTxEntityMap;
import org.jboss.ejb.GlobalTxEntityMap.GlobalTxSynchronization;
import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCEntityMetaData;
import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCEntityBridge2;
import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCCMRFieldBridge2;
import org.jboss.deployment.DeploymentException;

import javax.ejb.EJBException;
import javax.transaction.RollbackException;
import javax.transaction.Synchronization;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import java.sql.SQLException;

/**
* @author <a href="mailto:alex@jboss.org">Alexey Loubyansky</a>
* @version <tt>$Revision: 94413 $</tt>
*/
public class Schema
{
   private final String viewsTxLocalKey;

   private EntityTable[] entityTables;
   private RelationTable[] relationTables;

   private GlobalTxEntityMap txLocal = EntityContainer.getGlobalTxEntityMap();

   public Schema(String ejbModuleName)
   {
    this.viewsTxLocalKey = ejbModuleName + ".schema.views";
   }

   public EntityTable createEntityTable(JDBCEntityMetaData metadata, JDBCEntityBridge2 entity)
      throws DeploymentException
   {
      if(entityTables == null)
      {
         entityTables = new EntityTable[1];
      }
      else
      {
         EntityTable[] tmp = entityTables;
         entityTables = new EntityTable[tmp.length + 1];
         System.arraycopy(tmp, 0, entityTables, 0, tmp.length);
      }

      EntityTable table = new EntityTable(metadata, entity, this, entityTables.length - 1);
      entityTables[entityTables.length - 1] = table;
      return table;
   }

   public RelationTable createRelationTable(JDBCCMRFieldBridge2 leftField, JDBCCMRFieldBridge2 rightField)
      throws DeploymentException
   {
      if(relationTables == null)
      {
         relationTables = new RelationTable[1];
      }
      else
      {
         RelationTable[] tmp = relationTables;
         relationTables = new RelationTable[tmp.length + 1];
         System.arraycopy(tmp, 0, relationTables, 0, tmp.length);
      }

      RelationTable table = new RelationTable(leftField, rightField, this, relationTables.length - 1);
      relationTables[relationTables.length - 1] = table;
      return table;
   }

   public Table.View getView(EntityTable table)
   {
      Views views = getViews();
      Table.View view = views.entityViews[table.getTableId()];
      if(view == null)
      {
         view = table.createView(views.tx);
         views.entityViews[table.getTableId()] = view;
      }
      return view;
   }

   public Table.View getView(RelationTable table)
   {
      Views views = getViews();
      Table.View view = views.relationViews[table.getTableId()];
      if(view == null)
      {
         view = table.createView(views.tx);
         views.relationViews[table.getTableId()] = view;
      }
      return view;
   }

   public void flush()
   {
      Views views = getViews();

      Table.View[] relationViews = views.relationViews;
      if(relationViews != null)
      {
         for(int i = 0; i < relationViews.length; ++i)
         {
            final Table.View view = relationViews[i];
            if(view != null)
            {
               try
               {
                  view.flushDeleted(views);
               }
               catch(SQLException e)
               {
                  throw new EJBException("Failed to delete many-to-many relationships: " + e.getMessage(), e);
               }
            }
         }
      }

      final Table.View[] entityViews = views.entityViews;
      for(int i = 0; i < entityViews.length; ++i)
      {
         Table.View view = entityViews[i];
         if(view != null)
         {
            try
            {
               view.flushDeleted(views);
            }
            catch(SQLException e)
            {
               throw new EJBException("Failed to delete instances: " + e.getMessage(), e);
            }
         }
      }

      for(int i = 0; i < entityViews.length; ++i)
      {
         Table.View view = entityViews[i];
         if(view != null)
         {
            try
            {
               view.flushCreated(views);
            }
            catch(SQLException e)
            {
               throw new EJBException("Failed to create instances: " + e.getMessage(), e);
            }
         }
      }

      for(int i = 0; i < entityViews.length; ++i)
      {
         Table.View view = entityViews[i];
         if(view != null)
         {
            try
            {
               view.flushUpdated();
            }
            catch(SQLException e)
            {
               throw new EJBException("Failed to update instances: " + e.getMessage(), e);
            }
         }
      }

      if(relationViews != null)
      {
         for(int i = 0; i < relationViews.length; ++i)
         {
            final Table.View view = relationViews[i];
            if(view != null)
            {
               try
               {
                  view.flushCreated(views);
               }
               catch(SQLException e)
               {
                  throw new EJBException("Failed to create many-to-many relationships: " + e.getMessage(), e);
               }
            }
         }
      }
   }

   private Views getViews()
   {
      Transaction tx = txLocal.getTransaction();
      GlobalTxSynchronization globalSync;
      try
      {
         globalSync = txLocal.getGlobalSynchronization(tx);
      }
      catch(RollbackException e)
      {
         throw new EJBException("Transaction already marked to roll back: " + e.getMessage(), e);
      }
      catch(SystemException e)
      {
         throw new IllegalStateException("Failed to register transaction synchronization: " + e.getMessage());
      }

      if(globalSync == null)
         throw new IllegalStateException("Global transaction synchronization is not available for transaction " + tx);
     
      Views views = (Views) globalSync.getTxLocal(viewsTxLocalKey);
      if(views == null)
      {
         views = new Views(tx);
         globalSync.putTxLocal(viewsTxLocalKey, views);
         globalSync.addSynchronization(new SchemaSynchronization(views));
      }
      return views;
   }

   // Inner

   public class Views
   {
      public final Transaction tx;
      public final Table.View[] entityViews;
      public final Table.View[] relationViews;

      public Views(Transaction tx)
      {
         this.tx = tx;
         this.entityViews = new Table.View[entityTables.length];
         this.relationViews = relationTables == null ? null : new Table.View[relationTables.length];
      }
   }

   private class SchemaSynchronization implements Synchronization
   {
      private final Views views;

      public SchemaSynchronization(Views views)
      {
         this.views = views;
      }

      public void beforeCompletion()
      {
         flush();

         for(int i = 0; i < views.entityViews.length; ++i)
         {
            Table.View view = views.entityViews[i];
            if(view != null)
            {
               view.beforeCompletion();
            }
         }
      }

      public void afterCompletion(int status)
      {
         if(status == Status.STATUS_MARKED_ROLLBACK ||
            status == Status.STATUS_ROLLEDBACK ||
            status == Status.STATUS_ROLLING_BACK)
         {
            for(int i = 0; i < views.entityViews.length; ++i)
            {
               Table.View view = views.entityViews[i];
               if(view != null)
               {
                  view.rolledback();
               }
            }
         }
         else
         {
            for(int i = 0; i < views.entityViews.length; ++i)
            {
               Table.View view = views.entityViews[i];
               if(view != null)
               {
                  view.committed();
               }
            }
         }
      }
   }
}
TOP

Related Classes of org.jboss.ejb.plugins.cmp.jdbc2.schema.Schema$SchemaSynchronization

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.