[exo-jcr-commits] exo-jcr SVN: r4718 - in jcr/branches/1.12.x/patch/1.12.10-GA: JCR-1633 and 1 other directory.

do-not-reply at jboss.org do-not-reply at jboss.org
Tue Aug 9 08:00:30 EDT 2011


Author: areshetnyak
Date: 2011-08-09 08:00:30 -0400 (Tue, 09 Aug 2011)
New Revision: 4718

Added:
   jcr/branches/1.12.x/patch/1.12.10-GA/JCR-1633/
   jcr/branches/1.12.x/patch/1.12.10-GA/JCR-1633/JCR-1633.patch
Log:
JCR-1633 : Patch for allow to keep missing values into the JCR Cache was commited

Added: jcr/branches/1.12.x/patch/1.12.10-GA/JCR-1633/JCR-1633.patch
===================================================================
--- jcr/branches/1.12.x/patch/1.12.10-GA/JCR-1633/JCR-1633.patch	                        (rev 0)
+++ jcr/branches/1.12.x/patch/1.12.10-GA/JCR-1633/JCR-1633.patch	2011-08-09 12:00:30 UTC (rev 4718)
@@ -0,0 +1,655 @@
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java	(revision 4692)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java	(working copy)
+@@ -28,6 +28,7 @@
+ import org.exoplatform.services.jcr.datamodel.ItemData;
+ import org.exoplatform.services.jcr.datamodel.ItemType;
+ import org.exoplatform.services.jcr.datamodel.NodeData;
++import org.exoplatform.services.jcr.datamodel.NullItemData;
+ import org.exoplatform.services.jcr.datamodel.PropertyData;
+ import org.exoplatform.services.jcr.datamodel.QPath;
+ import org.exoplatform.services.jcr.datamodel.QPathEntry;
+@@ -157,14 +158,14 @@
+    {
+       // from cache at first
+       ItemData cdata = persistentManager.getCachedItemData(identifier);
+-      if (cdata != null)
++      if (cdata != null && !(cdata instanceof NullItemData))
+          return super.getItemData(identifier);
+ 
+       if (!this.equals(versionDataManager) && !identifier.equals(Constants.ROOT_UUID))
+       {
+          // search in System cache for /jcr:system nodes only
+          cdata = versionDataManager.persistentManager.getCachedItemData(identifier);
+-         if (cdata != null)
++         if (cdata != null && !(cdata instanceof NullItemData))
+             if (isSystemDescendant(cdata.getQPath()))
+                return versionDataManager.getItemData(identifier);
+             else
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java	(revision 4692)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java	(working copy)
+@@ -30,6 +30,9 @@
+ import org.exoplatform.services.jcr.datamodel.ItemData;
+ import org.exoplatform.services.jcr.datamodel.ItemType;
+ import org.exoplatform.services.jcr.datamodel.NodeData;
++import org.exoplatform.services.jcr.datamodel.NullItemData;
++import org.exoplatform.services.jcr.datamodel.NullNodeData;
++import org.exoplatform.services.jcr.datamodel.NullPropertyData;
+ import org.exoplatform.services.jcr.datamodel.PropertyData;
+ import org.exoplatform.services.jcr.datamodel.QPath;
+ import org.exoplatform.services.jcr.datamodel.QPathEntry;
+@@ -396,6 +399,13 @@
+     */
+    public void put(ItemData item)
+    {
++      // There is different commit processing for NullNodeData and ordinary ItemData
++      if (item instanceof NullItemData)
++      {
++         putNullItem((NullItemData)item);
++         return;
++      }
++
+       boolean inTransaction = cache.isTransactionActive();
+       try
+       {
+@@ -507,7 +517,7 @@
+          for (String propId : set)
+          {
+             PropertyData prop = (PropertyData)cache.get(makeItemFqn(propId), ITEM_DATA);
+-            if (prop == null)
++            if (prop == null || prop instanceof NullItemData)
+             {
+                return null;
+             }
+@@ -680,23 +690,48 @@
+    public ItemData get(String parentId, QPathEntry name, ItemType itemType)
+    {
+       String itemId = null;
+-      if (itemType == ItemType.NODE || itemType == ItemType.UNKNOWN)
++      if (itemType == ItemType.UNKNOWN)
+       {
+-         // try as node first
++         // Try as node first.
+          itemId = (String)cache.get(makeChildFqn(childNodes, parentId, name), ITEM_ID);
++
++         if (itemId == null || itemId.equals(NullItemData.NULL_ID))
++         {
++            // node with such a name is not found or marked as not-exist, so check the properties
++            String propId = (String)cache.get(makeChildFqn(childProps, parentId, name), ITEM_ID);
++            if (propId != null)
++            {
++               itemId = propId;
++            }
++         }
+       }
+-
+-      if (itemType == ItemType.PROPERTY || itemType == ItemType.UNKNOWN && itemId == null)
++      else if (itemType == ItemType.NODE)
+       {
+-         // try as property
++         itemId = (String)cache.get(makeChildFqn(childNodes, parentId, name), ITEM_ID);
++      }
++      else
++      {
+          itemId = (String)cache.get(makeChildFqn(childProps, parentId, name), ITEM_ID);
+       }
+ 
+       if (itemId != null)
+       {
+-         return get(itemId);
++         if (itemId.equals(NullItemData.NULL_ID))
++         {
++            if (itemType == ItemType.UNKNOWN || itemType == ItemType.NODE)
++            {
++               return new NullNodeData();
++            }
++            else
++            {
++               return new NullPropertyData();
++            }
++         }
++         else
++         {
++            return get(itemId);
++         }
+       }
+-
+       return null;
+    }
+ 
+@@ -705,6 +740,7 @@
+     */
+    public ItemData get(String id)
+    {
++      // NullNodeData with id may be stored as ordinary NodeData or PropertyData
+       return (ItemData)cache.get(makeItemFqn(id), ITEM_DATA);
+    }
+ 
+@@ -723,7 +759,7 @@
+          for (Object child : set)
+          {
+             NodeData node = (NodeData)cache.get(makeItemFqn((String)child), ITEM_DATA);
+-            if (node == null)
++            if (node == null || node instanceof NullItemData)
+             {
+                return null;
+             }
+@@ -788,7 +824,7 @@
+          for (Object child : set)
+          {
+             PropertyData prop = (PropertyData)cache.get(makeItemFqn((String)child), ITEM_DATA);
+-            if (prop == null)
++            if (prop == null || prop instanceof NullItemData)
+             {
+                return null;
+             }
+@@ -944,6 +980,54 @@
+          modifyListsOfChild == ModifyChildOption.NOT_MODIFY);
+    }
+ 
++   /**
++    * Internal put NullNode.
++    *
++    * @param item, NullItemData, new data to put in the cache
++    */
++   protected void putNullItem(NullItemData item)
++   {
++      boolean inTransaction = cache.isTransactionActive();
++      try
++      {
++         if (!inTransaction)
++         {
++            cache.beginTransaction();
++         }
++         cache.setLocal(true);
++
++         if (!item.getIdentifier().equals(NullItemData.NULL_ID))
++         {
++            //put in $ITEMS
++            cache.putIfAbsent(makeItemFqn(item.getIdentifier()), ITEM_DATA, item);
++         }
++         else if (item.getName() != null && item.getParentIdentifier() != null)
++         {
++            if (item.isNode())
++            {
++               // put in $CHILD_NODES
++               cache.putIfAbsent(makeChildFqn(childNodes, item.getParentIdentifier(), item.getName()), ITEM_ID,
++                  NullItemData.NULL_ID);
++            }
++            else
++            {
++               // put in $CHILD_PROPERTIES
++               cache.putIfAbsent(makeChildFqn(childProps, item.getParentIdentifier(), item.getName()), ITEM_ID,
++                  NullItemData.NULL_ID);
++            }
++         }
++      }
++      finally
++      {
++         cache.setLocal(false);
++         if (!inTransaction)
++         {
++            dedicatedTxCommit();
++         }
++      }
++
++   }
++
+    protected ItemData putNodeInBufferedCache(NodeData node, ModifyChildOption modifyListsOfChild)
+    {
+       // if not a root node
+@@ -960,7 +1044,9 @@
+          }
+       }
+       // add in ITEMS
+-      return (ItemData)cache.putInBuffer(makeItemFqn(node.getIdentifier()), ITEM_DATA, node);
++      // NullNodeData must never be returned inside internal cache operations. 
++      ItemData returnedData = (ItemData)cache.putInBuffer(makeItemFqn(node.getIdentifier()), ITEM_DATA, node);
++      return (returnedData instanceof NullItemData) ? null : returnedData;
+    }
+ 
+    /**
+@@ -1008,8 +1094,11 @@
+       }
+ 
+       // add in ITEMS
+-      return (PropertyData)cache.put(makeItemFqn(prop.getIdentifier()), ITEM_DATA, prop,
+-         modifyListsOfChild == ModifyChildOption.NOT_MODIFY);
++      // NullItemData must never be returned inside internal cache operations. 
++      ItemData returnedData =
++         (ItemData)cache.put(makeItemFqn(prop.getIdentifier()), ITEM_DATA, prop,
++            modifyListsOfChild == ModifyChildOption.NOT_MODIFY);
++      return (returnedData instanceof NullItemData) ? null : (PropertyData)returnedData;
+    }
+ 
+    protected void removeItem(ItemData item)
+@@ -1065,7 +1154,8 @@
+    protected void updateMixin(NodeData node)
+    {
+       NodeData prevData = (NodeData)cache.put(makeItemFqn(node.getIdentifier()), ITEM_DATA, node);
+-      if (prevData != null)
++      // prevent update NullNodeData
++      if (prevData != null && !(prevData instanceof NullItemData))
+       {
+          // do update ACL if needed
+          if (prevData.getACL() == null || !prevData.getACL().equals(node.getACL()))
+@@ -1119,6 +1209,7 @@
+     */
+    protected void updateInBuffer(final NodeData node, final NodeData prevNode)
+    {
++      // I expect that NullNodeData will never update existing NodeData.
+       // get previously cached NodeData and using its name remove child on the parent
+       Fqn<String> prevFqn =
+          makeChildFqn(childNodes, node.getParentIdentifier(), prevNode.getQPath().getEntries()[prevNode.getQPath()
+@@ -1132,6 +1223,7 @@
+          }
+       }
+ 
++      // node and prevNode are not NullNodeDatas
+       // update childs paths if index changed
+       int nodeIndex = node.getQPath().getEntries()[node.getQPath().getEntries().length - 1].getIndex();
+       int prevNodeIndex = prevNode.getQPath().getEntries()[prevNode.getQPath().getEntries().length - 1].getIndex();
+@@ -1165,7 +1257,7 @@
+ 
+          // check is this descendant of prevRootPath
+          QPath nodeQPath = data.getQPath();
+-         if (nodeQPath.isDescendantOf(prevRootPath))
++         if (nodeQPath != null && nodeQPath.isDescendantOf(prevRootPath))
+          {
+ 
+             //make relative path
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java	(revision 4692)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java	(working copy)
+@@ -23,6 +23,9 @@
+ import org.exoplatform.services.jcr.datamodel.ItemData;
+ import org.exoplatform.services.jcr.datamodel.ItemType;
+ import org.exoplatform.services.jcr.datamodel.NodeData;
++import org.exoplatform.services.jcr.datamodel.NullItemData;
++import org.exoplatform.services.jcr.datamodel.NullNodeData;
++import org.exoplatform.services.jcr.datamodel.NullPropertyData;
+ import org.exoplatform.services.jcr.datamodel.PropertyData;
+ import org.exoplatform.services.jcr.datamodel.QPathEntry;
+ import org.exoplatform.services.jcr.datamodel.ValueData;
+@@ -418,18 +421,20 @@
+             {
+                data = getPersistedItemData(parentData, name, itemType);
+             }
+-            else if (!data.isNode())
+-            {
+-               fixPropertyValues((PropertyData)data);
+-            }
+          }
+          finally
+          {
+             request.done();
+          }
+       }
+-      else if (!data.isNode())
++
++      if (data instanceof NullItemData)
+       {
++         return null;
++      }
++
++      if (data != null && !data.isNode())
++      {
+          fixPropertyValues((PropertyData)data);
+       }
+ 
+@@ -460,18 +465,20 @@
+             {
+                data = getPersistedItemData(identifier);
+             }
+-            else if (!data.isNode())
+-            {
+-               fixPropertyValues((PropertyData)data);
+-            }
+          }
+          finally
+          {
+             request.done();
+          }
+       }
+-      else if (!data.isNode())
++
++      if (data instanceof NullItemData)
+       {
++         return null;
++      }
++
++      if (data != null && !data.isNode())
++      {
+          fixPropertyValues((PropertyData)data);
+       }
+ 
+@@ -749,9 +756,23 @@
+       throws RepositoryException
+    {
+       ItemData data = super.getItemData(parentData, name, itemType);
+-      if (data != null && cache.isEnabled())
++      if (cache.isEnabled())
+       {
+-         cache.put(data);
++         if (data == null)
++         {
++            if (itemType == ItemType.NODE || itemType == ItemType.UNKNOWN)
++            {
++               cache.put(new NullNodeData(parentData, name));
++            }
++            else
++            {
++               cache.put(new NullPropertyData(parentData, name));
++            }
++         }
++         else
++         {
++            cache.put(data);
++         }
+       }
+       return data;
+    }
+@@ -766,9 +787,17 @@
+    protected ItemData getPersistedItemData(String identifier) throws RepositoryException
+    {
+       ItemData data = super.getItemData(identifier);
+-      if (data != null && cache.isEnabled())
++      if (cache.isEnabled())
+       {
+-         cache.put(data);
++         if (data != null)
++         {
++            cache.put(data);
++         }
++         else if (identifier != null)
++         {
++            // no matter does property or node expected - store NullNodeData
++            cache.put(new NullNodeData(identifier));
++         }
+       }
+       return data;
+    }
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/NullPropertyData.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/NullPropertyData.java	(revision 0)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/NullPropertyData.java	(revision 0)
+@@ -0,0 +1,79 @@
++/*
++ * Copyright (C) 2003-2010 eXo Platform SAS.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Affero General Public License
++ * as published by the Free Software Foundation; either version 3
++ * of the License, or (at your option) any later version.
++ *
++ * This program 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 General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see<http://www.gnu.org/licenses/>.
++ */
++package org.exoplatform.services.jcr.datamodel;
++
++import java.util.List;
++
++/**
++ * Created by The eXo Platform SAS.
++ * 
++ * <br/>Date: 
++ *
++ * @author <a href="karpenko.sergiy at gmail.com">Karpenko Sergiy</a> 
++ * @version $Id: NullPropertyData.java 111 2011-05-30 11:11:11Z serg $
++ */
++public class NullPropertyData extends NullItemData implements PropertyData
++{
++
++   public NullPropertyData(NodeData parent, QPathEntry name)
++   {
++      super(parent, name);
++   }
++
++   public NullPropertyData(String id)
++   {
++      super(id);
++   }
++
++   public NullPropertyData()
++   {
++      super();
++   }
++
++   /**
++    * {@inheritDoc}
++    */
++   public int getType()
++   {
++      throw new UnsupportedOperationException("Method is not supported");
++   }
++
++   /**
++    * {@inheritDoc}
++    */
++   public List<ValueData> getValues()
++   {
++      throw new UnsupportedOperationException("Method is not supported");
++   }
++
++   /**
++    * {@inheritDoc}
++    */
++   public boolean isMultiValued()
++   {
++      throw new UnsupportedOperationException("Method is not supported");
++   }
++
++   /**
++    * {@inheritDoc}
++    */
++   public boolean isNode()
++   {
++      return false;
++   }
++
++}
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/NullNodeData.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/NullNodeData.java	(revision 0)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/NullNodeData.java	(revision 0)
+@@ -0,0 +1,88 @@
++/*
++ * Copyright (C) 2010 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.datamodel;
++
++import org.exoplatform.services.jcr.access.AccessControlList;
++
++/**
++ * This class is used to represent <code>null</code> value, it is designed to be used  
++ * into the cache to represent missing value.
++ * 
++ * @author <a href="anatoliy.bazko at exoplatform.org">Anatoliy Bazko</a>
++ * @version $Id: NullNodeData.java 111 2011-05-30 11:11:11Z tolusha $
++ */
++public class NullNodeData extends NullItemData implements NodeData
++{
++
++   public NullNodeData(NodeData parent, QPathEntry name)
++   {
++      super(parent, name);
++   }
++
++   public NullNodeData(String id)
++   {
++      super(id);
++   }
++
++   public NullNodeData()
++   {
++      super();
++   }
++
++   /**
++    * {@inheritDoc}
++    */
++   public boolean isNode()
++   {
++      return true;
++   }
++
++   /**
++    * {@inheritDoc}
++    */
++   public AccessControlList getACL()
++   {
++      throw new UnsupportedOperationException("Method is not supported");
++   }
++
++   /**
++    * {@inheritDoc}
++    */
++   public InternalQName[] getMixinTypeNames()
++   {
++      throw new UnsupportedOperationException("Method is not supported");
++   }
++
++   /**
++    * {@inheritDoc}
++    */
++   public int getOrderNumber()
++   {
++      throw new UnsupportedOperationException("Method is not supported");
++   }
++
++   /**
++    * {@inheritDoc}
++    */
++   public InternalQName getPrimaryTypeName()
++   {
++      throw new UnsupportedOperationException("Method is not supported");
++   }
++
++}
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/NullItemData.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/NullItemData.java	(revision 0)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/NullItemData.java	(revision 0)
+@@ -0,0 +1,98 @@
++/*
++ * Copyright (C) 2003-2010 eXo Platform SAS.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Affero General Public License
++ * as published by the Free Software Foundation; either version 3
++ * of the License, or (at your option) any later version.
++ *
++ * This program 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 General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see<http://www.gnu.org/licenses/>.
++ */
++package org.exoplatform.services.jcr.datamodel;
++
++import org.exoplatform.services.jcr.dataflow.ItemDataVisitor;
++
++import javax.jcr.RepositoryException;
++
++/**
++ * Created by The eXo Platform SAS.
++ * 
++ * <br/>Date: 
++ *
++ * @author <a href="karpenko.sergiy at gmail.com">Karpenko Sergiy</a> 
++ * @version $Id: NullItemData.java 111 2011-05-30 11:11:11Z serg $
++ */
++public abstract class NullItemData implements ItemData
++{
++
++   public static final String NULL_ID = "_null_id";
++
++   private final String id;
++
++   private final String parentId;
++
++   private final QPathEntry name;
++
++   private final QPath path;
++
++   public NullItemData(NodeData parent, QPathEntry name)
++   {
++      this.parentId = parent.getIdentifier();
++      this.path = QPath.makeChildPath(parent.getQPath(), name);
++      this.name = name;
++      this.id = NULL_ID;
++   }
++
++   public NullItemData(String id)
++   {
++      this.parentId = null;
++      this.path = null;
++      this.name = null;
++      this.id = id;
++   }
++
++   public NullItemData()
++   {
++      this.parentId = null;
++      this.path = null;
++      this.name = null;
++      this.id = NULL_ID;
++   }
++
++   public void accept(ItemDataVisitor visitor) throws RepositoryException
++   {
++      throw new UnsupportedOperationException("Method is not supported");
++   }
++
++   public String getIdentifier()
++   {
++      return id;
++   }
++
++   public String getParentIdentifier()
++   {
++      return parentId;
++   }
++
++   public int getPersistedVersion()
++   {
++      throw new UnsupportedOperationException("Method is not supported");
++   }
++
++   public QPath getQPath()
++   {
++      return path;
++   }
++
++   public QPathEntry getName()
++   {
++      return name;
++   }
++
++}



More information about the exo-jcr-commits mailing list