incubator-bval-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mben...@apache.org
Subject svn commit: r1069992 - /incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java
Date Sat, 12 Feb 2011 00:02:13 GMT
Author: mbenson
Date: Sat Feb 12 00:02:12 2011
New Revision: 1069992

URL: http://svn.apache.org/viewvc?rev=1069992&view=rev
Log:
use a caching iterator so that when cached MetaBeans are used and are up-to-date against the
entire context, thus not needing to be checked against each constituent leaf metaBean, additional
unused Path objects are not created

Modified:
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java

Modified: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java?rev=1069992&r1=1069991&r2=1069992&view=diff
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java
(original)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java
Sat Feb 12 00:02:12 2011
@@ -28,7 +28,6 @@ import java.util.Collections;
 import java.util.Deque;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.concurrent.ConcurrentHashMap;
@@ -117,6 +116,141 @@ final class DynamicMetaGraphManagerImpl 
     }
 
     /**
+     * Iterator over pairs of path : class representing each step in a path.
+     */
+    private static class TypePathIterator implements Iterator<Pair<? extends PathImpl,
Class<?>>>,
+        Iterable<Pair<? extends PathImpl, Class<?>>> {
+        private final PathImpl fullPath;
+        private ArrayList<Pair<? extends PathImpl, Class<?>>> cache;
+        private ArrayList<Path.Node> nodes;
+
+        private Class<?> rawType;
+        private Type type;
+        private Object bean;
+        private int pos;
+
+        /**
+         * Create a new TypePathIterator instance.
+         * 
+         * @param fullPath
+         * @param rootBean
+         * @param rootType
+         */
+        private TypePathIterator(PathImpl fullPath, Object rootBean, Class<?> rootType)
{
+            super();
+            this.fullPath = fullPath;
+            this.rawType = rootType;
+            this.type = rootType;
+            this.bean = rootBean;
+            this.pos = 0;
+
+            nodes = new ArrayList<Path.Node>();
+            for (Path.Node node : fullPath) {
+                nodes.add(node);
+            }
+            cache = new ArrayList<Pair<? extends PathImpl, Class<?>>>(nodes.size());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public boolean hasNext() {
+            return nodes != null || cache.size() > pos;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Pair<? extends PathImpl, Class<?>> next() {
+            try {
+                if (pos < cache.size()) {
+                    return cache.get(pos);
+                }
+                if (nodes == null) {
+                    throw new NoSuchElementException();
+                }
+
+                Pair<PathImpl, Class<?>> result = null;
+
+                PathImpl path;
+                if (pos == 0) {
+                    path = fullPath;
+                } else {
+                    path = buildPath(nodes);
+                }
+
+                while (result == null) {
+                    if (nodes.isEmpty() || !nodes.get(0).isInIterable()) {
+                        result = Pair.<PathImpl, Class<?>> of(path, rawType);
+                    }
+                    if (path.isRootPath() || nodes.isEmpty()) {
+                        nodes = null;
+                        break;
+                    }
+                    Path.Node node = nodes.remove(0);
+                    if (node.isInIterable()) {
+                        AccessStrategy access;
+                        if (IndexedAccess.getJavaElementType(type) != null) {
+                            access =
+                                new IndexedAccess(type, ObjectUtils.defaultIfNull(node.getIndex(),
Integer.valueOf(-1))
+                                    .intValue());
+                        } else if (KeyedAccess.getJavaElementType(type) != null) {
+                            access = new KeyedAccess(type, node.getKey());
+                        } else {
+                            throw new UnknownPropertyException(String.format("%s in %s",
node, fullPath));
+                        }
+                        if (bean != null) {
+                            bean = access.get(bean);
+                        }
+                        rawType = TypeUtils.getRawType(access.getJavaType(), type);
+                        type = access.getJavaType();
+                        if (node.getName() != null) {
+                            // substitute a name-only node and repeat the loop:
+                            nodes.add(0, new NodeImpl(node.getName()));
+                        }
+                    } else if (node.getName() != null) {
+                        PropertyAccess access = new PropertyAccess(rawType, node.getName());
+                        if (bean != null) {
+                            bean = access.get(bean);
+                        }
+                        rawType = TypeUtils.getRawType(access.getJavaType(), type);
+                        type = access.getJavaType();
+                    }
+                    if (result == null) {
+                        path = buildPath(nodes);
+                    }
+                }
+                cache.add(result);
+                return result;
+            } finally {
+                pos++;
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Iterator<Pair<? extends PathImpl, Class<?>>> iterator()
{
+            return this.reset();
+        }
+
+        /**
+         * Reset the iterator.
+         */
+        public TypePathIterator reset() {
+            pos = 0;
+            return this;
+        }
+    }
+
+    /**
      * PathNavigation callback for initial location of a property path.
      */
     private class NavigateOrBuildGraph implements PathNavigation.Callback<FeaturesCapable>
{
@@ -411,8 +545,8 @@ final class DynamicMetaGraphManagerImpl 
                     rootBean = validationState.getRootBean();
                 }
                 try {
-                    List<Pair<? extends PathImpl, Class<?>>> typedPaths
=
-                        getTypedPaths(path, rootBean, rootMetaBean.getBeanClass());
+                    Iterable<Pair<? extends PathImpl, Class<?>>> typedPaths
=
+                        new TypePathIterator(path, rootBean, rootMetaBean.getBeanClass());
 
                     MetaBean cached = findCachedMetaBean(typedPaths, initial);
                     if (cached != null) {
@@ -581,6 +715,7 @@ final class DynamicMetaGraphManagerImpl 
 
     /**
      * Apply a constraint into the writable meta-graph.
+     * 
      * @param beanType
      * @param propertyPath
      * @param annotation
@@ -626,7 +761,7 @@ final class DynamicMetaGraphManagerImpl 
      *            MetaBean from the (factory-level) "static" cache
      * @return MetaBean
      */
-    private MetaBean findCachedMetaBean(List<Pair<? extends PathImpl, Class<?>>>
typedPaths, MetaBean initial) {
+    private MetaBean findCachedMetaBean(Iterable<Pair<? extends PathImpl, Class<?>>>
typedPaths, MetaBean initial) {
         Iterator<MetaBean> iter = new LeafIterator(typedPaths, /* findCacheMeta: */true);
         if (iter.hasNext()) {
             // cached payload guaranteed not to be null:
@@ -706,73 +841,6 @@ final class DynamicMetaGraphManagerImpl 
         return metaBean;
     }
 
-    /**
-     * Build up a list of pairs of path : class representing each object in the currently
known path, i.e. what we're
-     * trying to complete the bean for.
-     * 
-     * @param fullPath
-     * @param rootBean
-     * @param rootType
-     * @return List in descending order of path length
-     */
-    private static List<Pair<? extends PathImpl, Class<?>>> getTypedPaths(final
PathImpl fullPath, Object rootBean,
-        Class<?> rootType) {
-        // get a list of Nodes we can play with:
-        LinkedList<Path.Node> nodes = new LinkedList<Path.Node>();
-        for (Path.Node node : fullPath) {
-            nodes.add(node);
-        }
-
-        List<Pair<? extends PathImpl, Class<?>>> result =
-            new ArrayList<Pair<? extends PathImpl, Class<?>>>((int) (nodes.size()
* 1.5));
-
-        Class<?> rawType = rootType;
-        Type type = rawType;
-        Object bean = rootBean;
-        PathImpl path = fullPath;
-
-        while (true) {
-            if (nodes.isEmpty() || !nodes.get(0).isInIterable()) {
-                result.add(Pair.<PathImpl, Class<?>> of(path, rawType));
-            }
-            if (path.isRootPath() || nodes.isEmpty()) {
-                break;
-            }
-            // handle the property:
-            Path.Node node = nodes.remove(0);
-            if (node.isInIterable()) {
-                AccessStrategy access;
-                if (IndexedAccess.getJavaElementType(type) != null) {
-                    access =
-                        new IndexedAccess(type, ObjectUtils.defaultIfNull(node.getIndex(),
Integer.valueOf(-1))
-                            .intValue());
-                } else if (KeyedAccess.getJavaElementType(type) != null) {
-                    access = new KeyedAccess(type, node.getKey());
-                } else {
-                    throw new UnknownPropertyException(String.format("%s in %s", node, path));
-                }
-                if (bean != null) {
-                    bean = access.get(bean);
-                }
-                rawType = TypeUtils.getRawType(access.getJavaType(), type);
-                type = access.getJavaType();
-                if (node.getName() != null) {
-                    // substitute a name-only node and repeat the loop:
-                    nodes.addFirst(new NodeImpl(node.getName()));
-                }
-            } else if (node.getName() != null) {
-                PropertyAccess access = new PropertyAccess(rawType, node.getName());
-                if (bean != null) {
-                    bean = access.get(bean);
-                }
-                rawType = TypeUtils.getRawType(access.getJavaType(), type);
-                type = access.getJavaType();
-            }
-            path = buildPath(nodes);
-        }
-        return result;
-    }
-
     private static PathImpl buildPath(Iterable<? extends Path.Node> nodes) {
         PathImpl result = PathImpl.create(null);
         for (Path.Node node : nodes) {
@@ -781,4 +849,4 @@ final class DynamicMetaGraphManagerImpl 
         return result;
     }
 
-}
+}
\ No newline at end of file



Mime
View raw message