Index: jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/logging/RepositoryServiceLogger.java =================================================================== --- jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/logging/RepositoryServiceLogger.java (revision 918491) +++ jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/logging/RepositoryServiceLogger.java (revision ) @@ -213,14 +213,14 @@ }, "getNodeInfo(SessionInfo, NodeId)", new Object[]{unwrap(sessionInfo), nodeId}); } - public Iterator getItemInfos(final SessionInfo sessionInfo, final NodeId nodeId) + public Iterator getItemInfos(final SessionInfo sessionInfo, final ItemId itemId) throws RepositoryException { return (Iterator) execute(new Callable() { public Object call() throws RepositoryException { - return service.getItemInfos(unwrap(sessionInfo), nodeId); + return service.getItemInfos(unwrap(sessionInfo), itemId); } - }, "getItemInfos(SessionInfo, NodeId)", new Object[]{unwrap(sessionInfo), nodeId}); + }, "getItemInfos(SessionInfo, NodeId)", new Object[]{unwrap(sessionInfo), itemId}); } public Iterator getChildInfos(final SessionInfo sessionInfo, final NodeId parentId) Index: jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/GetItemsTest.java =================================================================== --- jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/GetItemsTest.java (revision 982707) +++ jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/GetItemsTest.java (revision ) @@ -16,11 +16,8 @@ */ package org.apache.jackrabbit.jcr2spi; -import static org.apache.jackrabbit.spi.commons.iterator.Iterators.filterIterator; -import static org.apache.jackrabbit.spi.commons.iterator.Iterators.iteratorChain; -import static org.apache.jackrabbit.spi.commons.iterator.Iterators.singleton; - import org.apache.jackrabbit.spi.ChildInfo; +import org.apache.jackrabbit.spi.ItemId; import org.apache.jackrabbit.spi.ItemInfo; import org.apache.jackrabbit.spi.NodeId; import org.apache.jackrabbit.spi.NodeInfo; @@ -39,9 +36,12 @@ import javax.jcr.PathNotFoundException; import javax.jcr.RepositoryException; import javax.jcr.Session; - import java.util.Iterator; +import static org.apache.jackrabbit.spi.commons.iterator.Iterators.filterIterator; +import static org.apache.jackrabbit.spi.commons.iterator.Iterators.iteratorChain; +import static org.apache.jackrabbit.spi.commons.iterator.Iterators.singleton; + /** * Test cases for {@link RepositoryService#getItemInfos(SessionInfo, NodeId)}. Specifically * for JCR-1797. @@ -150,14 +150,14 @@ } @Override - public Iterator getItemInfos(SessionInfo sessionInfo, final NodeId nodeId) + public Iterator getItemInfos(SessionInfo sessionInfo, final ItemId itemId) throws RepositoryException { - + return iteratorChain( - singleton(itemInfoStore.getNodeInfo(nodeId)), + singleton(itemInfoStore.getItemInfo(itemId)), filterIterator(itemInfoStore.getItemInfos(), new Predicate() { public boolean evaluate(ItemInfo info) { - return !nodeId.equals(info.getId()); + return !itemId.equals(info.getId()); } })); } Index: jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java =================================================================== --- jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java (revision 997303) +++ jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java (revision ) @@ -49,6 +49,7 @@ import org.apache.jackrabbit.spi.commons.QPropertyDefinitionImpl; import org.apache.jackrabbit.spi.commons.QNodeDefinitionImpl; import org.apache.jackrabbit.spi.commons.QNodeTypeDefinitionImpl; +import org.apache.jackrabbit.spi.commons.iterator.Iterators; import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver; import org.apache.jackrabbit.spi.commons.nodetype.NodeTypeDefinitionImpl; import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl; @@ -383,57 +384,66 @@ /** * {@inheritDoc} */ - public Iterator getItemInfos(SessionInfo sessionInfo, NodeId nodeId) + public Iterator getItemInfos(SessionInfo sessionInfo, ItemId itemId) throws ItemNotFoundException, RepositoryException { + + if (!itemId.denotesNode()) { + PropertyId propertyId = (PropertyId) itemId; + PropertyInfo propertyInfo = getPropertyInfo(sessionInfo, propertyId); + return Iterators.singleton(propertyInfo); + } + else { + NodeId nodeId = (NodeId) itemId; - final SessionInfoImpl sInfo = getSessionInfoImpl(sessionInfo); - Node node = getNode(nodeId, sInfo); - Name ntName = null; - try { - ntName = sInfo.getNamePathResolver().getQName(node.getProperty(JcrConstants.JCR_PRIMARYTYPE).getString()); - } catch (NameException e) { - // ignore. should never occur - } - int depth = batchReadConfig.getDepth(ntName); - if (depth == BatchReadConfig.DEPTH_DEFAULT) { - NodeInfo info; - try { - info = new NodeInfoImpl(node, idFactory, sInfo.getNamePathResolver()); - } catch (NameException e) { - throw new RepositoryException(e); - } - return Collections.singletonList(info).iterator(); - } else { - final List itemInfos = new ArrayList(); - ItemVisitor visitor = new TraversingItemVisitor(false, depth) { - @Override - protected void entering(Property property, int i) throws RepositoryException { - try { - itemInfos.add(new PropertyInfoImpl(property, idFactory, sInfo.getNamePathResolver(), getQValueFactory())); - } catch (NameException e) { - throw new RepositoryException(e); - } - } - @Override - protected void entering(Node node, int i) throws RepositoryException { - try { - itemInfos.add(new NodeInfoImpl(node, idFactory, sInfo.getNamePathResolver())); - } catch (NameException e) { - throw new RepositoryException(e); - } - } - @Override - protected void leaving(Property property, int i) { - // nothing to do - } - @Override - protected void leaving(Node node, int i) { - // nothing to do - } - }; - visitor.visit(node); - return itemInfos.iterator(); - } - } + final SessionInfoImpl sInfo = getSessionInfoImpl(sessionInfo); + Node node = getNode(nodeId, sInfo); + Name ntName = null; + try { + ntName = sInfo.getNamePathResolver().getQName(node.getProperty(JcrConstants.JCR_PRIMARYTYPE).getString()); + } catch (NameException e) { + // ignore. should never occur + } + int depth = batchReadConfig.getDepth(ntName); + if (depth == BatchReadConfig.DEPTH_DEFAULT) { + NodeInfo info; + try { + info = new NodeInfoImpl(node, idFactory, sInfo.getNamePathResolver()); + } catch (NameException e) { + throw new RepositoryException(e); + } + return Collections.singletonList(info).iterator(); + } else { + final List itemInfos = new ArrayList(); + ItemVisitor visitor = new TraversingItemVisitor(false, depth) { + @Override + protected void entering(Property property, int i) throws RepositoryException { + try { + itemInfos.add(new PropertyInfoImpl(property, idFactory, sInfo.getNamePathResolver(), getQValueFactory())); + } catch (NameException e) { + throw new RepositoryException(e); + } + } + @Override + protected void entering(Node node, int i) throws RepositoryException { + try { + itemInfos.add(new NodeInfoImpl(node, idFactory, sInfo.getNamePathResolver())); + } catch (NameException e) { + throw new RepositoryException(e); + } + } + @Override + protected void leaving(Property property, int i) { + // nothing to do + } + @Override + protected void leaving(Node node, int i) { + // nothing to do + } + }; + visitor.visit(node); + return itemInfos.iterator(); + } + } + } /** * {@inheritDoc} Index: jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/benchmark/ReadPerformanceTest.java =================================================================== --- jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/benchmark/ReadPerformanceTest.java (revision 982707) +++ jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/benchmark/ReadPerformanceTest.java (revision ) @@ -16,12 +16,9 @@ */ package org.apache.jackrabbit.jcr2spi.benchmark; -import static org.apache.jackrabbit.spi.commons.iterator.Iterators.filterIterator; -import static org.apache.jackrabbit.spi.commons.iterator.Iterators.iteratorChain; -import static org.apache.jackrabbit.spi.commons.iterator.Iterators.singleton; - import org.apache.jackrabbit.jcr2spi.AbstractJCR2SPITest; import org.apache.jackrabbit.spi.ChildInfo; +import org.apache.jackrabbit.spi.ItemId; import org.apache.jackrabbit.spi.ItemInfo; import org.apache.jackrabbit.spi.ItemInfoCache; import org.apache.jackrabbit.spi.NodeId; @@ -42,7 +39,6 @@ import javax.jcr.Property; import javax.jcr.RepositoryException; import javax.jcr.Session; - import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -51,6 +47,10 @@ import java.util.Random; import java.util.concurrent.Callable; +import static org.apache.jackrabbit.spi.commons.iterator.Iterators.filterIterator; +import static org.apache.jackrabbit.spi.commons.iterator.Iterators.iteratorChain; +import static org.apache.jackrabbit.spi.commons.iterator.Iterators.singleton; + /** * Utility for testing jcr2spi read performance */ @@ -320,12 +320,12 @@ } @Override - public Iterator getItemInfos(SessionInfo sessionInfo, NodeId nodeId) + public Iterator getItemInfos(SessionInfo sessionInfo, ItemId itemId) throws ItemNotFoundException, RepositoryException { roundTripCount++; - NodeInfo nodeInfo = itemInfoStore.getNodeInfo(nodeId); - return iteratorChain(singleton(nodeInfo), getBatch()); + ItemInfo itemInfo = itemInfoStore.getItemInfo(itemId); + return iteratorChain(singleton(itemInfo), getBatch()); } @Override Index: jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java =================================================================== --- jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java (revision 1136828) +++ jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java (revision ) @@ -273,17 +273,17 @@ /** * Method used to 'batch-read' from the persistent storage. It returns the - * NodeInfo for the given NodeId as the first + * ItemInfo for the given ItemId as the first * element in the Iterator. In addition the iterator may contain * arbitrary ItemInfos. * * @param sessionInfo - * @param nodeId + * @param itemId * @return An Iterator of ItemInfos containing - * at least a single element: the NodeInfo that represents - * the Node identified by the given NodeId. If the Iterator - * contains multiple elements, the first is expected to represent the Node - * identified by the given NodeId. + * at least a single element: the ItemInfo that represents + * the Item identified by the given ItemId. If the Iterator + * contains multiple elements, the first is expected to represent the Item + * identified by the given ItemId. * @throws javax.jcr.ItemNotFoundException * @throws javax.jcr.RepositoryException * @see javax.jcr.Session#getItem(String) @@ -296,7 +296,7 @@ * @see javax.jcr.Node#getVersionHistory() * @see javax.jcr.version.Version#getContainingHistory() */ - public Iterator getItemInfos(SessionInfo sessionInfo, NodeId nodeId) throws ItemNotFoundException, RepositoryException; + public Iterator getItemInfos(SessionInfo sessionInfo, ItemId itemId) throws ItemNotFoundException, RepositoryException; /** * Returns an Iterator of ChildInfos present on the @@ -347,6 +347,7 @@ * @throws javax.jcr.RepositoryException * @see javax.jcr.Session#getItem(String) * @see javax.jcr.Node#getProperty(String) + * @deprecated Use {@link #getItemInfos(SessionInfo, NodeId)} */ public PropertyInfo getPropertyInfo(SessionInfo sessionInfo, PropertyId propertyId) throws ItemNotFoundException, RepositoryException; Index: jackrabbit-jcr-client/src/test/java/org/apache/jackrabbit/client/RepositoryFactoryImplTest.java =================================================================== --- jackrabbit-jcr-client/src/test/java/org/apache/jackrabbit/client/RepositoryFactoryImplTest.java (revision 918491) +++ jackrabbit-jcr-client/src/test/java/org/apache/jackrabbit/client/RepositoryFactoryImplTest.java (revision ) @@ -301,7 +301,7 @@ return null; } - public Iterator getItemInfos(SessionInfo sessionInfo, NodeId nodeId) throws ItemNotFoundException, RepositoryException { + public Iterator getItemInfos(SessionInfo sessionInfo, ItemId itemId) throws ItemNotFoundException, RepositoryException { return null; } @@ -514,4 +514,4 @@ } } -} \ No newline at end of file +} Index: jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java =================================================================== --- jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java (revision 1157175) +++ jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java (revision ) @@ -121,6 +121,7 @@ import org.apache.jackrabbit.spi.commons.conversion.ParsingNameResolver; import org.apache.jackrabbit.spi.commons.conversion.ParsingPathResolver; import org.apache.jackrabbit.spi.commons.conversion.PathResolver; +import org.apache.jackrabbit.spi.commons.iterator.Iterators; import org.apache.jackrabbit.spi.commons.name.NameConstants; import org.apache.jackrabbit.spi.commons.namespace.AbstractNamespaceResolver; import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver; @@ -988,18 +989,24 @@ /** * @see RepositoryService#getItemInfos(SessionInfo, NodeId) */ - public Iterator getItemInfos(SessionInfo sessionInfo, NodeId nodeId) throws RepositoryException { + public Iterator getItemInfos(SessionInfo sessionInfo, ItemId itemId) throws RepositoryException { // TODO: implement batch read properly: // currently: missing 'value/values' property PropertyInfo cannot be built // currently: missing prop-names with child-NodeInfo + if (itemId.denotesNode()) { - List l = new ArrayList(); + List l = new ArrayList(); - NodeInfo nInfo = getNodeInfo(sessionInfo, nodeId); + NodeInfo nInfo = getNodeInfo(sessionInfo, (NodeId) itemId); - l.add(nInfo); - // at least add propertyInfos for the meta-props already known from the - // nodeInfo. - l.addAll(buildPropertyInfos(nInfo)); - return l.iterator(); - } + l.add(nInfo); + // at least add propertyInfos for the meta-props already known from the + // nodeInfo. + l.addAll(buildPropertyInfos(nInfo)); + return l.iterator(); + } + else { + PropertyInfo pInfo = getPropertyInfo(sessionInfo, (PropertyId) itemId); + return Iterators.singleton(pInfo); + } + } private NodeInfoImpl buildNodeInfo(MultiStatusResponse nodeResponse, NodeId parentId, DavPropertySet propSet, Index: jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java =================================================================== --- jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java (revision 1151110) +++ jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java (revision ) @@ -48,6 +48,7 @@ import org.apache.jackrabbit.spi.NodeId; import org.apache.jackrabbit.spi.Path; import org.apache.jackrabbit.spi.PropertyId; +import org.apache.jackrabbit.spi.PropertyInfo; import org.apache.jackrabbit.spi.QValue; import org.apache.jackrabbit.spi.RepositoryService; import org.apache.jackrabbit.spi.SessionInfo; @@ -55,6 +56,7 @@ import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver; import org.apache.jackrabbit.spi.commons.conversion.PathResolver; import org.apache.jackrabbit.spi.commons.identifier.IdFactoryImpl; +import org.apache.jackrabbit.spi.commons.iterator.Iterators; import org.apache.jackrabbit.spi.commons.name.NameConstants; import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl; import org.apache.jackrabbit.spi.commons.name.PathBuilder; @@ -300,44 +302,51 @@ * @see RepositoryService#getItemInfos(SessionInfo, NodeId) */ @Override - public Iterator getItemInfos(SessionInfo sessionInfo, NodeId nodeId) throws ItemNotFoundException, RepositoryException { - Path path = getPath(nodeId, sessionInfo); + public Iterator getItemInfos(SessionInfo sessionInfo, ItemId itemId) throws ItemNotFoundException, RepositoryException { + if (!itemId.denotesNode()) { + PropertyInfo propertyInfo = super.getPropertyInfo(sessionInfo, (PropertyId) itemId); + return Iterators.singleton(propertyInfo); + } + else { + NodeId nodeId = (NodeId) itemId; + Path path = getPath(itemId, sessionInfo); - String uri = getURI(path, sessionInfo); - int depth = batchReadConfig.getDepth(path, this.getNamePathResolver(sessionInfo)); + String uri = getURI(path, sessionInfo); + int depth = batchReadConfig.getDepth(path, this.getNamePathResolver(sessionInfo)); - GetMethod method = new GetMethod(uri + "." + depth + ".json"); - try { - int statusCode = getClient(sessionInfo).executeMethod(method); - if (statusCode == DavServletResponse.SC_OK) { - if (method.getResponseContentLength() == 0) { - // no JSON response -> no such node on the server + GetMethod method = new GetMethod(uri + "." + depth + ".json"); + try { + int statusCode = getClient(sessionInfo).executeMethod(method); + if (statusCode == DavServletResponse.SC_OK) { + if (method.getResponseContentLength() == 0) { + // no JSON response -> no such node on the server - throw new ItemNotFoundException("No such node " + nodeId); + throw new ItemNotFoundException("No such item " + nodeId); - } + } - NamePathResolver resolver = getNamePathResolver(sessionInfo); - NodeInfoImpl nInfo = new NodeInfoImpl(nodeId, path); + NamePathResolver resolver = getNamePathResolver(sessionInfo); + NodeInfoImpl nInfo = new NodeInfoImpl(nodeId, path); - ItemInfoJsonHandler handler = new ItemInfoJsonHandler(resolver, nInfo, getRootURI(sessionInfo), getQValueFactory(sessionInfo), getPathFactory(), getIdFactory()); - JsonParser ps = new JsonParser(handler); - ps.parse(method.getResponseBodyAsStream(), method.getResponseCharSet()); + ItemInfoJsonHandler handler = new ItemInfoJsonHandler(resolver, nInfo, getRootURI(sessionInfo), getQValueFactory(sessionInfo), getPathFactory(), getIdFactory()); + JsonParser ps = new JsonParser(handler); + ps.parse(method.getResponseBodyAsStream(), method.getResponseCharSet()); - Iterator it = handler.getItemInfos(); - if (!it.hasNext()) { - throw new ItemNotFoundException("No such node " + uri); - } - return handler.getItemInfos(); - } else { - throw ExceptionConverter.generate(new DavException(statusCode, "Unable to retrieve NodeInfo for " + uri), method); - } - } catch (HttpException e) { - throw ExceptionConverter.generate(new DavException(method.getStatusCode(), "Unable to retrieve NodeInfo for " + uri)); - } catch (IOException e) { - log.error("Internal error while retrieving NodeInfo.",e); - throw new RepositoryException(e.getMessage()); - } finally { - method.releaseConnection(); - } - } + Iterator it = handler.getItemInfos(); + if (!it.hasNext()) { + throw new ItemNotFoundException("No such node " + uri); + } + return handler.getItemInfos(); + } else { + throw ExceptionConverter.generate(new DavException(statusCode, "Unable to retrieve NodeInfo for " + uri), method); + } + } catch (HttpException e) { + throw ExceptionConverter.generate(new DavException(method.getStatusCode(), "Unable to retrieve NodeInfo for " + uri)); + } catch (IOException e) { + log.error("Internal error while retrieving NodeInfo.",e); + throw new RepositoryException(e.getMessage()); + } finally { + method.releaseConnection(); + } + } + } @Override public Batch createBatch(SessionInfo sessionInfo, ItemId itemId) throws RepositoryException { Index: jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/AbstractJCR2SPITest.java =================================================================== --- jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/AbstractJCR2SPITest.java (revision 918491) +++ jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/AbstractJCR2SPITest.java (revision ) @@ -154,10 +154,10 @@ return AbstractJCR2SPITest.this.createRootNodeDefinition(); } - public Iterator getItemInfos(SessionInfo sessionInfo, NodeId nodeId) + public Iterator getItemInfos(SessionInfo sessionInfo, ItemId itemId) throws ItemNotFoundException, RepositoryException { - return AbstractJCR2SPITest.this.getItemInfos(sessionInfo, nodeId); + return AbstractJCR2SPITest.this.getItemInfos(sessionInfo, itemId); } public Iterator getChildInfos(SessionInfo sessionInfo, NodeId parentId) @@ -316,7 +316,7 @@ public abstract NodeInfo getNodeInfo(SessionInfo sessionInfo, NodeId nodeId) throws RepositoryException; - public abstract Iterator getItemInfos(SessionInfo sessionInfo, NodeId nodeId) throws ItemNotFoundException, RepositoryException; + public abstract Iterator getItemInfos(SessionInfo sessionInfo, ItemId itemId) throws ItemNotFoundException, RepositoryException; public abstract Iterator getChildInfos(SessionInfo sessionInfo, NodeId parentId) throws ItemNotFoundException, RepositoryException; Index: jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java =================================================================== --- jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java (revision 1104030) +++ jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java (revision ) @@ -85,20 +85,20 @@ try { Entry cached = cache.getNodeInfo(nodeId); - NodeInfo info; + ItemInfo info; if (isUpToDate(cached, entry)) { info = cached.info; } else { // otherwise retreive item info from service and cache the whole batch Iterator infos = service.getItemInfos(sessionInfo, nodeId); info = first(infos, cache, entry.getGeneration()); - if (info == null) { + if (info == null || !info.denotesNode()) { throw new ItemNotFoundException("NodeId: " + nodeId); } } assertMatchingPath(info, entry); - return createNodeState(info, entry); + return createNodeState((NodeInfo) info, entry); } catch (PathNotFoundException e) { throw new ItemNotFoundException(e); @@ -116,12 +116,12 @@ // Get item info from cache Iterator infos = null; Entry cached = cache.getNodeInfo(nodeId); - NodeInfo info; + ItemInfo info; if (cached == null) { // or from service if not in cache infos = service.getItemInfos(sessionInfo, nodeId); info = first(infos, null, 0); - if (info == null) { + if (info == null || !info.denotesNode()) { throw new ItemNotFoundException("NodeId: " + nodeId); } } else { @@ -147,7 +147,7 @@ } assertMatchingPath(info, entry); - return createNodeState(info, (NodeEntry) entry); + return createNodeState((NodeInfo) info, (NodeEntry) entry); } } catch (PathNotFoundException e) { @@ -164,17 +164,20 @@ try { // Get item info from cache and use it if up to date Entry cached = cache.getPropertyInfo(propertyId); - PropertyInfo info; + ItemInfo info; if (isUpToDate(cached, entry)) { info = cached.info; } else { // otherwise retreive item info from service and cache the whole batch - info = service.getPropertyInfo(sessionInfo, propertyId); - cache.put(info, entry.getGeneration()); + Iterator infos = service.getItemInfos(sessionInfo, propertyId); + info = first(infos, cache, entry.getGeneration()); + if (info == null || info.denotesNode()) { + throw new ItemNotFoundException("PropertyId: " + propertyId); - } + } + } assertMatchingPath(info, entry); - return createPropertyState(info, entry); + return createPropertyState((PropertyInfo) info, entry); } catch (PathNotFoundException e) { throw new ItemNotFoundException(e); @@ -190,30 +193,39 @@ try { // Get item info from cache + Iterator infos = null; Entry cached = cache.getPropertyInfo(propertyId); - PropertyInfo info; + ItemInfo info; if (cached == null) { // or from service if not in cache - info = service.getPropertyInfo(sessionInfo, propertyId); + infos = service.getItemInfos(sessionInfo, propertyId); + info = first(infos, null, 0); + if (info == null || info.denotesNode()) { + throw new ItemNotFoundException("PropertyId: " + propertyId); + } } else { info = cached.info; } // Build the hierarchy entry for the item info HierarchyEntry entry = createHierarchyEntries(info, anyParent); - if (entry == null || entry.denotesNode()) { throw new ItemNotFoundException( "HierarchyEntry does not belong to any existing ItemInfo. No ItemState was created."); } else { + long generation = entry.getGeneration(); if (isOutdated(cached, entry)) { // if not, retreive the item info from the service and put the whole batch into the cache - info = service.getPropertyInfo(sessionInfo, propertyId); - cache.put(info, entry.getGeneration()); + infos = service.getItemInfos(sessionInfo, propertyId); + info = first(infos, cache, generation); + } else if (infos != null) { + // Otherwise put the whole batch retrieved from the service earlier into the cache + cache.put(info, generation); + first(infos, cache, generation); } assertMatchingPath(info, entry); - return createPropertyState(info, (PropertyEntry) entry); + return createPropertyState((PropertyInfo) info, (PropertyEntry) entry); } } catch (PathNotFoundException e) { @@ -250,23 +262,18 @@ //------------------------------------------------------------< private >--- /** - * Returns the first item in the iterator if it exists and denotes a node. - * Otherwise returns null. If cache is not - * null, caches all items by the given generation. - * @param generation + * Returns the first item in the iterator if it exists. Otherwise returns null. + * If cache is not null, caches all items by the given + * generation. */ - private static NodeInfo first(Iterator infos, ItemInfoCache cache, long generation) { + private static ItemInfo first(Iterator infos, ItemInfoCache cache, long generation) { ItemInfo first = null; if (infos.hasNext()) { first = infos.next(); if (cache != null) { cache.put(first, generation); } - - if (!first.denotesNode()) { - first = null; - } + } - } if (cache != null) { while (infos.hasNext()) { @@ -274,7 +281,7 @@ } } - return (NodeInfo) first; + return first; } /**