Package nexj.core.persistence.virtual

Source Code of nexj.core.persistence.virtual.VirtualUpdate

// Copyright 2010 NexJ Systems Inc. This software is licensed under the terms of the Eclipse Public License 1.0
package nexj.core.persistence.virtual;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;

import nexj.core.meta.Attribute;
import nexj.core.meta.Metaclass;
import nexj.core.meta.persistence.AttributeMapping;
import nexj.core.meta.persistence.virtual.UpdateMapping;
import nexj.core.meta.persistence.virtual.UpdateMappingCase;
import nexj.core.meta.persistence.virtual.VirtualClassMapping;
import nexj.core.meta.persistence.virtual.VirtualDataSourceFragment;
import nexj.core.meta.persistence.virtual.VirtualMapping;
import nexj.core.persistence.PersistenceException;
import nexj.core.persistence.Work;
import nexj.core.rpc.TransferObject;
import nexj.core.runtime.Instance;
import nexj.core.util.Logger;
import nexj.core.util.ObjUtil;

/**
* Work item that executes virtual persistence adapter update mappings.
*/
public class VirtualUpdate extends VirtualWork
{
   // constants

   /**
    * The name for the transfer object event.
    */
   public final static String EVENT = "update";

   // associations

   /**
    * The bitmap of attributes being updated.
    */
   protected BitSet m_attributeSet;

   /**
    * The class logger.
    */
   protected final static Logger s_logger = Logger.getLogger(VirtualUpdate.class);

   // constructors

   /**
    * Constructs a new update work item.
    * @param instance The instance to update.
    * @param adapter The adapter.
    */
   public VirtualUpdate(Instance instance, VirtualAdapter adapter)
   {
      super(instance, adapter);

      Metaclass metaclass = instance.getMetaclass();
      int nCount = metaclass.getInstanceAttributeCount();

      m_attributeSet = new BitSet(nCount);

      for (int i = 0; i < nCount; i++)
      {
         if (instance.isDirty(i))
         {
            Attribute attribute = metaclass.getInstanceAttribute(i);
            AttributeMapping attributeMapping = m_mapping.getAttributeMapping(attribute);

            if (attributeMapping != null && (attribute.getType().isPrimitive() ||
               !((VirtualClassMapping)attributeMapping).getKey(false).isObjectKey()))
            {
               m_attributeSet.set(i);
            }
         }
      }
   }

   // operations

   /**
    * @see nexj.core.persistence.Work#getType()
    */
   public int getType()
   {
      return UPDATE;
   }

   /**
    * Orders the updates so that work units that update the same attributes are
    * grouped together.
    * @see nexj.core.persistence.virtual.VirtualWork#compareTo(nexj.core.persistence.Work)
    */
   protected int compareTo(Work work)
   {
      VirtualUpdate other = (VirtualUpdate)work;
      int nDifference;

      nDifference = other.getInstance().getMetaclass().getName().compareTo(getInstance().getMetaclass().getName());

      if (nDifference != 0)
      {
         return nDifference;
      }

      BitSet attrSet = m_attributeSet;
      BitSet otherAttrSet = other.m_attributeSet;

      nDifference = attrSet.cardinality() - otherAttrSet.cardinality();

      if (nDifference != 0)
      {
         return nDifference;
      }

      BitSet diffSet = (BitSet)attrSet.clone();

      diffSet.xor(otherAttrSet);

      int i = diffSet.nextSetBit(0);

      if (i < 0)
      {
         return 0;
      }

      return otherAttrSet.get(i) ? -1 : 1;
   }

   /**
    * @see nexj.core.persistence.virtual.VirtualWork#execute(nexj.core.persistence.Work[], int, int)
    */
   public void execute(Work[] workArray, int nStart, int nEnd)
   {
      // All items have the same attributes to update
      VirtualMapping mapping = (VirtualMapping)m_mapping;
      UpdateMapping updateMapping = mapping.getUpdateMapping();
      Metaclass metaclass = mapping.getMetaclass();
      List updateList = updateMapping.getUpdateCases(m_attributeSet);

      // Execute updates
      Attribute lockingAttribute = mapping.getLockingAttribute();
      int nLockingOrdinal = (lockingAttribute == null) ? -1 : lockingAttribute.getOrdinal();
      String sLockingAttributeName = (lockingAttribute == null) ? null : lockingAttribute.getName();
      VirtualDataSourceFragment fragment = (VirtualDataSourceFragment)getFragment();

      for (int i = 0, nSize = updateList.size(); i < nSize; i++)
      {
         UpdateMappingCase update = (UpdateMappingCase)updateList.get(i);
         BitSet updateAttrSet = update.getAttributeSet();
         ArrayList tobjList =  new ArrayList(nEnd - nStart);
         int nUpdateAttrCount = updateAttrSet.cardinality() + ((nLockingOrdinal >= 0) ? 1 : 0);
         boolean bIgnoreDirty = !update.isDirty();
         boolean bFull = update.isFull();

         for (int k = nStart; k < nEnd; k++)
         {
            VirtualUpdate work = (VirtualUpdate)workArray[k];
            Instance instance = work.getInstance();
            TransferObject tobj = new TransferObject(instance.getOID(), metaclass.getName(), EVENT, nUpdateAttrCount);

            if (bFull)
            {
               for (int m = 0, nCount = metaclass.getInstanceAttributeCount(); m < nCount; m++)
               {
                  Attribute attribute = metaclass.getInstanceAttribute(m);

                  if (bIgnoreDirty || instance.isDirty(m))
                  {
                     setValue(tobj, attribute, instance.getValue(m));
                  }
               }
            }
            else
            {
               for (int m = updateAttrSet.nextSetBit(0); m >= 0; m = updateAttrSet.nextSetBit(m + 1))
               {
                  Attribute attribute = metaclass.getInstanceAttribute(m);

                  if (bIgnoreDirty || instance.isDirty(m))
                  {
                     setValue(tobj, attribute, instance.getValue(m));
                  }
               }
            }

            if (nLockingOrdinal >= 0)
            {
               tobj.setValue(sLockingAttributeName, instance.getValue(nLockingOrdinal));
            }

            tobjList.add(tobj);
         }

         boolean bError = true;

         try
         {
            update.invoke(tobjList, m_adapter.getInvocationContext().getMachine(), fragment);
            bError = false;
         }
         finally
         {
            // Set new locking values
            if (nLockingOrdinal >= 0)
            {
               for (int k = nStart; k < nEnd; k++)
               {
                  Instance instance = ((VirtualUpdate)workArray[k]).getInstance();
                  TransferObject tobj = (TransferObject)tobjList.get(k - nStart);
                  Object locking = tobj.findValue(sLockingAttributeName);

                  if (locking == null || ObjUtil.equal(locking, instance.getValue(nLockingOrdinal)))
                  {
                     if (!bError)
                     {
                        PersistenceException ex = new PersistenceException("err.persistence.virtual.lockingNotModified",
                           new Object[]{sLockingAttributeName, instance.getMetaclass().getName()});

                        ex.setValue("result", tobj);

                        throw ex;
                     }
                  }
                  else
                  {
                     instance.setValueDirect(nLockingOrdinal, locking);
                  }
               }
            }
         }
      }
   }

   /**
    * @see java.lang.Object#toString()
    */
   public String toString()
   {
      StringBuilder buf = new StringBuilder("Virtual update of class ");

      buf.append(m_instance.getMetaclass().getName());

      if (m_attributeSet != null && !m_attributeSet.isEmpty())
      {
         buf.append(" attributes (");
         UpdateMapping.appendAttrSet(buf, m_attributeSet, m_instance.getMetaclass());
         buf.append(')');
      }
      else
      {
         buf.append(", no attributes updated");
      }

      return buf.toString();
   }
}
TOP

Related Classes of nexj.core.persistence.virtual.VirtualUpdate

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.