[exo-jcr-commits] exo-jcr SVN: r951 - jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache.

do-not-reply at jboss.org do-not-reply at jboss.org
Tue Dec 8 11:21:28 EST 2009


Author: areshetnyak
Date: 2009-12-08 11:21:28 -0500 (Tue, 08 Dec 2009)
New Revision: 951

Modified:
   jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoader.java
Log:
EXOJCR-278 : The commit in DB on prepare phase in JDBCCacheLoder.

Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoader.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoader.java	2009-12-08 15:53:12 UTC (rev 950)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoader.java	2009-12-08 16:21:28 UTC (rev 951)
@@ -1,878 +1,882 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * 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.exoplatform.services.jcr.impl.storage.jbosscache;
-
-import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
-import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.datamodel.PropertyData;
-import org.exoplatform.services.jcr.datamodel.QPathEntry;
-import org.exoplatform.services.jcr.impl.dataflow.TransientItemData;
-import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection;
-import org.exoplatform.services.jcr.impl.storage.jdbc.PropertyDataInfo;
-import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
-import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.Modification;
-import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
-import org.jboss.cache.factories.annotations.Inject;
-import org.jboss.cache.loader.AbstractCacheLoader;
-
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.jcr.RepositoryException;
-
-/**
- * Created by The eXo Platform SAS.
- * 
- * <br/>Date: 31.10.2009
- *
- * @author <a href="mailto:peter.nedonosko at exoplatform.com.ua">Peter Nedonosko</a> 
- * @version $Id$
- */
-public class JDBCCacheLoader extends AbstractCacheLoader
-{
-   protected static final Log LOG = ExoLogger.getLogger("jcr.JDBCCacheLoader");
-
-   /**
-    * Storage connections involved in transactions.
-    */
-   protected Map<Object, JDBCStorageConnection> transactions = new ConcurrentHashMap<Object, JDBCStorageConnection>();
-
-   private IndividualCacheLoaderConfig config;
-
-   private WorkspaceDataContainer dataContainer;
-
-   public JDBCCacheLoader()
-   {
-   }
-
-   /**
-    * Init the loader DataContainer with given WorkspaceDataContainer instance.
-    *
-    * @param dataContainer WorkspaceDataContainer
-    */
-   @Inject
-   public void init(WorkspaceDataContainer dataContainer) throws RepositoryConfigurationException
-   {
-      if (this.dataContainer != null)
-      {
-         throw new RepositoryConfigurationException("Cannot set WorkspaceDataContainer twice");
-      }
-
-      this.dataContainer = dataContainer;
-   }
-
-   /**
-    * Apply all Modifications on JDBC database, but don't commit them.
-    *
-    * @param modifications List if Modification
-    * @param conn JDBCStorageConnection
-    * @throws RepositoryException if error occurs
-    */
-   protected void apply(List<Modification> modifications, JDBCStorageConnection conn) throws RepositoryException
-   {
-      for (Modification m : modifications)
-      {
-         switch (m.getType())
-         {
-            case PUT_DATA :
-               if (LOG.isDebugEnabled())
-               {
-                  LOG.debug("PUT_DATA modification");
-               }
-               break;
-            case PUT_DATA_ERASE :
-               if (LOG.isDebugEnabled())
-               {
-                  LOG.debug("PUT_DATA_ERASE modification");
-               }
-               break;
-            case PUT_KEY_VALUE :
-               if (LOG.isDebugEnabled())
-               {
-                  LOG.debug("PUT_KEY_VALUE modification");
-               }
-
-               doUpdate(m, conn);
-
-               break;
-            case REMOVE_DATA :
-               if (LOG.isDebugEnabled())
-               {
-                  LOG.debug("REMOVE_DATA modification");
-               }
-               break;
-            case REMOVE_KEY_VALUE :
-               if (LOG.isDebugEnabled())
-               {
-                  LOG.debug("REMOVE_KEY_VALUE modification");
-               }
-               break;
-            case REMOVE_NODE :
-               if (LOG.isDebugEnabled())
-               {
-                  LOG.debug("REMOVE_NODE modification");
-               }
-
-               doRemove(m, conn);
-
-               break;
-            case MOVE :
-               if (LOG.isDebugEnabled())
-               {
-                  LOG.debug("MOVE modification");
-               }
-               break;
-            default :
-               throw new CacheException("Unknown modification " + m.getType());
-         }
-      }
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public void put(List<Modification> modifications) throws Exception
-   {
-      if (LOG.isDebugEnabled())
-      {
-         LOG.debug("Modifications list  size = " + modifications.size());
-      }
-
-      JDBCStorageConnection conn = (JDBCStorageConnection)dataContainer.openConnection();
-
-      try
-      {
-         apply(modifications, conn);
-         conn.commit();
-      }
-      catch (RepositoryException e)
-      {
-         LOG.error("RepositoryException: ", e); // TODO don't catch, but be sure it will be thrown to JCR
-         throw new RepositoryException(e);
-      }
-      catch (IllegalStateException e)
-      {
-         LOG.error("IllegalStateException: ", e); // TODO don't catch, but be sure it will be thrown to JCR
-         throw new IllegalStateException(e);
-      }
-      finally
-      {
-         if (conn != null && conn.isOpened())
-         {
-            conn.rollback();
-         }
-      }
-   }
-
-   /**
-    * Remove NodeData or PropertyData.
-    * 
-    * @param modification Modification
-    * @param conn JDBCStorageConnection
-    * @throws IllegalStateException if connection closed
-    * @throws RepositoryException if error occurs
-    */
-   private void doRemove(Modification modification, JDBCStorageConnection conn) throws IllegalStateException,
-      RepositoryException
-   {
-      Fqn fqn = IdTreeHelper.buildFqn(modification.getFqn());
-
-      if (fqn.size() == 2)
-      {
-         String identifier = (String)fqn.get(1);
-
-         if (fqn.get(0).equals(JBossCacheStorage.NODES))
-         {
-            conn.deleteNode(identifier);
-         }
-         else if (fqn.get(0).equals(JBossCacheStorage.PROPS))
-         {
-            conn.deleteProperty(identifier);
-         }
-      }
-      else
-      {
-         // remove of child node, we're not interested in such info for persistence
-      }
-   }
-
-   /**
-    * Performs ADD to NodeData and PropertyData.
-    * 
-    * @param modification Modification
-    * @param conn JDBCStorageConnection
-    * @throws IllegalStateException if connection closed
-    * @throws RepositoryException if error occurs
-    */
-   private void doAdd(Modification modification, JDBCStorageConnection conn) throws IllegalStateException,
-      RepositoryException
-   {
-      if (modification.getValue() instanceof NodeData)
-      {
-         //add node data
-         conn.add((NodeData)modification.getValue());
-      }
-      else if (modification.getValue() instanceof PropertyData)
-      {
-         //add property data
-         conn.add((PropertyData)modification.getValue());
-      }
-   }
-
-   /**
-    * Performs UPDATE to NodeData or PropertyData.
-    * 
-    * @param modification Modification
-    * @param conn JDBCStorageConnection
-    * @throws IllegalStateException if connection closed
-    * @throws RepositoryException if error occurs
-    */
-   private void doUpdate(Modification m, JDBCStorageConnection conn) throws IllegalStateException, RepositoryException
-   {
-      Fqn fqn = IdTreeHelper.buildFqn(m.getFqn());
-
-      if (fqn.size() == 2 && m.getValue() instanceof TransientItemData)
-      {
-         //Check flag it's mixin update for node, if this flag set we have node need to 
-         TransientItemData item = (TransientItemData)m.getValue();
-
-         if ((item.getState() & TransientItemData.TRANSITIVE_PATH_UPDATED) == 0)
-         {
-            // if not a transitive update of path, update it in the database
-            if (conn.itemExists((String)fqn.get(1), item.isNode()))
-            {
-               // update if it's non transitive update
-               if (item.isNode())
-               {
-                  if ((item.getState() & TransientItemData.TRANSITIVE_MIXIN_UPDATED) == 0
-                     && (item.getState() & TransientItemData.TRANSITIVE_ACL_UPDATED) == 0)
-                  {
-                     // TODO do not handle mixin or ACL updates in db; it's a workaround - review logic in the connection
-
-                     // TODO conn.rename() is used to update all the fields in DB.
-                     // Original conn.update() will be matched as deprecated, 
-                     // and conn.rename() should be renamed to update. This
-                     // is done to solve the issue, when we need to guess each
-                     // time whether node is moved or just updated. This
-                     // solution is used as the fastest among other. 
-                     conn.rename((NodeData)item);
-                  }
-               }
-               else
-               {
-                  //update property data
-                  conn.update((PropertyData)item);
-               }
-            }
-            else
-            {
-               doAdd(m, conn);
-            }
-         }
-      }
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public Map<Object, Object> get(Fqn fqn) throws Exception
-   {
-      Fqn name = (fqn.size() > 1 ? IdTreeHelper.buildFqn(fqn) : fqn);
-      Map<Object, Object> attrs;
-
-      if (name.size() > 1)
-      {
-         if (name.get(0).equals(JBossCacheStorage.NODES))
-         {
-            // /$NODES/<NODE_ID>
-            if (name.size() == 2)
-            {
-               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
-               try
-               {
-                  String nodeId = name.getLastElementAsString();
-                  NodeData nodeData = (NodeData) conn.getItemData(nodeId);
-                  if (nodeData != null)
-                  {
-                     List<PropertyDataInfo> childProps = conn.getChildProperties(nodeId);
-                     if (childProps.size() <= 0)
-                     {
-                        throw new JDBCCacheLoaderException("FATAL Empty attributes for Node " + nodeId + "  '" + name
-                                 + "'");
-                     }
-
-                     attrs = new LinkedHashMap<Object, Object>();
-                     attrs.put(JBossCacheStorage.ITEM_DATA, nodeData);
-                     for (PropertyDataInfo prop : childProps)
-                     {
-                        attrs.put(prop.getPropertyName(), prop.getPropertyId());
-                     }
-                  }
-                  else
-                  {
-                     attrs = null;
-                  }
-               }
-               finally
-               {
-                  conn.close();
-               }
-            }
-            // /$NODES/<NODE_ID>/<SUB_NODE_NAME>
-            else if (name.size() == 3)
-            {
-               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
-               try
-               {
-                  QPathEntry childNodeName = QPathEntry.parse(name.getLastElementAsString());
-                  String parentId = (String) name.get(1);
-
-                  String nodeId =
-                           conn.getNodeIdentifier(parentId, childNodeName.getAsString(false), childNodeName.getIndex());
-                  if (nodeId != null)
-                  {
-                     attrs = new LinkedHashMap<Object, Object>();
-                     attrs.put(JBossCacheStorage.ITEM_ID, nodeId);
-                  }
-                  else
-                  {
-                     attrs = null;
-                  }
-               }
-               finally
-               {
-                  conn.close();
-               }
-            }
-            else
-            {
-               attrs = null;
-               LOG.warn("Unexpected Fqn asked " + name);
-            }
-         }
-         // /$PROPS/<PROPERTY_ID>
-         else if (name.get(0).equals(JBossCacheStorage.PROPS))
-         {
-            if (name.size() == 2)
-            {
-               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
-               try
-               {
-                  String propertyId = name.getLastElementAsString();
-                  PropertyData propertyData = (PropertyData) conn.getItemData(propertyId);
-                  if (propertyData != null)
-                  {
-                     attrs = new LinkedHashMap<Object, Object>();
-                     attrs.put(JBossCacheStorage.ITEM_DATA, propertyData);
-                  }
-                  else
-                  {
-                     attrs = null;
-                  }
-               }
-               finally
-               {
-                  conn.close();
-               }
-            }
-            else
-            {
-               attrs = null;
-               LOG.warn("Unexpected Fqn asked " + name);
-            }
-         }
-         else if (name.get(0).equals(JBossCacheStorage.REFS))
-         {
-            // get reference
-            if (name.size() == 3)
-            {
-               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
-               try
-               {
-                  // do we have such property reference
-                  String nodeID = String.valueOf(name.get(1));
-                  String propID = String.valueOf(name.get(2));
-
-                  if (conn.hasReference(nodeID, propID))
-                  {
-                     attrs = new LinkedHashMap<Object, Object>();
-                  }
-                  else
-                  {
-                     attrs = null;
-                  }
-               }
-               finally
-               {
-                  conn.close();
-               }
-            }
-            else if (name.size() == 2)
-            {
-               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
-               try
-               {
-                  // do we have node with any reference
-                  String nodeID = name.getLastElementAsString();
-                  if (conn.getReferenceIdentifiers(nodeID).size() > 0)
-                  {
-                     attrs = new LinkedHashMap<Object, Object>();
-                  }
-                  else
-                  {
-                     attrs = null;
-                  }
-               }
-               finally
-               {
-                  conn.close();
-               }
-            }
-            else
-            {
-               attrs = null;
-               LOG.warn("Unexpected Fqn asked " + name);
-            }
-
-         }
-         else
-         {
-            attrs = null;
-            if (LOG.isDebugEnabled())
-            {
-               LOG.warn("Unexpected Fqn asked " + name);
-            }
-         }
-      }
-      else if (name.isRoot() || name.equals(Fqn.ROOT) || name.getLastElementAsString().equals("/")
-               || name.get(0).equals(JBossCacheStorage.PROPS) || name.get(0).equals(JBossCacheStorage.NODES)
-               || name.get(0).equals(JBossCacheStorage.LOCKS) || name.get(0).equals(JBossCacheStorage.REFS))
-      {
-         // roots, like NODES, PROPS etc               
-         attrs = new LinkedHashMap<Object, Object>();
-      }
-      else
-      {
-         LOG.warn("Unexpected Fqn asked " + name);
-         attrs = null;
-      }
-
-      return attrs;
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public boolean exists(Fqn fqn) throws Exception
-   {
-      Fqn name = (fqn.size() > 1 ? IdTreeHelper.buildFqn(fqn) : fqn);
-
-      boolean exists;
-
-      if (name.size() > 1)
-      {
-         if (name.get(0).equals(JBossCacheStorage.NODES))
-         {
-            // /$NODES/<NODE_ID>
-            if (name.size() == 2)
-            {
-               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
-               try
-               {
-                  String nodeId = name.getLastElementAsString();
-                  String nodeName = conn.getNodeName(nodeId);
-
-                  if (nodeName != null)
-                  {
-                     exists = true;
-                  }
-                  else
-                  {
-                     exists = false;
-                  }
-               }
-               finally
-               {
-                  conn.close();
-               }
-            }
-            // /$NODES/<NODE_ID>/<SUB_NODE_NAME>
-            else if (name.size() == 3)
-            {
-               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
-               try
-               {
-                  QPathEntry childNodeName = QPathEntry.parse(name.getLastElementAsString());
-                  String parentId = (String) name.get(1);
-
-                  String nodeId =
-                           conn.getNodeIdentifier(parentId, childNodeName.getAsString(false), childNodeName.getIndex());
-                  if (nodeId != null)
-                  {
-                     exists = true;
-                  }
-                  else
-                  {
-                     exists = false;
-                  }
-               }
-               finally
-               {
-                  conn.close();
-               }
-            }
-            else
-            {
-               exists = false;
-               LOG.warn("Unexpected Fqn asked " + name);
-            }
-         }
-         // /$PROPS/<PROPERTY_ID>
-         else if (name.get(0).equals(JBossCacheStorage.PROPS))
-         {
-            if (name.size() == 2)
-            {
-               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
-               try
-               {
-                  String propertyId = name.getLastElementAsString();
-                  String propertyName = conn.getPropertyName(propertyId);
-
-                  if (propertyName != null)
-                  {
-                     exists = true;
-                  }
-                  else
-                  {
-                     exists = false;
-                  }
-               }
-               finally
-               {
-                  conn.close();
-               }
-            }
-            else
-            {
-               exists = false;
-               LOG.warn("Unexpected Fqn asked " + name);
-            }
-         }
-         else if (name.get(0).equals(JBossCacheStorage.REFS))
-         {
-            // /$REFS/<NODE_ID>
-            if (name.size() == 2)
-            {
-               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
-               try
-               {
-                  String nodeId = name.getLastElementAsString();
-                  exists = conn.getReferenceIdentifiers(nodeId).size() > 0;
-               }
-               finally
-               {
-                  conn.close();
-               }
-            }
-            // /$REFS/<NODE_ID>/<REF_PROP_ID>
-            else if (name.size() == 3)
-            {
-               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
-               try
-               {
-                  String refPropertyId = name.getLastElementAsString();
-                  String nodeId = (String) name.get(1);
-
-                  exists = conn.hasReference(nodeId, refPropertyId);
-               }
-               finally
-               {
-                  conn.close();
-               }
-            }
-            else
-            {
-               exists = false;
-               LOG.warn("Unexpected Fqn asked " + name);
-            }
-         }
-         else
-         {
-            exists = false;
-            if (LOG.isDebugEnabled())
-            {
-               LOG.debug("Unexpected Fqn asked " + name);
-            }
-         }
-      }
-      else if (name.isRoot() || name.equals(Fqn.ROOT) || name.getLastElementAsString().equals("/")
-               || name.get(0).equals(JBossCacheStorage.PROPS) || name.get(0).equals(JBossCacheStorage.NODES)
-               || name.get(0).equals(JBossCacheStorage.LOCKS) || name.get(0).equals(JBossCacheStorage.REFS))
-      {
-         // roots, like NODES, PROPS etc               
-         exists = true;
-      }
-      else
-      {
-         exists = false;
-         LOG.warn("Unexpected Fqn asked " + name);
-      }
-
-      return exists;
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public Set<?> getChildrenNames(Fqn fqn) throws Exception
-   {
-      // return child nodes names
-
-      //to sub Fqn (example /$LOCKS/5/4/3) 
-      //      if (IdTreeHelper.isSubFqn(fqn))
-      //         return null;
-
-      Fqn name = (fqn.size() >= 2 ? IdTreeHelper.buildFqn(fqn) : fqn);
-
-      // /$NODES/<NODE_ID>
-      if (name.size() == 2)
-      {
-         String nodeId = (String) name.get(1);
-         if (name.get(0).equals(JBossCacheStorage.NODES))
-         {
-            JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
-            try
-            {
-               return conn.getChildNodeNames(nodeId);
-            }
-            finally
-            {
-               conn.close();
-            }
-         }
-         else if (name.get(0).equals(JBossCacheStorage.REFS))
-         {
-            JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
-            try
-            {
-               List<String> references = conn.getReferenceIdentifiers(nodeId);
-               Set<String> result = new LinkedHashSet<String>();
-               result.addAll(references);
-               return result;
-            }
-            finally
-            {
-               conn.close();
-            }
-         }
-         else
-         {
-            // TODO this a property on any unexpected part of cache throw Exception
-            return null;
-         }
-      }
-      else if (name.isRoot() || name.get(0).equals(Fqn.ROOT) || name.getLastElementAsString().equals("/"))
-      {
-         Set<String> childs = new LinkedHashSet<String>();
-         childs.add(JBossCacheStorage.NODES);
-         childs.add(JBossCacheStorage.PROPS);
-         childs.add(JBossCacheStorage.LOCKS);
-         childs.add(JBossCacheStorage.REFS);
-         return childs;
-      }
-      else if (name.size() > 2)
-      {
-         // seems it is fqn like /$NODES/nodeUUID/childname[/...] or /$REFS/nodeUUID/propUUUIS[/...]
-         // TODO  this is unexpected part of cache throw Exception
-         LOG.warn("This is unexpected FQN " + name);
-         return null;
-      }
-      else if (name.get(0).equals(JBossCacheStorage.NODES))
-      {
-         // TODO should never be called
-         LOG.warn("conn.getAllNodeIdentifiers()");
-         return null/*conn.getAllNodeIdentifiers()*/;
-      }
-      else if (name.get(0).equals(JBossCacheStorage.PROPS))
-      {
-         // TODO should never be called
-         LOG.warn("conn.getAllPropertyIdentifiers()");
-         return null/*conn.getAllPropertyIdentifiers()*/;
-      }
-      else if (name.get(0).equals(JBossCacheStorage.LOCKS))
-      {
-         // TODO return all Locks in workspace
-         return new LinkedHashSet<String>();
-      }
-      else if (name.get(0).equals(JBossCacheStorage.REFS))
-      {
-         return null/*conn.getAllRefencedNodeIdentifiers()*/;
-      }
-      else
-      {
-         return null;
-      }
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public IndividualCacheLoaderConfig getConfig()
-   {
-      return config;
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public void setConfig(IndividualCacheLoaderConfig config)
-   {
-      this.config = config;
-
-   }
-
-   // 2-phase TRANSACTION support
-
-   /**
-    * {@inheritDoc}
-    */
-   public void prepare(Object tx, List<Modification> modifications, boolean onePhase) throws Exception
-   {
-      if (onePhase)
-      {
-         final JDBCStorageConnection conn = (JDBCStorageConnection)dataContainer.openConnection();
-         apply(modifications, conn);
-         conn.commit(); // same immediately 
-      }
-      else
-      {
-         final JDBCStorageConnection exconn = transactions.remove(tx);
-         if (exconn != null)
-         {
-            // apply in existed connection associated with tx
-            apply(modifications, exconn);
-         }
-         else
-         {
-            // open new tx conn, apply in it, save the conn
-            final JDBCStorageConnection conn = (JDBCStorageConnection)dataContainer.openConnection();
-            apply(modifications, conn);
-            transactions.put(tx, conn);
-         }
-      }
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public void commit(Object tx) throws Exception
-   {
-      final WorkspaceStorageConnection conn = transactions.remove(tx);
-      if (conn == null)
-      {
-         throw new RepositoryException("Transaction " + tx + " not found in transaction table.");
-      }
-
-      conn.commit();
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public void rollback(Object tx)
-   {
-      final WorkspaceStorageConnection conn = transactions.remove(tx);
-      if (conn != null)
-      {
-         try
-         {
-            conn.rollback();
-         }
-         catch (Throwable e)
-         {
-            // TODO why we cannot throw an exception??? (throws Exception expected)
-            LOG.error("Error of transaction " + tx + " rollback.", e);
-         }
-      }
-      else
-      {
-         LOG.warn("Transaction " + tx + " not found in transaction table, but rollback called.");
-      }
-   }
-
-   // SHOULD NOT BE USED methods
-
-   /**
-    * {@inheritDoc}
-    */
-   public Object put(Fqn name, Object key, Object value) throws Exception
-   {
-      LOG.error("The method 'put(Fqn name, Object key, Object value))' should not be called. " + name + " " + key + " "
-         + value);
-      throw new JDBCCacheLoaderException("The method 'put(Fqn name, Object key, Object value))' should not be called.");
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public void put(Fqn name, Map<Object, Object> attributes) throws Exception
-   {
-      LOG.error("The method 'put(Fqn name, Map<Object, Object> attributes)' should not be called. " + name + " "
-         + attributes);
-      throw new JDBCCacheLoaderException(
-         "The method 'put(Fqn name, Map<Object, Object> attributes)' should not be called.");
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public Object remove(Fqn fqn, Object key) throws Exception
-   {
-      LOG.error("The method 'remove(Fqn fqn, Object key)' should not be called. " + fqn + " " + key);
-      throw new JDBCCacheLoaderException("The method 'remove(Fqn fqn, Object key)' should not be called.");
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public void remove(Fqn fqn) throws Exception
-   {
-      LOG.error("The method 'remove(Fqn fqn)' should not be called. " + fqn);
-      throw new JDBCCacheLoaderException("The method 'remove(Fqn fqn)' should not be called.");
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public void removeData(Fqn fqn) throws Exception
-   {
-      LOG.error("The method 'removeData(Fqn fqn)' should not be called. " + fqn);
-      throw new JDBCCacheLoaderException("The method 'removeData(Fqn fqn)' should not be called.");
-   }
-
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * 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.exoplatform.services.jcr.impl.storage.jbosscache;
+
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.PropertyData;
+import org.exoplatform.services.jcr.datamodel.QPathEntry;
+import org.exoplatform.services.jcr.impl.dataflow.TransientItemData;
+import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection;
+import org.exoplatform.services.jcr.impl.storage.jdbc.PropertyDataInfo;
+import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
+import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Modification;
+import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
+import org.jboss.cache.factories.annotations.Inject;
+import org.jboss.cache.loader.AbstractCacheLoader;
+
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS.
+ * 
+ * <br/>Date: 31.10.2009
+ *
+ * @author <a href="mailto:peter.nedonosko at exoplatform.com.ua">Peter Nedonosko</a> 
+ * @version $Id$
+ */
+public class JDBCCacheLoader extends AbstractCacheLoader
+{
+   protected static final Log LOG = ExoLogger.getLogger("jcr.JDBCCacheLoader");
+
+   /**
+    * Storage connections involved in transactions.
+    */
+   protected Map<Object, JDBCStorageConnection> transactions = new ConcurrentHashMap<Object, JDBCStorageConnection>();
+
+   private IndividualCacheLoaderConfig config;
+
+   private WorkspaceDataContainer dataContainer;
+
+   public JDBCCacheLoader()
+   {
+   }
+
+   /**
+    * Init the loader DataContainer with given WorkspaceDataContainer instance.
+    *
+    * @param dataContainer WorkspaceDataContainer
+    */
+   @Inject
+   public void init(WorkspaceDataContainer dataContainer) throws RepositoryConfigurationException
+   {
+      if (this.dataContainer != null)
+      {
+         throw new RepositoryConfigurationException("Cannot set WorkspaceDataContainer twice");
+      }
+
+      this.dataContainer = dataContainer;
+   }
+
+   /**
+    * Apply all Modifications on JDBC database, but don't commit them.
+    *
+    * @param modifications List if Modification
+    * @param conn JDBCStorageConnection
+    * @throws RepositoryException if error occurs
+    */
+   protected void apply(List<Modification> modifications, JDBCStorageConnection conn) throws RepositoryException
+   {
+      for (Modification m : modifications)
+      {
+         switch (m.getType())
+         {
+            case PUT_DATA :
+               if (LOG.isDebugEnabled())
+               {
+                  LOG.debug("PUT_DATA modification");
+               }
+               break;
+            case PUT_DATA_ERASE :
+               if (LOG.isDebugEnabled())
+               {
+                  LOG.debug("PUT_DATA_ERASE modification");
+               }
+               break;
+            case PUT_KEY_VALUE :
+               if (LOG.isDebugEnabled())
+               {
+                  LOG.debug("PUT_KEY_VALUE modification");
+               }
+
+               doUpdate(m, conn);
+
+               break;
+            case REMOVE_DATA :
+               if (LOG.isDebugEnabled())
+               {
+                  LOG.debug("REMOVE_DATA modification");
+               }
+               break;
+            case REMOVE_KEY_VALUE :
+               if (LOG.isDebugEnabled())
+               {
+                  LOG.debug("REMOVE_KEY_VALUE modification");
+               }
+               break;
+            case REMOVE_NODE :
+               if (LOG.isDebugEnabled())
+               {
+                  LOG.debug("REMOVE_NODE modification");
+               }
+
+               doRemove(m, conn);
+
+               break;
+            case MOVE :
+               if (LOG.isDebugEnabled())
+               {
+                  LOG.debug("MOVE modification");
+               }
+               break;
+            default :
+               throw new CacheException("Unknown modification " + m.getType());
+         }
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void put(List<Modification> modifications) throws Exception
+   {
+      if (LOG.isDebugEnabled())
+      {
+         LOG.debug("Modifications list  size = " + modifications.size());
+      }
+
+      JDBCStorageConnection conn = (JDBCStorageConnection)dataContainer.openConnection();
+
+      try
+      {
+         apply(modifications, conn);
+         conn.commit();
+      }
+      catch (RepositoryException e)
+      {
+         LOG.error("RepositoryException: ", e); // TODO don't catch, but be sure it will be thrown to JCR
+         throw new RepositoryException(e);
+      }
+      catch (IllegalStateException e)
+      {
+         LOG.error("IllegalStateException: ", e); // TODO don't catch, but be sure it will be thrown to JCR
+         throw new IllegalStateException(e);
+      }
+      finally
+      {
+         if (conn != null && conn.isOpened())
+         {
+            conn.rollback();
+         }
+      }
+   }
+
+   /**
+    * Remove NodeData or PropertyData.
+    * 
+    * @param modification Modification
+    * @param conn JDBCStorageConnection
+    * @throws IllegalStateException if connection closed
+    * @throws RepositoryException if error occurs
+    */
+   private void doRemove(Modification modification, JDBCStorageConnection conn) throws IllegalStateException,
+      RepositoryException
+   {
+      Fqn fqn = IdTreeHelper.buildFqn(modification.getFqn());
+
+      if (fqn.size() == 2)
+      {
+         String identifier = (String)fqn.get(1);
+
+         if (fqn.get(0).equals(JBossCacheStorage.NODES))
+         {
+            conn.deleteNode(identifier);
+         }
+         else if (fqn.get(0).equals(JBossCacheStorage.PROPS))
+         {
+            conn.deleteProperty(identifier);
+         }
+      }
+      else
+      {
+         // remove of child node, we're not interested in such info for persistence
+      }
+   }
+
+   /**
+    * Performs ADD to NodeData and PropertyData.
+    * 
+    * @param modification Modification
+    * @param conn JDBCStorageConnection
+    * @throws IllegalStateException if connection closed
+    * @throws RepositoryException if error occurs
+    */
+   private void doAdd(Modification modification, JDBCStorageConnection conn) throws IllegalStateException,
+      RepositoryException
+   {
+      if (modification.getValue() instanceof NodeData)
+      {
+         //add node data
+         conn.add((NodeData)modification.getValue());
+      }
+      else if (modification.getValue() instanceof PropertyData)
+      {
+         //add property data
+         conn.add((PropertyData)modification.getValue());
+      }
+   }
+
+   /**
+    * Performs UPDATE to NodeData or PropertyData.
+    * 
+    * @param modification Modification
+    * @param conn JDBCStorageConnection
+    * @throws IllegalStateException if connection closed
+    * @throws RepositoryException if error occurs
+    */
+   private void doUpdate(Modification m, JDBCStorageConnection conn) throws IllegalStateException, RepositoryException
+   {
+      Fqn fqn = IdTreeHelper.buildFqn(m.getFqn());
+
+      if (fqn.size() == 2 && m.getValue() instanceof TransientItemData)
+      {
+         //Check flag it's mixin update for node, if this flag set we have node need to 
+         TransientItemData item = (TransientItemData)m.getValue();
+
+         if ((item.getState() & TransientItemData.TRANSITIVE_PATH_UPDATED) == 0)
+         {
+            // if not a transitive update of path, update it in the database
+            if (conn.itemExists((String)fqn.get(1), item.isNode()))
+            {
+               // update if it's non transitive update
+               if (item.isNode())
+               {
+                  if ((item.getState() & TransientItemData.TRANSITIVE_MIXIN_UPDATED) == 0
+                     && (item.getState() & TransientItemData.TRANSITIVE_ACL_UPDATED) == 0)
+                  {
+                     // TODO do not handle mixin or ACL updates in db; it's a workaround - review logic in the connection
+
+                     // TODO conn.rename() is used to update all the fields in DB.
+                     // Original conn.update() will be matched as deprecated, 
+                     // and conn.rename() should be renamed to update. This
+                     // is done to solve the issue, when we need to guess each
+                     // time whether node is moved or just updated. This
+                     // solution is used as the fastest among other. 
+                     conn.rename((NodeData)item);
+                  }
+               }
+               else
+               {
+                  //update property data
+                  conn.update((PropertyData)item);
+               }
+            }
+            else
+            {
+               doAdd(m, conn);
+            }
+         }
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public Map<Object, Object> get(Fqn fqn) throws Exception
+   {
+      Fqn name = (fqn.size() > 1 ? IdTreeHelper.buildFqn(fqn) : fqn);
+      Map<Object, Object> attrs;
+
+      if (name.size() > 1)
+      {
+         if (name.get(0).equals(JBossCacheStorage.NODES))
+         {
+            // /$NODES/<NODE_ID>
+            if (name.size() == 2)
+            {
+               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
+               try
+               {
+                  String nodeId = name.getLastElementAsString();
+                  NodeData nodeData = (NodeData) conn.getItemData(nodeId);
+                  if (nodeData != null)
+                  {
+                     List<PropertyDataInfo> childProps = conn.getChildProperties(nodeId);
+                     if (childProps.size() <= 0)
+                     {
+                        throw new JDBCCacheLoaderException("FATAL Empty attributes for Node " + nodeId + "  '" + name
+                                 + "'");
+                     }
+
+                     attrs = new LinkedHashMap<Object, Object>();
+                     attrs.put(JBossCacheStorage.ITEM_DATA, nodeData);
+                     for (PropertyDataInfo prop : childProps)
+                     {
+                        attrs.put(prop.getPropertyName(), prop.getPropertyId());
+                     }
+                  }
+                  else
+                  {
+                     attrs = null;
+                  }
+               }
+               finally
+               {
+                  conn.close();
+               }
+            }
+            // /$NODES/<NODE_ID>/<SUB_NODE_NAME>
+            else if (name.size() == 3)
+            {
+               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
+               try
+               {
+                  QPathEntry childNodeName = QPathEntry.parse(name.getLastElementAsString());
+                  String parentId = (String) name.get(1);
+
+                  String nodeId =
+                           conn.getNodeIdentifier(parentId, childNodeName.getAsString(false), childNodeName.getIndex());
+                  if (nodeId != null)
+                  {
+                     attrs = new LinkedHashMap<Object, Object>();
+                     attrs.put(JBossCacheStorage.ITEM_ID, nodeId);
+                  }
+                  else
+                  {
+                     attrs = null;
+                  }
+               }
+               finally
+               {
+                  conn.close();
+               }
+            }
+            else
+            {
+               attrs = null;
+               LOG.warn("Unexpected Fqn asked " + name);
+            }
+         }
+         // /$PROPS/<PROPERTY_ID>
+         else if (name.get(0).equals(JBossCacheStorage.PROPS))
+         {
+            if (name.size() == 2)
+            {
+               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
+               try
+               {
+                  String propertyId = name.getLastElementAsString();
+                  PropertyData propertyData = (PropertyData) conn.getItemData(propertyId);
+                  if (propertyData != null)
+                  {
+                     attrs = new LinkedHashMap<Object, Object>();
+                     attrs.put(JBossCacheStorage.ITEM_DATA, propertyData);
+                  }
+                  else
+                  {
+                     attrs = null;
+                  }
+               }
+               finally
+               {
+                  conn.close();
+               }
+            }
+            else
+            {
+               attrs = null;
+               LOG.warn("Unexpected Fqn asked " + name);
+            }
+         }
+         else if (name.get(0).equals(JBossCacheStorage.REFS))
+         {
+            // get reference
+            if (name.size() == 3)
+            {
+               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
+               try
+               {
+                  // do we have such property reference
+                  String nodeID = String.valueOf(name.get(1));
+                  String propID = String.valueOf(name.get(2));
+
+                  if (conn.hasReference(nodeID, propID))
+                  {
+                     attrs = new LinkedHashMap<Object, Object>();
+                  }
+                  else
+                  {
+                     attrs = null;
+                  }
+               }
+               finally
+               {
+                  conn.close();
+               }
+            }
+            else if (name.size() == 2)
+            {
+               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
+               try
+               {
+                  // do we have node with any reference
+                  String nodeID = name.getLastElementAsString();
+                  if (conn.getReferenceIdentifiers(nodeID).size() > 0)
+                  {
+                     attrs = new LinkedHashMap<Object, Object>();
+                  }
+                  else
+                  {
+                     attrs = null;
+                  }
+               }
+               finally
+               {
+                  conn.close();
+               }
+            }
+            else
+            {
+               attrs = null;
+               LOG.warn("Unexpected Fqn asked " + name);
+            }
+
+         }
+         else
+         {
+            attrs = null;
+            if (LOG.isDebugEnabled())
+            {
+               LOG.warn("Unexpected Fqn asked " + name);
+            }
+         }
+      }
+      else if (name.isRoot() || name.equals(Fqn.ROOT) || name.getLastElementAsString().equals("/")
+               || name.get(0).equals(JBossCacheStorage.PROPS) || name.get(0).equals(JBossCacheStorage.NODES)
+               || name.get(0).equals(JBossCacheStorage.LOCKS) || name.get(0).equals(JBossCacheStorage.REFS))
+      {
+         // roots, like NODES, PROPS etc               
+         attrs = new LinkedHashMap<Object, Object>();
+      }
+      else
+      {
+         LOG.warn("Unexpected Fqn asked " + name);
+         attrs = null;
+      }
+
+      return attrs;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean exists(Fqn fqn) throws Exception
+   {
+      Fqn name = (fqn.size() > 1 ? IdTreeHelper.buildFqn(fqn) : fqn);
+
+      boolean exists;
+
+      if (name.size() > 1)
+      {
+         if (name.get(0).equals(JBossCacheStorage.NODES))
+         {
+            // /$NODES/<NODE_ID>
+            if (name.size() == 2)
+            {
+               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
+               try
+               {
+                  String nodeId = name.getLastElementAsString();
+                  String nodeName = conn.getNodeName(nodeId);
+
+                  if (nodeName != null)
+                  {
+                     exists = true;
+                  }
+                  else
+                  {
+                     exists = false;
+                  }
+               }
+               finally
+               {
+                  conn.close();
+               }
+            }
+            // /$NODES/<NODE_ID>/<SUB_NODE_NAME>
+            else if (name.size() == 3)
+            {
+               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
+               try
+               {
+                  QPathEntry childNodeName = QPathEntry.parse(name.getLastElementAsString());
+                  String parentId = (String) name.get(1);
+
+                  String nodeId =
+                           conn.getNodeIdentifier(parentId, childNodeName.getAsString(false), childNodeName.getIndex());
+                  if (nodeId != null)
+                  {
+                     exists = true;
+                  }
+                  else
+                  {
+                     exists = false;
+                  }
+               }
+               finally
+               {
+                  conn.close();
+               }
+            }
+            else
+            {
+               exists = false;
+               LOG.warn("Unexpected Fqn asked " + name);
+            }
+         }
+         // /$PROPS/<PROPERTY_ID>
+         else if (name.get(0).equals(JBossCacheStorage.PROPS))
+         {
+            if (name.size() == 2)
+            {
+               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
+               try
+               {
+                  String propertyId = name.getLastElementAsString();
+                  String propertyName = conn.getPropertyName(propertyId);
+
+                  if (propertyName != null)
+                  {
+                     exists = true;
+                  }
+                  else
+                  {
+                     exists = false;
+                  }
+               }
+               finally
+               {
+                  conn.close();
+               }
+            }
+            else
+            {
+               exists = false;
+               LOG.warn("Unexpected Fqn asked " + name);
+            }
+         }
+         else if (name.get(0).equals(JBossCacheStorage.REFS))
+         {
+            // /$REFS/<NODE_ID>
+            if (name.size() == 2)
+            {
+               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
+               try
+               {
+                  String nodeId = name.getLastElementAsString();
+                  exists = conn.getReferenceIdentifiers(nodeId).size() > 0;
+               }
+               finally
+               {
+                  conn.close();
+               }
+            }
+            // /$REFS/<NODE_ID>/<REF_PROP_ID>
+            else if (name.size() == 3)
+            {
+               JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
+               try
+               {
+                  String refPropertyId = name.getLastElementAsString();
+                  String nodeId = (String) name.get(1);
+
+                  exists = conn.hasReference(nodeId, refPropertyId);
+               }
+               finally
+               {
+                  conn.close();
+               }
+            }
+            else
+            {
+               exists = false;
+               LOG.warn("Unexpected Fqn asked " + name);
+            }
+         }
+         else
+         {
+            exists = false;
+            if (LOG.isDebugEnabled())
+            {
+               LOG.debug("Unexpected Fqn asked " + name);
+            }
+         }
+      }
+      else if (name.isRoot() || name.equals(Fqn.ROOT) || name.getLastElementAsString().equals("/")
+               || name.get(0).equals(JBossCacheStorage.PROPS) || name.get(0).equals(JBossCacheStorage.NODES)
+               || name.get(0).equals(JBossCacheStorage.LOCKS) || name.get(0).equals(JBossCacheStorage.REFS))
+      {
+         // roots, like NODES, PROPS etc               
+         exists = true;
+      }
+      else
+      {
+         exists = false;
+         LOG.warn("Unexpected Fqn asked " + name);
+      }
+
+      return exists;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public Set<?> getChildrenNames(Fqn fqn) throws Exception
+   {
+      // return child nodes names
+
+      //to sub Fqn (example /$LOCKS/5/4/3) 
+      //      if (IdTreeHelper.isSubFqn(fqn))
+      //         return null;
+
+      Fqn name = (fqn.size() >= 2 ? IdTreeHelper.buildFqn(fqn) : fqn);
+
+      // /$NODES/<NODE_ID>
+      if (name.size() == 2)
+      {
+         String nodeId = (String) name.get(1);
+         if (name.get(0).equals(JBossCacheStorage.NODES))
+         {
+            JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
+            try
+            {
+               return conn.getChildNodeNames(nodeId);
+            }
+            finally
+            {
+               conn.close();
+            }
+         }
+         else if (name.get(0).equals(JBossCacheStorage.REFS))
+         {
+            JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
+            try
+            {
+               List<String> references = conn.getReferenceIdentifiers(nodeId);
+               Set<String> result = new LinkedHashSet<String>();
+               result.addAll(references);
+               return result;
+            }
+            finally
+            {
+               conn.close();
+            }
+         }
+         else
+         {
+            // TODO this a property on any unexpected part of cache throw Exception
+            return null;
+         }
+      }
+      else if (name.isRoot() || name.get(0).equals(Fqn.ROOT) || name.getLastElementAsString().equals("/"))
+      {
+         Set<String> childs = new LinkedHashSet<String>();
+         childs.add(JBossCacheStorage.NODES);
+         childs.add(JBossCacheStorage.PROPS);
+         childs.add(JBossCacheStorage.LOCKS);
+         childs.add(JBossCacheStorage.REFS);
+         return childs;
+      }
+      else if (name.size() > 2)
+      {
+         // seems it is fqn like /$NODES/nodeUUID/childname[/...] or /$REFS/nodeUUID/propUUUIS[/...]
+         // TODO  this is unexpected part of cache throw Exception
+         LOG.warn("This is unexpected FQN " + name);
+         return null;
+      }
+      else if (name.get(0).equals(JBossCacheStorage.NODES))
+      {
+         // TODO should never be called
+         LOG.warn("conn.getAllNodeIdentifiers()");
+         return null/*conn.getAllNodeIdentifiers()*/;
+      }
+      else if (name.get(0).equals(JBossCacheStorage.PROPS))
+      {
+         // TODO should never be called
+         LOG.warn("conn.getAllPropertyIdentifiers()");
+         return null/*conn.getAllPropertyIdentifiers()*/;
+      }
+      else if (name.get(0).equals(JBossCacheStorage.LOCKS))
+      {
+         // TODO return all Locks in workspace
+         return new LinkedHashSet<String>();
+      }
+      else if (name.get(0).equals(JBossCacheStorage.REFS))
+      {
+         return null/*conn.getAllRefencedNodeIdentifiers()*/;
+      }
+      else
+      {
+         return null;
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public IndividualCacheLoaderConfig getConfig()
+   {
+      return config;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void setConfig(IndividualCacheLoaderConfig config)
+   {
+      this.config = config;
+
+   }
+
+   // 2-phase TRANSACTION not support
+
+   /**
+    * {@inheritDoc}
+    */
+   public void prepare(Object tx, List<Modification> modifications, boolean onePhase) throws Exception
+   {
+      final JDBCStorageConnection conn = (JDBCStorageConnection)dataContainer.openConnection();
+      apply(modifications, conn);
+      conn.commit();
+      
+      /*if (onePhase)
+      {
+         final JDBCStorageConnection conn = (JDBCStorageConnection)dataContainer.openConnection();
+         apply(modifications, conn);
+         conn.commit(); // same immediately 
+      }
+      else
+      {
+         final JDBCStorageConnection exconn = transactions.remove(tx);
+         if (exconn != null)
+         {
+            // apply in existed connection associated with tx
+            apply(modifications, exconn);
+         }
+         else
+         {
+            // open new tx conn, apply in it, save the conn
+            final JDBCStorageConnection conn = (JDBCStorageConnection)dataContainer.openConnection();
+            apply(modifications, conn);
+            transactions.put(tx, conn);
+         }
+      }*/
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void commit(Object tx) throws Exception
+   {
+      /*final WorkspaceStorageConnection conn = transactions.remove(tx);
+      if (conn == null)
+      {
+         throw new RepositoryException("Transaction " + tx + " not found in transaction table.");
+      }
+
+      conn.commit();*/
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void rollback(Object tx)
+   {
+      /*final WorkspaceStorageConnection conn = transactions.remove(tx);
+      if (conn != null)
+      {
+         try
+         {
+            conn.rollback();
+         }
+         catch (Throwable e)
+         {
+            // TODO why we cannot throw an exception??? (throws Exception expected)
+            LOG.error("Error of transaction " + tx + " rollback.", e);
+         }
+      }
+      else
+      {
+         LOG.warn("Transaction " + tx + " not found in transaction table, but rollback called.");
+      }*/
+   }
+
+   // SHOULD NOT BE USED methods
+
+   /**
+    * {@inheritDoc}
+    */
+   public Object put(Fqn name, Object key, Object value) throws Exception
+   {
+      LOG.error("The method 'put(Fqn name, Object key, Object value))' should not be called. " + name + " " + key + " "
+         + value);
+      throw new JDBCCacheLoaderException("The method 'put(Fqn name, Object key, Object value))' should not be called.");
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void put(Fqn name, Map<Object, Object> attributes) throws Exception
+   {
+      LOG.error("The method 'put(Fqn name, Map<Object, Object> attributes)' should not be called. " + name + " "
+         + attributes);
+      throw new JDBCCacheLoaderException(
+         "The method 'put(Fqn name, Map<Object, Object> attributes)' should not be called.");
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public Object remove(Fqn fqn, Object key) throws Exception
+   {
+      LOG.error("The method 'remove(Fqn fqn, Object key)' should not be called. " + fqn + " " + key);
+      throw new JDBCCacheLoaderException("The method 'remove(Fqn fqn, Object key)' should not be called.");
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void remove(Fqn fqn) throws Exception
+   {
+      LOG.error("The method 'remove(Fqn fqn)' should not be called. " + fqn);
+      throw new JDBCCacheLoaderException("The method 'remove(Fqn fqn)' should not be called.");
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void removeData(Fqn fqn) throws Exception
+   {
+      LOG.error("The method 'removeData(Fqn fqn)' should not be called. " + fqn);
+      throw new JDBCCacheLoaderException("The method 'removeData(Fqn fqn)' should not be called.");
+   }
+
 }
\ No newline at end of file



More information about the exo-jcr-commits mailing list