[exo-jcr-commits] exo-jcr SVN: r1302 - in jcr/branches/1.12.0-OPT/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/impl/core/itemfilters and 6 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Tue Jan 5 12:49:40 EST 2010


Author: pnedonosko
Date: 2010-01-05 12:49:40 -0500 (Tue, 05 Jan 2010)
New Revision: 1302

Added:
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/itemfilters/ItemDataFilter.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/itemfilters/ItemDataNamePatternFilter.java
Modified:
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ItemImpl.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/PropertyImpl.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/observation/ActionLauncher.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionHistoryImpl.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/DefaultItemDataCopyVisitor.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/ItemDataCloneVisitor.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/EntityCollection.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/NodeIteratorOnDemand.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/xml/exporting/BaseXmlExporter.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/load/TestJira282.java
Log:
EXOJCR-359 Reduce amount of NodeImpl created on read operations + lazy child items refactoring (EXOJCR-338)

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ItemImpl.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ItemImpl.java	2010-01-05 17:43:15 UTC (rev 1301)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ItemImpl.java	2010-01-05 17:49:40 UTC (rev 1302)
@@ -706,8 +706,11 @@
    {
       NodeImpl parent = (NodeImpl)item(getParentIdentifier());
       if (parent == null)
+      {
          throw new ItemNotFoundException("FATAL: Parent is null for " + getPath() + " parent UUID: "
             + getParentIdentifier());
+      }
+
       return parent;
    }
 
@@ -722,8 +725,11 @@
    {
       NodeData parent = (NodeData)dataManager.getItemData(getData().getParentIdentifier());
       if (parent == null)
+      {
          throw new ItemNotFoundException("FATAL: Parent is null for " + getPath() + " parent UUID: "
             + getData().getParentIdentifier());
+      }
+
       return parent;
    }
 
@@ -778,7 +784,7 @@
    }
 
    /**
-    * Loads data
+    * Loads data.
     *
     * @param data
     *          source item data
@@ -788,6 +794,18 @@
    abstract void loadData(ItemData data) throws RepositoryException;
 
    /**
+    * Loads data using existing parent data (used primary and mixin types for Item Definition discovery).
+    *
+    * @param data
+    *          source item data
+    * @param parent NodeData 
+    *          Items's parent
+    * @throws RepositoryException 
+    *          if errors occurs
+    */
+   abstract void loadData(ItemData data, NodeData parent) throws RepositoryException;
+
+   /**
     * Loads data.
     *
     * @param data
@@ -811,11 +829,13 @@
    {
       NodeData ndata;
       if (isNode())
+      {
          ndata = (NodeData)getData();
+      }
       else
-         ndata = parentData(); // (NodeData)
-      // dataManager.getItemData(data.getParentIdentifier
-      // ())
+      {
+         ndata = parentData();
+      }
 
       return session.getAccessManager().hasPermission(ndata.getACL(), action, session.getUserState().getIdentity());
    }

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java	2010-01-05 17:43:15 UTC (rev 1301)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java	2010-01-05 17:49:40 UTC (rev 1302)
@@ -42,7 +42,8 @@
 import org.exoplatform.services.jcr.datamodel.QPathEntry;
 import org.exoplatform.services.jcr.datamodel.ValueData;
 import org.exoplatform.services.jcr.impl.Constants;
-import org.exoplatform.services.jcr.impl.core.itemfilters.ItemFilter;
+import org.exoplatform.services.jcr.impl.core.itemfilters.ItemDataFilter;
+import org.exoplatform.services.jcr.impl.core.itemfilters.ItemDataNamePatternFilter;
 import org.exoplatform.services.jcr.impl.core.itemfilters.NamePatternFilter;
 import org.exoplatform.services.jcr.impl.core.lock.LockImpl;
 import org.exoplatform.services.jcr.impl.core.nodetype.ItemAutocreator;
@@ -58,7 +59,6 @@
 import org.exoplatform.services.jcr.impl.dataflow.session.SessionChangesLog;
 import org.exoplatform.services.jcr.impl.dataflow.session.TransactionableDataManager;
 import org.exoplatform.services.jcr.impl.util.EntityCollection;
-import org.exoplatform.services.jcr.impl.util.NodeIteratorOnDemand;
 import org.exoplatform.services.jcr.observation.ExtendedEvent;
 import org.exoplatform.services.jcr.util.IdGenerator;
 import org.exoplatform.services.log.ExoLogger;
@@ -75,6 +75,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.NoSuchElementException;
 
 import javax.jcr.AccessDeniedException;
 import javax.jcr.InvalidItemStateException;
@@ -90,6 +91,7 @@
 import javax.jcr.Property;
 import javax.jcr.PropertyIterator;
 import javax.jcr.PropertyType;
+import javax.jcr.RangeIterator;
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.Value;
@@ -156,7 +158,7 @@
     * 
     * @param data
     *          Node data
-    * @param parent parent NodeData 
+    * @param parent NodeData Nodes's parent 
     * @param session   
     *          Session
     * @throws RepositoryException
@@ -166,7 +168,7 @@
    {
       super(data, session);
       this.sysLocFactory = session.getSystemLocationFactory();
-      loadNodeData(data, parent);
+      loadData(data, parent);
    }
 
    /**
@@ -482,7 +484,9 @@
       checkValid();
 
       if (!session.getAccessManager().hasPermission(getACL(), actions, session.getUserState().getIdentity()))
+      {
          throw new AccessControlException("Permission denied " + getPath() + " : " + actions);
+      }
    }
 
    /**
@@ -494,7 +498,8 @@
     * @throws AccessDeniedException
     *           if Nodes cannot be listed due to permissions on this Node
     */
-   public List<NodeImpl> childNodes() throws RepositoryException, AccessDeniedException
+   @Deprecated
+   private List<NodeImpl> childNodes() throws RepositoryException, AccessDeniedException
    {
 
       List<NodeImpl> storedNodes = dataManager.getChildNodes(nodeData(), true);
@@ -511,7 +516,8 @@
     * @throws AccessDeniedException
     *           if Properties cannot be listed due to permissions on this Node
     */
-   public List<PropertyImpl> childProperties() throws RepositoryException, AccessDeniedException
+   @Deprecated
+   private List<PropertyImpl> childProperties() throws RepositoryException, AccessDeniedException
    {
 
       List<PropertyImpl> storedProperties = dataManager.getChildProperties(nodeData(), true);
@@ -801,7 +807,9 @@
       {
          NodeData corrNode = (NodeData)corrDataManager.getItemData(getUUID());
          if (corrNode != null)
+         {
             return corrNode;
+         }
       }
       else
       {
@@ -826,7 +834,9 @@
       }
       NodeData corrNode = (NodeData)corrDataManager.getItemData(myPath);
       if (corrNode != null)
+      {
          return corrNode;
+      }
 
       throw new ItemNotFoundException("No corresponding path for " + getPath() + " in "
          + corrSession.getWorkspace().getName());
@@ -886,7 +896,10 @@
                   .getMixinTypeNames());
 
             if (definition == null)
+            {
                throw new ConstraintViolationException("Node definition not found for " + getPath());
+            }
+
             // TODO same functionality in NodeTypeImpl
             InternalQName[] rnames = definition.getRequiredPrimaryTypes();
             NodeType[] rnts = new NodeType[rnames.length];
@@ -898,7 +911,6 @@
             nodeDefinition =
                new NodeDefinitionImpl(definition, nodeTypesHolder, nodeTypeManager, sysLocFactory, session
                   .getValueFactory());
-
          }
       }
 
@@ -927,7 +939,10 @@
 
       LockImpl lock = session.getLockManager().getLock(this);
       if (lock == null)
+      {
          throw new LockException("Lock not found " + getPath());
+      }
+
       return lock;
 
    }
@@ -942,7 +957,9 @@
 
       // should not be null
       if (nodeData().getMixinTypeNames() == null)
+      {
          throw new RepositoryException("Data Container implementation error getMixinTypeNames == null");
+      }
 
       ExtendedNodeTypeManager nodeTypeManager = (ExtendedNodeTypeManager)session.getWorkspace().getNodeTypeManager();
       NodeType[] mixinNodeTypes = new NodeType[nodeData().getMixinTypeNames().length];
@@ -966,7 +983,10 @@
       NodeType[] mixinTypes = getMixinNodeTypes();
       String[] mtNames = new String[mixinTypes.length];
       for (int i = 0; i < mtNames.length; i++)
+      {
          mtNames[i] = mixinTypes[i].getName();
+      }
+
       return mtNames;
    }
 
@@ -982,8 +1002,11 @@
 
       ItemImpl node = dataManager.getItem(nodeData(), itemPath.getInternalPath().getEntries(), true);
       if (node == null || !node.isNode())
+      {
          throw new PathNotFoundException("Node not found " + (isRoot() ? "" : getLocation().getAsString(false)) + "/"
             + itemPath.getAsString(false));
+      }
+
       return (NodeImpl)node;
    }
 
@@ -993,6 +1016,7 @@
    public String getIdentifier() throws RepositoryException
    {
       checkValid();
+
       return this.getInternalIdentifier();
    }
 
@@ -1004,17 +1028,25 @@
 
       long start = System.currentTimeMillis();
       if (LOG.isDebugEnabled())
+      {
          LOG.debug("getNodes() >>>>>");
+      }
 
       checkValid();
       try
       {
-         return new NodeIteratorOnDemand(childNodesData(), dataManager, nodeData());
+         // TODO full iterator code
+         // return new EntityCollection(childNodes());
+
+         // lazy childs
+         return new LazyNodeIterator(childNodesData());
       }
       finally
       {
          if (LOG.isDebugEnabled())
+         {
             LOG.debug("getNodes() <<<<< " + ((System.currentTimeMillis() - start) / 1000d) + "sec");
+         }
       }
    }
 
@@ -1026,25 +1058,35 @@
 
       long start = System.currentTimeMillis();
       if (LOG.isDebugEnabled())
+      {
          LOG.debug("getNodes(String) >>>>>");
+      }
 
       checkValid();
 
       try
       {
-         ItemFilter filter = new NamePatternFilter(namePattern);
-         ArrayList<NodeImpl> list = new ArrayList<NodeImpl>();
-         for (NodeImpl item : childNodes())
-         {
-            if (filter.accept(item))
-               list.add(item);
-         }
-         return new EntityCollection(list);
+         // TODO full iterator code
+         //         ItemFilter filter = new NamePatternFilter(namePattern);
+         //         ArrayList<NodeImpl> list = new ArrayList<NodeImpl>();
+         //         for (NodeImpl item : childNodes())
+         //         {
+         //            if (filter.accept(item))
+         //            {
+         //               list.add(item);
+         //            }
+         //         }
+         //         return new EntityCollection(list);
+
+         // lazy childs
+         return new LazyNodeIterator(childNodesData(), new ItemDataNamePatternFilter(namePattern, session));
       }
       finally
       {
          if (LOG.isDebugEnabled())
+         {
             LOG.debug("getNodes(String) <<<<< " + ((System.currentTimeMillis() - start) / 1000d) + "sec");
+         }
       }
    }
 
@@ -1107,12 +1149,18 @@
 
       try
       {
-         return new EntityCollection(childProperties());
+         // TODO full iterator code
+         // return new EntityCollection(childProperties());
+
+         // lazy childs
+         return new LazyPropertyIterator(childPropertiesData());
       }
       finally
       {
          if (LOG.isDebugEnabled())
+         {
             LOG.debug("getProperties() <<<<< " + ((System.currentTimeMillis() - start) / 1000d) + "sec");
+         }
       }
    }
 
@@ -1130,20 +1178,26 @@
 
       try
       {
-         ItemFilter filter = new NamePatternFilter(namePattern);
-         ArrayList<PropertyImpl> list = new ArrayList<PropertyImpl>();
-         for (PropertyImpl item : childProperties())
-         {
-            if (filter.accept(item))
-               list.add(item);
-         }
+         // TODO full iterator code
+         //         ItemFilter filter = new NamePatternFilter(namePattern);
+         //         ArrayList<PropertyImpl> list = new ArrayList<PropertyImpl>();
+         //         for (PropertyImpl item : childProperties())
+         //         {
+         //            if (filter.accept(item))
+         //               list.add(item);
+         //         }
+         //
+         //         return new EntityCollection(list);
 
-         return new EntityCollection(list);
+         // lazy childs
+         return new LazyPropertyIterator(childPropertiesData(), new ItemDataNamePatternFilter(namePattern, session));
       }
       finally
       {
          if (LOG.isDebugEnabled())
+         {
             LOG.debug("getProperties(String) <<<<< " + ((System.currentTimeMillis() - start) / 1000d) + "sec");
+         }
       }
    }
 
@@ -1364,18 +1418,23 @@
    public void loadData(ItemData data) throws RepositoryException, InvalidItemStateException,
       ConstraintViolationException
    {
-      loadNodeData(data, null);
+      loadData(data, (NodeData)null);
    }
 
-   private void loadNodeData(ItemData data, NodeData parent) throws RepositoryException, InvalidItemStateException,
+   /**
+    * {@inheritDoc}
+    */
+   public void loadData(ItemData data, NodeData parent) throws RepositoryException, InvalidItemStateException,
       ConstraintViolationException
    {
-      if (data == null)
-      {
-         throw new InvalidItemStateException("Data is null for " + this.getPath()
-            + " Probably was deleted by another session and can not be loaded from container ");
-      }
 
+      // TODO
+      //      if (data == null)
+      //      {
+      //         throw new InvalidItemStateException("Data is null for " + this.getPath()
+      //            + " Probably was deleted by another session and can not be loaded from container ");
+      //      }
+
       if (data.isNode())
       {
          NodeData nodeData = (NodeData)data;
@@ -2316,10 +2375,14 @@
    protected void doOrderBefore(QPath srcPath, QPath destPath) throws RepositoryException
    {
       if (!getPrimaryNodeType().hasOrderableChildNodes())
+      {
          throw new UnsupportedRepositoryOperationException("child node ordering not supported on node " + getPath());
+      }
 
       if (srcPath.equals(destPath))
+      {
          return;
+      }
 
       // check existence
       if (dataManager.getItemData(srcPath) == null)
@@ -2334,17 +2397,24 @@
       }
 
       if (!checkedOut())
+      {
          throw new VersionException(" cannot change child node ordering of a checked-in node ");
+      }
 
       if (destPath != null && srcPath.getDepth() != destPath.getDepth())
+      {
          throw new ItemNotFoundException("Source and destenation is not relative paths of depth one, "
             + "i.e. is not a childs of same parent node");
+      }
 
-      List<NodeData> siblings = dataManager.getChildNodesData(nodeData());
-      Collections.sort(siblings, new NodeDataOrderComparator());
+      List<NodeData> siblings = new ArrayList<NodeData>(dataManager.getChildNodesData(nodeData()));
       if (siblings.size() < 2)
+      {
          throw new UnsupportedRepositoryOperationException("Nothing to order Count of child nodes " + siblings.size());
+      }
 
+      Collections.sort(siblings, new NodeDataOrderComparator());
+
       // calculating source and destination position
       int srcInd = -1, destInd = -1;
       for (int i = 0; i < siblings.size(); i++)
@@ -2572,6 +2642,26 @@
    }
 
    /**
+    * Return child Properties list.
+    * 
+    * @return List of child Properties
+    * @throws RepositoryException
+    *           if error occurs
+    * @throws AccessDeniedException
+    *           if Nodes cannot be listed due to permissions on this Node
+    */
+   private List<PropertyData> childPropertiesData() throws RepositoryException, AccessDeniedException
+   {
+
+      List<PropertyData> storedProps = new ArrayList<PropertyData>(dataManager.getChildPropertiesData(nodeData()));
+
+      // TODO we should not sort here!
+      Collections.sort(storedProps, new PropertiesDataOrderComparator<PropertyData>());
+
+      return storedProps;
+   }
+
+   /**
     * Return child Nodes list.
     * 
     * @return List of child Nodes
@@ -2580,34 +2670,41 @@
     * @throws AccessDeniedException
     *           if Nodes cannot be listed due to permissions on this Node
     */
-   private List<Object> childNodesData() throws RepositoryException, AccessDeniedException
+   private List<NodeData> childNodesData() throws RepositoryException, AccessDeniedException
    {
-      List<NodeData> storedNodes = dataManager.getChildNodesData(nodeData());
-      Collections.sort(storedNodes, new NodeDataOrderComparator());
 
-      List<Object> results = new ArrayList<Object>(storedNodes.size());
+      //List<NodeData> storedNodes = dataManager.getChildNodesData(nodeData());
+      List<NodeData> storedNodes = new ArrayList<NodeData>(dataManager.getChildNodesData(nodeData()));
 
-      Iterator<NodeData> it = storedNodes.iterator();
-      while (it.hasNext())
-      {
-         NodeData node = it.next();
+      // TODO we should not sort here!
+      Collections.sort(storedNodes, new NodeDataOrderComparator());
 
-         if (session.getAccessManager().hasPermission(node.getACL(), new String[]{PermissionType.READ},
-            session.getUserState().getIdentity()))
-         {
-            ItemImpl pooled = dataManager.reloadItem(node);
-            if (pooled != null)
-            {
-               results.add(pooled);
-            }
-            else
-            {
-               results.add(node);
-            }
-         }
-      }
+      return storedNodes;
 
-      return results;
+      // TODO cleanup
+      //      List<Object> results = new ArrayList<Object>(storedNodes.size());
+      //
+      //      Iterator<NodeData> it = storedNodes.iterator();
+      //      while (it.hasNext())
+      //      {
+      //         NodeData node = it.next();
+      //
+      //         if (session.getAccessManager().hasPermission(node.getACL(), new String[]{PermissionType.READ},
+      //            session.getUserState().getIdentity()))
+      //         {
+      //            ItemImpl pooled = dataManager.reloadItem(node);
+      //            if (pooled != null)
+      //            {
+      //               results.add(pooled);
+      //            }
+      //            else
+      //            {
+      //               results.add(node);
+      //            }
+      //         }
+      //      }
+      //
+      //      return results;
    }
 
    private EntityCollection createMergeFailed(Map<String, String> failed, SessionChangesLog changes)
@@ -2675,17 +2772,6 @@
 
    private int getNextChildOrderNum() throws RepositoryException
    {
-      //      int max = -1;
-      //      for (NodeData sibling : siblings)
-      //      {
-      //         int cur = sibling.getOrderNumber();
-      //         if (cur > max)
-      //            max = cur;
-      //      }
-      //      return ++max;
-
-      //return siblings.size();
-
       return dataManager.getChildNodesCount(nodeData());
    }
 
@@ -2771,7 +2857,6 @@
       InternalQName[] mixinTypeNames = new InternalQName[0];
       String identifier = IdGenerator.generate();
 
-      //List<NodeData> siblings = dataManager.getChildNodesData(parentNode.nodeData());
       int orderNum = parentNode.getNextChildOrderNum();
       int index = parentNode.getNextChildIndex(name, parentNode.nodeData());
 
@@ -2795,7 +2880,7 @@
          itemAutocreator.makeAutoCreatedItems(node.nodeData(), primaryTypeName, dataManager, session.getUserID());
       for (ItemState autoCreatedState : changes.getAllStates())
       {
-         dataManager.update(autoCreatedState, false);
+         dataManager.update(autoCreatedState, false); // TODO creates ItemImpl (EXOJCR-362)
       }
       // addAutoCreatedItems(node.nodeData(), primaryTypeName);
 
@@ -2997,4 +3082,256 @@
          return r;
       }
    }
+
+   private static class PropertiesDataOrderComparator<P extends PropertyData> implements Comparator<P>
+   {
+      public int compare(P p1, P p2)
+      {
+         int r = 0;
+         try
+         {
+            InternalQName qname1 = p1.getQPath().getName();
+            InternalQName qname2 = p2.getQPath().getName();
+            if (qname1.equals(Constants.JCR_PRIMARYTYPE))
+            {
+               r = Integer.MIN_VALUE;
+            }
+            else if (qname2.equals(Constants.JCR_PRIMARYTYPE))
+            {
+               r = Integer.MAX_VALUE;
+            }
+            else if (qname1.equals(Constants.JCR_MIXINTYPES))
+            {
+               r = Integer.MIN_VALUE + 1;
+            }
+            else if (qname2.equals(Constants.JCR_MIXINTYPES))
+            {
+               r = Integer.MAX_VALUE - 1;
+            }
+            else if (qname1.equals(Constants.JCR_UUID))
+            {
+               r = Integer.MIN_VALUE + 2;
+            }
+            else if (qname2.equals(Constants.JCR_UUID))
+            {
+               r = Integer.MAX_VALUE - 2;
+            }
+            else
+            {
+               r = qname1.getAsString().compareTo(qname2.getAsString());
+            }
+         }
+         catch (Exception e)
+         {
+            LOG.error("PropertiesDataOrderComparator error: " + e, e);
+         }
+         return r;
+      }
+   }
+
+   protected abstract class LazyItemsIterator implements RangeIterator
+   {
+
+      protected final ItemDataFilter filter;
+
+      protected Iterator<? extends ItemData> iter;
+
+      protected int size = -1;
+
+      protected ItemImpl next;
+
+      protected int pos = 0;
+
+      LazyItemsIterator(List<? extends ItemData> items, ItemDataFilter filter) throws RepositoryException
+      {
+         this.iter = items.iterator();
+         this.filter = filter;
+         fetchNext();
+      }
+
+      protected void fetchNext() throws RepositoryException
+      {
+         if (iter.hasNext())
+         {
+            ItemData item = iter.next();
+
+            // check read conditions 
+            if (canRead(item))
+            {
+               next = (ItemImpl)session.getTransientNodesManager().readItem(item, nodeData(), true, false);
+            }
+            else
+            {
+               // try next
+               next = null;
+               fetchNext();
+            }
+         }
+         else
+         {
+            next = null;
+         }
+      }
+
+      protected boolean canRead(ItemData item)
+      {
+         // TODO check if deleted // if (session.getTransientNodesManager().isDeleted(item.getQPath()))
+         return (filter != null ? filter.accept(item) : true)
+            && session.getAccessManager().hasPermission(
+               item.isNode() ? ((NodeData)item).getACL() : nodeData().getACL(), new String[]{PermissionType.READ},
+               session.getUserState().getIdentity());
+      }
+
+      public ItemImpl nextItem()
+      {
+         if (next != null)
+         {
+            try
+            {
+               ItemImpl i = next;
+               fetchNext();
+               pos++;
+
+               // fire action post-READ
+               session.getActionHandler().postRead(i);
+               return i;
+            }
+            catch (RepositoryException e)
+            {
+               LOG.error(e);
+               throw new NoSuchElementException(e.toString());
+            }
+         }
+
+         throw new NoSuchElementException();
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public boolean hasNext()
+      {
+         return next != null;
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public Object next()
+      {
+         return nextItem();
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public void skip(long skipNum)
+      {
+         pos += skipNum;
+         while (skipNum-- > 1)
+         {
+            iter.next();
+         }
+
+         try
+         {
+            fetchNext();
+         }
+         catch (RepositoryException e)
+         {
+            LOG.error(e);
+            throw new NoSuchElementException(e.toString());
+         }
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public long getSize()
+      {
+         if (size == -1)
+         {
+            // calc size
+
+            int sz = pos + (next != null ? 1 : 0);
+            if (iter.hasNext())
+            {
+               List<ItemData> itemsLeft = new ArrayList<ItemData>();
+               do
+               {
+                  ItemData item = iter.next();
+                  if (canRead(item))
+                  {
+                     itemsLeft.add(item);
+                     sz++;
+                  }
+               }
+               while (iter.hasNext());
+
+               iter = itemsLeft.iterator();
+            }
+            size = sz;
+         }
+
+         return size;
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public long getPosition()
+      {
+         return pos;
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public void remove()
+      {
+         LOG.warn("Remove not supported");
+      }
+   }
+
+   protected class LazyNodeIterator extends LazyItemsIterator implements NodeIterator
+   {
+      LazyNodeIterator(List<? extends ItemData> nodes) throws RepositoryException
+      {
+         super(nodes, null);
+      }
+
+      LazyNodeIterator(List<? extends ItemData> nodes, ItemDataFilter filter) throws RepositoryException
+      {
+         super(nodes, filter);
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public Node nextNode()
+      {
+         return (Node)nextItem();
+      }
+   }
+
+   protected class LazyPropertyIterator extends LazyItemsIterator implements PropertyIterator
+   {
+      LazyPropertyIterator(List<? extends ItemData> props) throws RepositoryException
+      {
+         super(props, null);
+      }
+
+      LazyPropertyIterator(List<? extends ItemData> props, ItemDataFilter filter) throws RepositoryException
+      {
+         super(props, filter);
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public Property nextProperty()
+      {
+         return (Property)nextItem();
+      }
+   }
 }

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/PropertyImpl.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/PropertyImpl.java	2010-01-05 17:43:15 UTC (rev 1301)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/PropertyImpl.java	2010-01-05 17:49:40 UTC (rev 1302)
@@ -83,14 +83,40 @@
    }
 
    /**
+    * PropertyImpl constructor.
+    * 
+    * @param data
+    *          ItemData object
+    * @param parent NodeData Property's parent
+    * @param session
+    *          Session object
+    * @throws RepositoryException
+    * @throws ConstraintViolationException
+    */
+   PropertyImpl(ItemData data, NodeData parent, SessionImpl session) throws RepositoryException,
+      ConstraintViolationException
+   {
+      super(data, session);
+      loadData(data, parent);
+   }
+
+   /**
     * {@inheritDoc}
     */
    void loadData(ItemData data) throws RepositoryException, ConstraintViolationException
    {
+      loadData(data, (NodeData)null);
+   }
 
-      // TODO
-      //if (!(data instanceof TransientPropertyData))
-      //   throw new RepositoryException("Load data: TransientPropertyData is expected, but have " + data);
+   /**
+    * {@inheritDoc}
+    */
+   void loadData(ItemData data, NodeData parent) throws RepositoryException, ConstraintViolationException
+   {
+      if (data.isNode())
+      {
+         throw new RepositoryException("Load data failed: Property expected");
+      }
 
       this.data = data;
       this.propertyData = (PropertyData)data;
@@ -99,19 +125,16 @@
       this.qpath = data.getQPath();
       this.location = null;
 
-      initDefinitions(this.propertyData.isMultiValued());
+      initDefinitions(this.propertyData.isMultiValued(), parent);
    }
 
    /**
     * {@inheritDoc}
     */
+   @Deprecated
    void loadData(ItemData data, ItemDefinitionData itemDefinitionData) throws RepositoryException,
       ConstraintViolationException
    {
-
-      //if (!(data instanceof TransientPropertyData))
-      //   throw new RepositoryException("Load data: TransientPropertyData is expected, but have " + data);
-
       this.data = data;
       this.propertyData = (PropertyData)data;
       this.type = propertyData.getType();
@@ -343,17 +366,26 @@
    }
 
    /**
+    * @param multiple
+    * @param parent
     * @throws RepositoryException
     * @throws ConstraintViolationException
     */
-   private void initDefinitions(boolean multiple) throws RepositoryException, ConstraintViolationException
+   private void initDefinitions(boolean multiple, NodeData parent) throws RepositoryException,
+      ConstraintViolationException
    {
 
-      NodeData parent = parentData();
       InternalQName pname = getData().getQPath().getName();
+
+      if (parent == null)
+      {
+         parent = parentData();
+      }
+
       PropertyDefinitionDatas definitions =
          session.getWorkspace().getNodeTypesHolder().getPropertyDefinitions(pname, parent.getPrimaryTypeName(),
             parent.getMixinTypeNames());
+
       if (definitions == null)
       {
          throw new ConstraintViolationException("Definition for property " + getPath() + " not found.");

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java	2010-01-05 17:43:15 UTC (rev 1301)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java	2010-01-05 17:49:40 UTC (rev 1302)
@@ -177,12 +177,18 @@
          item = getItemData(parent, relPathEntries[i]);
 
          if (item == null)
+         {
             break;
+         }
 
          if (item.isNode())
+         {
             parent = (NodeData)item;
+         }
          else if (i < relPathEntries.length - 1)
+         {
             throw new IllegalPathException("Path can not contains a property as the intermediate element");
+         }
       }
       return item;
    }
@@ -195,9 +201,13 @@
       if (name.getName().equals(JCRPath.PARENT_RELPATH) && name.getNamespace().equals(Constants.NS_DEFAULT_URI))
       {
          if (parent.getIdentifier().equals(Constants.ROOT_UUID))
+         {
             return null;
+         }
          else
+         {
             return getItemData(parent.getParentIdentifier());
+         }
       }
 
       ItemData data = null;
@@ -368,25 +378,27 @@
     */
    protected ItemImpl readItem(ItemData itemData, boolean pool) throws RepositoryException
    {
-      return readItem(itemData, pool, true);
+      return readItem(itemData, null, pool, true);
    }
 
    /**
-    * Read ItemImpl of given ItemData.
+    * Create or reload pooled ItemImpl with the given ItemData.
     * 
-    * @param itemData ItemData
+    * @param itemData ItemData, data to create ItemImpl
+    * @param parent NodeData, this item parent data, can be null. Not null used for getChildXXX() 
     * @param pool boolean, if true will reload pooled ItemImpl
-    * @param jcrAPI, boolean if true will call postRead Action and check permissions 
+    * @param apiRead boolean, if true will call postRead Action and check permissions 
     * @return ItemImpl
     * @throws RepositoryException if errro occurs
     */
-   protected ItemImpl readItem(ItemData itemData, boolean pool, boolean jcrAPI) throws RepositoryException
+   protected ItemImpl readItem(ItemData itemData, NodeData parent, boolean pool, boolean apiRead)
+      throws RepositoryException
    {
       if (itemData != null)
       {
          ItemImpl item;
          ItemImpl pooledItem;
-         if (pool && (pooledItem = itemsPool.get(itemData)) != null)
+         if (pool && (pooledItem = itemsPool.get(itemData, parent)) != null)
          {
             // use pooled & reloaded
             item = pooledItem;
@@ -394,10 +406,10 @@
          else
          {
             // create new
-            item = itemFactory.createItem(itemData);
+            item = itemFactory.createItem(itemData, parent);
          }
 
-         if (jcrAPI)
+         if (apiRead)
          {
             // TODO post read will be logically to call after the permissions check
             session.getActionHandler().postRead(item);
@@ -477,12 +489,57 @@
       ItemState lastState = changesLog.getItemState(identifier);
 
       if (lastState == null || lastState.isDeleted())
+      {
          return false;
+      }
 
       return changesLog.getItemState(identifier, ItemState.ADDED) != null;
    }
 
    /**
+    * Returns true if the item with <code>identifier</code> was deleted in this session. Within a transaction,
+    * isDelete on an Item may return false (because the item has been saved) even if that Item is not in
+    * persistent storage (because the transaction has not yet been committed).
+    * 
+    * @param identifier
+    *          of the item
+    * @return boolean, true if the item was deleted
+    */
+   public boolean isDeleted(String identifier)
+   {
+
+      ItemState lastState = changesLog.getItemState(identifier);
+
+      if (lastState != null && lastState.isDeleted())
+      {
+         return true;
+      }
+
+      return false;
+   }
+   
+   /**
+    * Returns true if the item with <code>itemPath</code> was deleted in this session. Within a transaction,
+    * isDelete on an Item may return false (because the item has been saved) even if that Item is not in
+    * persistent storage (because the transaction has not yet been committed).
+    * 
+    * @param itemPath QPath, path of the item
+    * @return boolean, true if the item was deleted
+    */
+   public boolean isDeleted(QPath itemPath)
+   {
+
+      ItemState lastState = changesLog.getItemState(itemPath);
+
+      if (lastState != null && lastState.isDeleted())
+      {
+         return true;
+      }
+
+      return false;
+   }
+
+   /**
     * Returns true if this Item has been saved but has subsequently been modified through the current
     * session and therefore the state of this item as recorded in the session differs from the state
     * of this item as saved. Within a transaction, isModified on an Item may return false (because
@@ -551,12 +608,12 @@
                   continue;
                }
 
-               item = (PropertyImpl)readItem(state.getData(), true, false);
+               item = (PropertyImpl)readItem(state.getData(), null, true, false);
                // TODO item = (PropertyImpl)itemFactory.createItem(state.getData());
             }
             else
             {
-               item = (PropertyImpl)readItem(data, true, false);
+               item = (PropertyImpl)readItem(data, null, true, false);
                // TODO item = (PropertyImpl)itemFactory.createItem(data);
             }
 
@@ -580,6 +637,7 @@
     * @throws AccessDeniedException
     *           if it's no permissions for childs listing
     */
+   @Deprecated
    public List<NodeImpl> getChildNodes(NodeData parent, boolean pool) throws RepositoryException, AccessDeniedException
    {
 
@@ -600,9 +658,9 @@
                .getIdentity()))
             {
                //NodeImpl item = itemFactory.createNode(data, parent.getPrimaryTypeName(), parent.getMixinTypeNames());
-               NodeImpl item = (NodeImpl) readItem(data, pool, false); 
+               NodeImpl item = (NodeImpl)readItem(data, parent, pool, false);
                session.getActionHandler().postRead(item);
-               
+
                //TODO if (pool)
                //   item = (NodeImpl)itemsPool.get(item);
 
@@ -632,13 +690,16 @@
     * @throws AccessDeniedException
     *           if it's no permissions for childs listing
     */
+   @Deprecated
    public List<PropertyImpl> getChildProperties(NodeData parent, boolean pool) throws RepositoryException,
       AccessDeniedException
    {
 
       long start = System.currentTimeMillis();
       if (log.isDebugEnabled())
+      {
          log.debug("getChildProperties(" + parent.getQPath().getAsString() + ") >>>>>");
+      }
 
       try
       {
@@ -653,9 +714,9 @@
             {
                // TODO if (pool)
                //   item = itemsPool.get(item);
-               ItemImpl item = readItem(data, pool, false);
+               ItemImpl item = readItem(data, parent, pool, false);
                session.getActionHandler().postRead(item);
-               
+
                props.add((PropertyImpl)item);
             }
          }
@@ -676,7 +737,9 @@
    {
       long start = System.currentTimeMillis();
       if (log.isDebugEnabled())
+      {
          log.debug("getChildNodesData(" + parent.getQPath().getAsString() + ") >>>>>");
+      }
 
       try
       {
@@ -685,8 +748,10 @@
       finally
       {
          if (log.isDebugEnabled())
+         {
             log.debug("getChildNodesData(" + parent.getQPath().getAsString() + ") <<<<< "
                + ((System.currentTimeMillis() - start) / 1000d) + "sec");
+         }
       }
    }
 
@@ -725,8 +790,10 @@
       finally
       {
          if (log.isDebugEnabled())
+         {
             log.debug("getChildPropertiesData(" + parent.getQPath().getAsString() + ") <<<<< "
                + ((System.currentTimeMillis() - start) / 1000d) + "sec");
+         }
       }
    }
 
@@ -749,8 +816,10 @@
       finally
       {
          if (log.isDebugEnabled())
+         {
             log.debug("listChildPropertiesData(" + parent.getQPath().getAsString() + ") <<<<< "
                + ((System.currentTimeMillis() - start) / 1000d) + "sec");
+         }
       }
    }
 
@@ -791,17 +860,23 @@
          }
 
          if (item != null && item.isNode())
+         {
             // node ACL
             return ((NodeData)item).getACL();
+         }
          else
+         {
             // item not found or it's a property - return parent ACL
             return parent.getACL();
+         }
       }
       finally
       {
          if (log.isDebugEnabled())
+         {
             log.debug("getACL(" + path.getAsString() + ") <<<<< " + ((System.currentTimeMillis() - start) / 1000d)
                + "sec");
+         }
       }
    }
 
@@ -1137,7 +1212,7 @@
 
       changesLog.add(itemState);
 
-      return readItem(itemState.getData(), pool, false);
+      return readItem(itemState.getData(), null, pool, false);
    }
 
    /**
@@ -1422,10 +1497,9 @@
     * @throws RepositoryException
     *          if errors is occurs
     */
-   public NodeImpl wrapNodeData(NodeData data, NodeData parent)
-      throws RepositoryException
+   public NodeImpl wrapNodeData(NodeData data, NodeData parent) throws RepositoryException
    {
-      
+
       NodeImpl node = itemFactory.createNode(data, parent);
       //NodeImpl node = (NodeImpl)itemsPool.get(data);
       session.getActionHandler().postRead(node);
@@ -1500,20 +1574,26 @@
                   .getQPath().getEntries().length - 1]);
 
             if (persisted != null)
+            {
                // reload item data
                removed.loadData(persisted);
+            }
          } // else it's transient item
 
          removedIter.remove();
       }
 
       if (exceptions.length() > 0 && log.isDebugEnabled())
+      {
          log.warn(exceptions);
+      }
    }
 
-   /*
-    * (non-Javadoc)
+   /**
     * @see javax.jcr.Item#refresh(boolean)
+    * @param item ItemData
+    * @throws InvalidItemStateException
+    * @throws RepositoryException
     */
    void refresh(ItemData item) throws InvalidItemStateException, RepositoryException
    {
@@ -1618,7 +1698,7 @@
       }
       else
       {
-         return new ArrayList<ItemData>(dataManager.getChildNodesData((NodeData)rootData));
+         return dataManager.getChildNodesData((NodeData)rootData);
       }
    }
 
@@ -1660,7 +1740,7 @@
       }
       else
       {
-         return new ArrayList<ItemData>(dataManager.getChildPropertiesData((NodeData)rootData));
+         return dataManager.getChildPropertiesData((NodeData)rootData);
       }
    }
 
@@ -1726,7 +1806,7 @@
       }
       else
       {
-         return new ArrayList<ItemData>(getStoredDescendants(rootData, dataManager, action));
+         return getStoredDescendants(rootData, dataManager, action);
       }
    }
 
@@ -1859,17 +1939,17 @@
 
       private WeakHashMap<String, ItemImpl> items;
 
-      private WeakHashMap<String, ItemData> datas;
+      //private WeakHashMap<String, ItemData> datas;
 
       ItemReferencePool()
       {
          items = new WeakHashMap<String, ItemImpl>();
-         datas = new WeakHashMap<String, ItemData>();
+         //datas = new WeakHashMap<String, ItemData>();
       }
 
       ItemImpl remove(String identifier)
       {
-         datas.remove(identifier);
+         //datas.remove(identifier);
          return items.remove(identifier);
       }
 
@@ -1906,7 +1986,7 @@
          ItemImpl item = items.get(identifier);
          if (item == null)
          {
-            datas.remove(identifier);
+            //datas.remove(identifier);
             items.put(identifier, newItem);
             return newItem;
          }
@@ -1926,20 +2006,36 @@
        */
       ItemImpl get(final ItemData newData) throws RepositoryException
       {
+         return get(newData, null);
+      }
+
+      /**
+       * Get ItemImpl from the pool using given data.   
+       * 
+       * @param newData ItemData
+       * @param parent nodeData
+       * @return ItemImpl item
+       * @throws RepositoryException
+       */
+      ItemImpl get(final ItemData newData, final NodeData parent) throws RepositoryException
+      {
          final String identifier = newData.getIdentifier();
          ItemImpl item = items.get(identifier);
          if (item != null)
          {
-            item.loadData(newData);
+            item.loadData(newData, parent);
          }
          else
          {
-//            ItemData preloaded = datas.remove(identifier);
-//            item =
-//               itemFactory.createItem(preloaded != null
-//                  && preloaded.getPersistedVersion() > newData.getPersistedVersion() ? preloaded : newData);
-            datas.remove(identifier);
-            item = itemFactory.createItem(newData);
+            //            ItemData preloaded = datas.remove(identifier);
+            //            item =
+            //               itemFactory.createItem(preloaded != null
+            //                  && preloaded.getPersistedVersion() > newData.getPersistedVersion() ? preloaded : newData);
+            //datas.remove(identifier);
+
+            // TODO if (changesLog.get) check if DELETED!!
+
+            item = itemFactory.createItem(newData, parent);
             items.put(item.getInternalIdentifier(), item);
          }
          return item;
@@ -1952,6 +2048,7 @@
        *          item identifier
        * @return ItemImpl object from pool
        */
+      @Deprecated
       ItemImpl getItem(String identifier)
       {
          return items.get(identifier);
@@ -1964,9 +2061,10 @@
        *          item identifier
        * @return ItemData object from pool
        */
+      @Deprecated
       ItemData getData(String identifier)
       {
-         return datas.get(identifier);
+         return null; //datas.get(identifier);
       }
 
       /**
@@ -1990,10 +2088,10 @@
             item.loadData(newItemData);
             return item;
          }
-         else
-         {
-            datas.put(identifier, newItemData);
-         }
+         //         else
+         //         {
+         //            datas.put(identifier, newItemData);
+         //         }
          return null;
       }
 
@@ -2106,11 +2204,28 @@
       {
 
          if (data.isNode())
+         {
             return createNode((NodeData)data);
+         }
          else
+         {
             return createProperty(data);
+         }
       }
 
+      private ItemImpl createItem(ItemData data, NodeData parent) throws RepositoryException
+      {
+
+         if (data.isNode())
+         {
+            return createNode((NodeData)data, parent);
+         }
+         else
+         {
+            return createProperty(data, parent);
+         }
+      }
+
       private NodeImpl createNode(NodeData data) throws RepositoryException
       {
          NodeImpl node = new NodeImpl(data, session);
@@ -2146,6 +2261,10 @@
          return new PropertyImpl(data, session);
       }
 
+      private PropertyImpl createProperty(ItemData data, NodeData parent) throws RepositoryException
+      {
+         return new PropertyImpl(data, parent, session);
+      }
    }
 
    /**

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java	2010-01-05 17:43:15 UTC (rev 1301)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java	2010-01-05 17:49:40 UTC (rev 1302)
@@ -609,9 +609,7 @@
          if (uri != null)
             return uri;
       }
-      // uri = ;
-      // if (namespaces.values().contains(uri))
-      // return null;
+
       return workspace.getNamespaceRegistry().getURI(prefix);
    }
 

Added: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/itemfilters/ItemDataFilter.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/itemfilters/ItemDataFilter.java	                        (rev 0)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/itemfilters/ItemDataFilter.java	2010-01-05 17:49:40 UTC (rev 1302)
@@ -0,0 +1,35 @@
+/*
+ * 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.impl.core.itemfilters;
+
+import org.exoplatform.services.jcr.datamodel.ItemData;
+
+public interface ItemDataFilter
+{
+
+   /**
+    * Returns <code>true</code> if the specified element is to be included in the set of child
+    * elements returbned by
+    * 
+    * @param item ItemData,
+    *          The item to be tested for inclusion in the returned set.
+    * @return a <code>boolean</code>.
+    */
+   public boolean accept(ItemData item);
+}


Property changes on: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/itemfilters/ItemDataFilter.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Id

Added: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/itemfilters/ItemDataNamePatternFilter.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/itemfilters/ItemDataNamePatternFilter.java	                        (rev 0)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/itemfilters/ItemDataNamePatternFilter.java	2010-01-05 17:49:40 UTC (rev 1302)
@@ -0,0 +1,114 @@
+/*
+ * 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.core.itemfilters;
+
+import org.exoplatform.services.jcr.datamodel.ItemData;
+import org.exoplatform.services.jcr.impl.core.JCRName;
+import org.exoplatform.services.jcr.impl.core.SessionImpl;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.regex.Pattern;
+
+import javax.jcr.NamespaceException;
+import javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS.
+ * 
+ * @author <a href="mailto:geaz at users.sourceforge.net">Gennady Azarenkov</a>
+ * @version $Id$
+ */
+
+public class ItemDataNamePatternFilter implements ItemDataFilter
+{
+
+   /**
+    * Logger.
+    */
+   protected static final Log LOG = ExoLogger.getLogger("jcr.ItemDataNamePatternFilter");
+
+   private final SessionImpl session;
+
+   private final List<String> expressions = new ArrayList<String>();
+
+   public ItemDataNamePatternFilter(String namePattern, SessionImpl session) throws NamespaceException,
+      RepositoryException
+   {
+      this.session = session;
+
+      StringTokenizer parser = new StringTokenizer(namePattern, "|");
+      while (parser.hasMoreTokens())
+      {
+         String token = parser.nextToken();
+
+         //         String expr;
+         //         int prefixIndex = token.indexOf(":");
+         //         if (prefixIndex > 0)
+         //         {
+         //            expr =
+         //               "[" + session.getNamespaceURI(token.substring(0, prefixIndex)) + "]"
+         //                  + (prefixIndex < token.length() - 1 ? token.substring(prefixIndex + 1) : "");
+         //         }
+         //         else
+         //         {
+         //            expr = token;
+         //         }
+
+         expressions.add(token.trim());
+      }
+   }
+
+   public boolean accept(ItemData item)
+   {
+      try
+      {
+         JCRName name = session.getLocationFactory().createJCRName(item.getQPath().getName());
+         for (String expr : expressions)
+         {
+            if (estimate(name.getAsString(), expr))
+            {
+               return true;
+            }
+         }
+      }
+      catch (RepositoryException e)
+      {
+         // if error - just log and don't accept it
+         LOG.error("Cannot parse JCR name for " + item.getQPath().getAsString(), e);
+      }
+
+      return false;
+   }
+
+   private boolean estimate(String name, String expr)
+   {
+      if (expr.indexOf("*") == -1)
+      {
+         return name.equals(expr);
+      }
+
+      String regexp = expr.replaceAll("\\*", ".*");
+      return Pattern.compile(regexp).matcher(name).matches();
+   }
+
+}


Property changes on: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/itemfilters/ItemDataNamePatternFilter.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Id

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/observation/ActionLauncher.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/observation/ActionLauncher.java	2010-01-05 17:43:15 UTC (rev 1301)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/observation/ActionLauncher.java	2010-01-05 17:49:40 UTC (rev 1302)
@@ -124,7 +124,7 @@
                   }
                }
          }
-         if (events.size() > 0)
+         if (events.getSize() > 0)
          {
             // TCK says, no events - no onEvent() action
             listener.onEvent(events);

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionHistoryImpl.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionHistoryImpl.java	2010-01-05 17:43:15 UTC (rev 1301)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionHistoryImpl.java	2010-01-05 17:49:40 UTC (rev 1302)
@@ -84,11 +84,11 @@
     * {@inheritDoc}
     */
    @Override
-   public void loadData(ItemData vhData) throws RepositoryException, InvalidItemStateException,
+   public void loadData(ItemData vhData, NodeData parent) throws RepositoryException, InvalidItemStateException,
       ConstraintViolationException
    {
       super.loadData(new VersionHistoryDataHelper((NodeData)vhData, session.getTransientNodesManager()
-         .getTransactManager(), session.getWorkspace().getNodeTypesHolder()));
+         .getTransactManager(), session.getWorkspace().getNodeTypesHolder()), parent);
    }
 
    /**

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/DefaultItemDataCopyVisitor.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/DefaultItemDataCopyVisitor.java	2010-01-05 17:43:15 UTC (rev 1301)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/DefaultItemDataCopyVisitor.java	2010-01-05 17:49:40 UTC (rev 1302)
@@ -149,7 +149,7 @@
       {
          ancestorToSave = curParent().getQPath();
       }
-      
+
       NodeData parent = curParent();
       QPath qpath = calculateNewNodePath(node, level);
       // Calc order number if parent supports orderable nodes...
@@ -246,6 +246,11 @@
       return null;
    }
 
+   protected int calculateNewNodeOrderNumber() throws RepositoryException
+   {
+      return dataManager.getChildNodesCount(curParent());
+   }
+
    protected QPath calculateNewNodePath(NodeData node, int level) throws RepositoryException
    {
       NodeData parent = curParent();
@@ -273,16 +278,4 @@
       }
       return QPath.makeChildPath(parent.getQPath(), qname, newIndex);
    }
-
-   protected int calculateNewNodeOrderNumber() throws RepositoryException
-   {
-      NodeData parent = curParent();
-      List<NodeData> existedChilds = dataManager.getChildNodesData(parent);
-      int orderNum = 0;
-      if (existedChilds.size() > 0) {
-         orderNum = existedChilds.get(existedChilds.size() - 1).getOrderNumber() + 1;
-      }
-      
-      return orderNum;
-   }
 }

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/ItemDataCloneVisitor.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/ItemDataCloneVisitor.java	2010-01-05 17:43:15 UTC (rev 1301)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/ItemDataCloneVisitor.java	2010-01-05 17:49:40 UTC (rev 1302)
@@ -104,20 +104,20 @@
       {
          Collections.reverse(itemDeletedExistingStates);
       }
-      
+
       return itemDeletedExistingStates;
    }
 
-   @Override
    protected int calculateNewNodeOrderNumber() throws RepositoryException
    {
       NodeData parent = curParent();
       List<NodeData> existedChilds = getMargedChildNodesData(parent);
       int orderNum = 0;
-      if (existedChilds.size() > 0) {
+      if (existedChilds.size() > 0)
+      {
          orderNum = existedChilds.get(existedChilds.size() - 1).getOrderNumber() + 1;
       }
-      
+
       return orderNum;
    }
 
@@ -147,7 +147,7 @@
          qname = node.getQPath().getName();
          newIndex = node.getQPath().getIndex();
       }
-      
+
       return QPath.makeChildPath(parent.getQPath(), qname, newIndex);
    }
 
@@ -158,7 +158,7 @@
       boolean isMixReferenceable =
          ntManager.isNodeType(Constants.MIX_REFERENCEABLE, node.getPrimaryTypeName(), node.getMixinTypeNames());
       deletedExistingPropery = false;
-      
+
       if (isMixReferenceable)
       {
          String identifier = node.getIdentifier();
@@ -226,7 +226,7 @@
             }
          }
       }
-      
+
       super.entering(property, level);
    };
 
@@ -250,7 +250,7 @@
             break;
          }
       }
-      
+
       return retval;
    }
 
@@ -259,14 +259,14 @@
       if (itemInItemStateList(itemDeletedExistingStates, item.getIdentifier(), ItemState.DELETED))
          return true;
       ItemState changesItemState = null;
-      
+
       if (changes != null)
       {
          changesItemState = changes.getItemState(item.getIdentifier());
          if (changesItemState != null && changesItemState.isDeleted())
             return true;
       }
-      
+
       return false;
    }
 
@@ -277,9 +277,11 @@
       for (NodeData nodeData : existedChilds)
       {
          if (!isItemDeleted(nodeData))
+         {
             result.add(nodeData);
+         }
       }
-      
+
       return result;
    }
 }

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/EntityCollection.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/EntityCollection.java	2010-01-05 17:43:15 UTC (rev 1301)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/EntityCollection.java	2010-01-05 17:49:40 UTC (rev 1302)
@@ -80,6 +80,7 @@
       this.pos = 0;
    }
 
+   @Deprecated
    public void reverse()
    {
       Collections.reverse(list);
@@ -236,6 +237,7 @@
       iter = list.iterator();
    }
 
+   @Deprecated
    public void remove(Object obj)
    {
       pos = 0;
@@ -243,11 +245,17 @@
       iter = list.iterator();
    }
 
+   @Deprecated
    public long size()
    {
       return getSize();
    }
 
+   /**
+    * For TESTs only.
+    * 
+    * @return List backed the iterator
+    */
    public List getList()
    {
       return list;

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/NodeIteratorOnDemand.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/NodeIteratorOnDemand.java	2010-01-05 17:43:15 UTC (rev 1301)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/NodeIteratorOnDemand.java	2010-01-05 17:49:40 UTC (rev 1302)
@@ -16,14 +16,12 @@
  */
 package org.exoplatform.services.jcr.impl.util;
 
-import org.exoplatform.services.jcr.datamodel.InternalQName;
 import org.exoplatform.services.jcr.datamodel.NodeData;
 import org.exoplatform.services.jcr.impl.core.NodeImpl;
 import org.exoplatform.services.jcr.impl.core.SessionDataManager;
 import org.exoplatform.services.log.ExoLogger;
 import org.exoplatform.services.log.Log;
 
-import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
@@ -39,18 +37,21 @@
  * @author <a href="mailto:anatoliy.bazko at exoplatform.com.ua">Anatoliy Bazko</a>
  * @version $Id$
  */
+ at Deprecated
 public class NodeIteratorOnDemand extends EntityCollection
 {
    protected static Log log = ExoLogger.getLogger("jcr.NodeIteratorOnDemand");
 
-   private final Iterator iter;
+   private final Iterator<Object> iter;
 
-   private final List list;
+   private final List<Object> list;
 
    private final SessionDataManager dataManager;
 
    private final NodeData parent;
 
+   private NodeImpl next;
+
    private int pos;
 
    /**
@@ -66,12 +67,10 @@
     * @param dataManager
     *          session data manager
     */
-   public NodeIteratorOnDemand(List list, SessionDataManager dataManager, NodeData parent)
+   @Deprecated
+   public NodeIteratorOnDemand(List<Object> list, SessionDataManager dataManager, NodeData parent)
    {
-      if (list == null)
-         this.list = new ArrayList();
-      else
-         this.list = list;
+      this.list = list;
 
       this.dataManager = dataManager;
       this.parent = parent;
@@ -170,4 +169,5 @@
       }
    }
 
+
 }

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/xml/exporting/BaseXmlExporter.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/xml/exporting/BaseXmlExporter.java	2010-01-05 17:43:15 UTC (rev 1301)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/xml/exporting/BaseXmlExporter.java	2010-01-05 17:49:40 UTC (rev 1302)
@@ -31,12 +31,12 @@
 import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
 import org.exoplatform.services.jcr.impl.dataflow.NodeDataOrderComparator;
 import org.exoplatform.services.jcr.impl.dataflow.PropertyDataOrderComparator;
-import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
 import org.exoplatform.services.jcr.impl.dataflow.ValueDataConvertor;
 import org.exoplatform.services.jcr.impl.util.ISO9075;
 import org.xml.sax.SAXException;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
@@ -162,9 +162,10 @@
          {
             currentLevel++;
 
-            List<PropertyData> properies = dataManager.getChildPropertiesData(node);
+            List<PropertyData> properies = new ArrayList<PropertyData>(dataManager.getChildPropertiesData(node));
             // Sorting properties
             Collections.sort(properies, new PropertyDataOrderComparator());
+
             for (PropertyData data : properies)
             {
                InternalQName propName = data.getQPath().getName();
@@ -180,7 +181,7 @@
             }
             if (!isNoRecurse() && (currentLevel > 0))
             {
-               List<NodeData> nodes = dataManager.getChildNodesData(node);
+               List<NodeData> nodes = new ArrayList<NodeData>(dataManager.getChildNodesData(node));
                // Sorting nodes
                Collections.sort(nodes, new NodeDataOrderComparator());
                for (NodeData data : nodes)

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/load/TestJira282.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/load/TestJira282.java	2010-01-05 17:43:15 UTC (rev 1301)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/load/TestJira282.java	2010-01-05 17:49:40 UTC (rev 1302)
@@ -33,6 +33,7 @@
 import java.util.Set;
 
 import javax.jcr.Node;
+import javax.jcr.NodeIterator;
 import javax.jcr.PathNotFoundException;
 import javax.jcr.RepositoryException;
 
@@ -234,11 +235,9 @@
             try
             {
                NodeImpl node = (NodeImpl)agentSession.getItem(validName);
-               List<NodeImpl> list = node.childNodes();
-               // log.info("Node:" + node.getPath() + " child count" + list.size());
-               for (NodeImpl nodeImpl : list)
+               for (NodeIterator iter = node.getNodes(); iter.hasNext();)
                {
-                  String name = nodeImpl.getPath();
+                  String name = iter.nextNode().getPath();
                }
             }
             catch (PathNotFoundException e)



More information about the exo-jcr-commits mailing list