You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2014/07/25 14:45:36 UTC
svn commit: r1613419 [1/5] - in /sling/trunk/contrib/extensions/sling-query:
./ src/ src/main/ src/main/java/ src/main/java/org/
src/main/java/org/apache/ src/main/java/org/apache/sling/
src/main/java/org/apache/sling/query/ src/main/java/org/apache/sl...
Author: bdelacretaz
Date: Fri Jul 25 12:45:33 2014
New Revision: 1613419
URL: http://svn.apache.org/r1613419
Log:
SLING-3667 Add SlingQuery library, donated by Tomek Rękawek, thanks!
Added:
sling/trunk/contrib/extensions/sling-query/ (with props)
sling/trunk/contrib/extensions/sling-query/CHANGELOG.md
sling/trunk/contrib/extensions/sling-query/README.md
sling/trunk/contrib/extensions/sling-query/pom.xml
sling/trunk/contrib/extensions/sling-query/src/
sling/trunk/contrib/extensions/sling-query/src/main/
sling/trunk/contrib/extensions/sling-query/src/main/java/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/AbstractQuery.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/IteratorUtils.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/LazyList.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/SlingQuery.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/Function.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/Predicate.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/SearchStrategy.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/TreeProvider.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/ElementToIteratorFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/IteratorToIteratorFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/Option.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/AddFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/ChildrenFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/ClosestFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/CompositeFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/DescendantFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/EvenFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/FilterFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/FindFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/HasFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/IdentityFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/IteratorToIteratorFunctionWrapper.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/LastFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/NextFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/NotFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/ParentFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/ParentsFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/PrevFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/SiblingsFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/SliceFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/UniqueFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/AbstractIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/AdaptToIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/AlternativeIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/ArgumentResettingIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/DescendantsIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/EmptyElementFilter.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/ExpandingIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/FilteringIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/LastIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/MergingIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/OptionDecoratingIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/OptionStrippingIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/ParentsIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/ReverseIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/SiblingsIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/SliceIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/SuppIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/UniqueIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/WarningIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/tree/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/tree/BfsTreeIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/iterator/tree/DfsTreeIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/predicate/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/predicate/IterableContainsPredicate.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/predicate/ParentPredicate.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/predicate/RejectingPredicate.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/predicate/SelectorOperator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/resource/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/resource/ResourcePredicate.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/resource/ResourcePropertyPredicate.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/resource/ResourceTreeProvider.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/resource/jcr/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/resource/jcr/JcrOperator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/resource/jcr/JcrQueryIterator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/resource/jcr/JcrTypeResolver.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/resource/jcr/SessionJcrTypeResolver.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/resource/jcr/query/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/resource/jcr/query/Atomic.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/resource/jcr/query/Formula.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/resource/jcr/query/JcrQueryBuilder.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/resource/jcr/query/Term.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/selector/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/selector/FunctionType.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/selector/HierarchyOperator.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/selector/SelectorFunction.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/selector/parser/
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/selector/parser/Attribute.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/selector/parser/Modifier.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/selector/parser/ParserContext.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/selector/parser/Selector.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/selector/parser/SelectorParser.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/selector/parser/SelectorSegment.java
sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/selector/parser/State.java
sling/trunk/contrib/extensions/sling-query/src/test/
sling/trunk/contrib/extensions/sling-query/src/test/java/
sling/trunk/contrib/extensions/sling-query/src/test/java/org/
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/AddTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/AttributeOperatorTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/ChildrenTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/ClosestTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/FilterTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/FindTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/HasTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/HierarchySelectorTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/LastTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/ListTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/MapTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/MultipleSelectorTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/NextPrevAllTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/NextPrevTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/NextPrevUntilTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/NotTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/ParentTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/ParentsTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/ParentsUntilTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/SelectorFunctionTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/SiblingsTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/SliceTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/TestUtils.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/UniqueTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/iterator/
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/iterator/ReverseTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/iterator/SuppTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/mock/
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/mock/MockTypeResolver.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/mock/ResourceMock.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/mock/StringResourceMock.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/mock/json/
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/mock/json/JsonToResource.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/selector/
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/selector/parser/
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/selector/parser/JcrMultiSelectorTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/selector/parser/JcrSelectorTest.java
sling/trunk/contrib/extensions/sling-query/src/test/java/org/apache/sling/query/selector/parser/SelectorTest.java
sling/trunk/contrib/extensions/sling-query/src/test/resources/
sling/trunk/contrib/extensions/sling-query/src/test/resources/sample_tree.json
Propchange: sling/trunk/contrib/extensions/sling-query/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Jul 25 12:45:33 2014
@@ -0,0 +1,14 @@
+target
+bin
+derby.log
+*.iml
+*.ipr
+*.iws
+.settings
+.project
+.classpath
+.externalToolBuilders
+maven-eclipse.xml
+
+
+
Added: sling/trunk/contrib/extensions/sling-query/CHANGELOG.md
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/CHANGELOG.md?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/CHANGELOG.md (added)
+++ sling/trunk/contrib/extensions/sling-query/CHANGELOG.md Fri Jul 25 12:45:33 2014
@@ -0,0 +1,37 @@
+## SlingQuery 1.4.2
+
+* Added new add(...) method
+
+## SlingQuery 1.4.1
+
+* Fixed bug in the QUERY search strategy related
+
+## SlingQuery 1.4.0
+
+* `not()` function is now lazy (eg. `$(resourceResolver).not('cq:InvalidType').first()` return results immediately)
+* multiple selectors can be joined with comma: `$('[jcr:title=Foo], [jcr:title=Bar])`
+* JCR query becomes the default SearchStrategy
+
+## SlingQuery 1.3.1
+
+* fixed `javax.jcr.RepositoryException: invalid node type name` bug (reported by Dawid JÄdraszek)
+
+## SlingQuery 1.3.0
+
+* lazy `asList()` method
+
+## SlingQuery 1.2.0
+
+* new strategy for the `find()`: `JCR`
+
+## SlingQuery 1.1.0
+
+* new selector features:
+ * [hierarchy operators](https://github.com/Cognifide/Sling-Query/wiki/Hierarchy-operator-list),
+ * [resource name](https://github.com/Cognifide/Sling-Query/wiki/Selector-syntax#wiki-resource-name),
+ * [new attribute operators](https://github.com/Cognifide/Sling-Query/wiki/Operator%20list)
+* two strategies for the `find()` method: `DFS` and `BFS`
+
+## SlingQuery 1.0.0
+
+* first released version
Added: sling/trunk/contrib/extensions/sling-query/README.md
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/README.md?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/README.md (added)
+++ sling/trunk/contrib/extensions/sling-query/README.md Fri Jul 25 12:45:33 2014
@@ -0,0 +1,66 @@
+# SlingQuery
+[](https://travis-ci.org/Cognifide/Sling-Query)
+
+SlingQuery is a Sling resource tree traversal tool inspired by the [jQuery](http://api.jquery.com/category/traversing/tree-traversal/).
+
+## Introduction
+
+Recommended way to find resources in the Sling repository is using tree-traversal methods, like `listChildren()` and `getParent()` rather than JCR queries. The latter are great for listing resources with given properties, but we can't leverage the repository tree structure with such queries. On the other hand, using tree-traversal method is quite verbose. Consider following code that takes an resource and returns its first ancestor, being `cq:Page`, with given `jcr:content/cq:template` attribute:
+
+ Resource resource = ...;
+ while ((resource = resource.getParent()) != null) {
+ if (!resource.isResourceType("cq:Page")) {
+ continue;
+ }
+ Resource template = resource.getChild("jcr:content/cq:template");
+ if (template != null && "my/template".equals(template.adaptTo(String.class))) {
+ break;
+ }
+ }
+ if (resource != null) {
+ // we've found appropriate ancestor
+ }
+
+SlingQuery is a tool that helps creating such queries in a more concise way. Above code could be written as:
+
+ import static com.cognifide.sling.query.api.SlingQuery.$;
+ // ...
+ $(resource).closest("cq:Page[jcr:content/cq:template=my/template]")
+
+Dollar sign is a static method that takes the resource array and creates SlingQuery object. The `closest()` method returns the first ancestor matching the selector string passed as the argument.
+
+SlingQuery is inspired by the jQuery framework. jQuery is the source of method names, selector string syntax and the dollar sign method used as a collection constructor.
+
+## Features
+
+* useful [operations](https://github.com/Cognifide/Sling-Query/wiki/Method-list) to traverse the resource tree,
+* flexible [filtering syntax](https://github.com/Cognifide/Sling-Query/wiki/Selector-syntax),
+* lazy evaluation of the query result,
+* `SlingQuery` object is immutable (thread-safe),
+* fluent, friendly, jQuery-like API.
+
+## Installation
+
+Add following Maven dependency to your `pom.xml`:
+
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.query</artifactId>
+ <version>1.4.4</version>
+ </dependency>
+
+## Documentation
+
+* [CIRCUIT 2014 presentation](http://cognifide.github.io/Sling-Query/circuit2014/)
+* [Basic ideas](https://github.com/Cognifide/Sling-Query/wiki/Basic-ideas)
+* [Method list](https://github.com/Cognifide/Sling-Query/wiki/Method-list)
+* [Selector syntax](https://github.com/Cognifide/Sling-Query/wiki/Selector-syntax)
+ * [Operator list](https://github.com/Cognifide/Sling-Query/wiki/Operator-list)
+ * [Modifier list](https://github.com/Cognifide/Sling-Query/wiki/Modifier-list)
+ * [Hierarchy operator list](https://github.com/Cognifide/Sling-Query/wiki/Hierarchy-operator-list)
+* [Examples](https://github.com/Cognifide/Sling-Query/wiki/Examples)
+
+## External resources
+
+* See the [Apache Sling website](http://sling.apache.org/) for the Sling reference documentation. Apache Sling, Apache and Sling are trademarks of the [Apache Software Foundation](http://apache.org).
+* Method names, selector syntax and some parts of documentation are inspired by the [jQuery](http://jquery.com/) library.
Added: sling/trunk/contrib/extensions/sling-query/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/pom.xml?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/pom.xml (added)
+++ sling/trunk/contrib/extensions/sling-query/pom.xml Fri Jul 25 12:45:33 2014
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <parent>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>sling</artifactId>
+ <version>19</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>org.apache.sling.query</artifactId>
+ <version>1.4.5-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+
+ <name>sling-query</name>
+ <description>jQuery-inspired repository traversal tool for Sling</description>
+
+ <properties>
+ <sling.java.version>6</sling.java.version>
+ </properties>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/sling-query</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/sling-query</developerConnection>
+ <url>http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query</url>
+ </scm>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <!-- commons -->
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <scope>provided</scope>
+ <version>2.5</version>
+ </dependency>
+
+ <!-- sling -->
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.api</artifactId>
+ <scope>provided</scope>
+ <version>2.2.4</version>
+ </dependency>
+
+ <!-- jcr -->
+ <dependency>
+ <groupId>javax.jcr</groupId>
+ <artifactId>jcr</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- org.slf4j -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- test dependencies -->
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>2.2.4</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/AbstractQuery.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/AbstractQuery.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/AbstractQuery.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/AbstractQuery.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,802 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.sling.query.api.Function;
+import org.apache.sling.query.api.Predicate;
+import org.apache.sling.query.api.SearchStrategy;
+import org.apache.sling.query.api.TreeProvider;
+import org.apache.sling.query.api.function.IteratorToIteratorFunction;
+import org.apache.sling.query.api.function.Option;
+import org.apache.sling.query.function.AddFunction;
+import org.apache.sling.query.function.ChildrenFunction;
+import org.apache.sling.query.function.ClosestFunction;
+import org.apache.sling.query.function.CompositeFunction;
+import org.apache.sling.query.function.DescendantFunction;
+import org.apache.sling.query.function.FilterFunction;
+import org.apache.sling.query.function.FindFunction;
+import org.apache.sling.query.function.HasFunction;
+import org.apache.sling.query.function.IdentityFunction;
+import org.apache.sling.query.function.LastFunction;
+import org.apache.sling.query.function.NextFunction;
+import org.apache.sling.query.function.NotFunction;
+import org.apache.sling.query.function.ParentFunction;
+import org.apache.sling.query.function.ParentsFunction;
+import org.apache.sling.query.function.PrevFunction;
+import org.apache.sling.query.function.SiblingsFunction;
+import org.apache.sling.query.function.SliceFunction;
+import org.apache.sling.query.function.UniqueFunction;
+import org.apache.sling.query.iterator.EmptyElementFilter;
+import org.apache.sling.query.iterator.OptionDecoratingIterator;
+import org.apache.sling.query.iterator.OptionStrippingIterator;
+import org.apache.sling.query.predicate.IterableContainsPredicate;
+import org.apache.sling.query.predicate.RejectingPredicate;
+import org.apache.sling.query.selector.SelectorFunction;
+
+public abstract class AbstractQuery<T, Q extends AbstractQuery<T, Q>> implements Iterable<T> {
+
+ protected final List<Function<?, ?>> functions = new ArrayList<Function<?, ?>>();
+
+ private final List<T> initialCollection;
+
+ private final SearchStrategy searchStrategy;
+
+ private final TreeProvider<T> provider;
+
+ protected AbstractQuery(TreeProvider<T> provider, T[] initialCollection, SearchStrategy strategy) {
+ this.provider = provider;
+ this.initialCollection = new ArrayList<T>(Arrays.asList(initialCollection));
+ this.searchStrategy = strategy;
+ }
+
+ protected AbstractQuery(AbstractQuery<T, Q> original, SearchStrategy searchStrategy) {
+ this.functions.addAll(original.functions);
+ this.initialCollection = new ArrayList<T>(original.initialCollection);
+ this.searchStrategy = searchStrategy;
+ this.provider = original.provider;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Iterator<T> iterator() {
+ IteratorToIteratorFunction<T> f = new CompositeFunction<T>(functions);
+ Iterator<Option<T>> iterator = f.apply(new OptionDecoratingIterator<T>(initialCollection.iterator()));
+ iterator = new EmptyElementFilter<T>(iterator);
+ return new OptionStrippingIterator<T>(iterator);
+ }
+
+ /**
+ * Include resources to the collection.
+ *
+ * @param iterable Resources to include
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q add(T... resources) {
+ return function(new AddFunction<T>(Arrays.asList(resources)));
+ }
+
+ /**
+ * Include resources to the collection.
+ *
+ * @param iterable Resources to include
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q add(Iterable<T> iterable) {
+ return function(new AddFunction<T>(iterable));
+ }
+
+ /**
+ * Transform SlingQuery collection into a lazy list.
+ *
+ * @return List containing all elements from the collection.
+ */
+ public List<T> asList() {
+ return new LazyList<T>(iterator());
+ }
+
+ /**
+ * Get list of the children for each Resource in the collection.
+ *
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q children() {
+ return function(new ChildrenFunction<T>(provider));
+ }
+
+ /**
+ * Get list of the children for each Resource in the collection.
+ *
+ * @param filter Children filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q children(String filter) {
+ return function(new ChildrenFunction<T>(provider), filter);
+ }
+
+ /**
+ * Get list of the children for each Resource in the collection.
+ *
+ * @param filter Children filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q children(Predicate<T> filter) {
+ return function(new ChildrenFunction<T>(provider), filter);
+ }
+
+ /**
+ * Get list of the children for each Resource in the collection.
+ *
+ * @param filter Children filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q children(Iterable<T> filter) {
+ return function(new ChildrenFunction<T>(provider), filter);
+ }
+
+ /**
+ * For each Resource in the collection, return the first element matching the selector testing the
+ * Resource itself and traversing up its ancestors.
+ *
+ * @param selector Ancestor filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q closest(String selector) {
+ return closest(parse(selector));
+ }
+
+ /**
+ * For each Resource in the collection, return the first element matching the selector testing the
+ * Resource itself and traversing up its ancestors.
+ *
+ * @param iterable Ancestor filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q closest(Iterable<T> iterable) {
+ return closest(new IterableContainsPredicate<T>(iterable, provider));
+ }
+
+ /**
+ * For each Resource in the collection, return the first element matching the selector testing the
+ * Resource itself and traversing up its ancestors.
+ *
+ * @param selector Ancestor filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q closest(Predicate<T> predicate) {
+ return function(new ClosestFunction<T>(predicate, provider));
+ }
+
+ /**
+ * Reduce Resource collection to the one Resource at the given 0-based index.
+ *
+ * @param index 0-based index
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q eq(int index) {
+ return slice(index, index);
+ }
+
+ /**
+ * Filter Resource collection using given selector.
+ *
+ * @param selector Selector
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q filter(String selector) {
+ return function(new IdentityFunction<T>(), selector);
+ }
+
+ /**
+ * Filter Resource collection using given predicate object.
+ *
+ * @param predicate Collection filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q filter(Predicate<T> predicate) {
+ return function(new FilterFunction<T>(predicate));
+ }
+
+ /**
+ * Filter Resource collection using given iterable.
+ *
+ * @param iterable Collection filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q filter(Iterable<T> iterable) {
+ return function(new FilterFunction<T>(new IterableContainsPredicate<T>(iterable, provider)));
+ }
+
+ /**
+ * For each Resource in collection use depth-first search to return all its descendants. Please notice
+ * that invoking this method on a Resource being a root of a large subtree may and will cause performance
+ * problems.
+ *
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q find() {
+ return function(new FindFunction<T>(searchStrategy, provider, ""));
+ }
+
+ /**
+ * For each Resource in collection use breadth-first search to return all its descendants. Please notice
+ * that invoking this method on a Resource being a root of a large subtree may and will cause performance
+ * problems.
+ *
+ * @param selector descendants filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q find(String selector) {
+ return function(new FindFunction<T>(searchStrategy, provider, selector), selector);
+ }
+
+ /**
+ * For each Resource in collection use breadth-first search to return all its descendants. Please notice
+ * that invoking this method on a Resource being a root of a large subtree may and will cause performance
+ * problems.
+ *
+ * @param predicate descendants filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q find(Predicate<T> predicate) {
+ return function(new FindFunction<T>(searchStrategy, provider, ""), predicate);
+ }
+
+ /**
+ * For each Resource in collection use breadth-first search to return all its descendants. Please notice
+ * that invoking this method on a Resource being a root of a large subtree may and will cause performance
+ * problems.
+ *
+ * @param iterable descendants filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q find(Iterable<T> iterable) {
+ return function(new DescendantFunction<T>(new LazyList<T>(iterable.iterator()), provider));
+ }
+
+ /**
+ * Filter Resource collection to the first element. Equivalent to {@code eq(0)} or {@code slice(0, 0)}.
+ *
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q first() {
+ return eq(0);
+ }
+
+ /**
+ * Pick such Resources from the collection that have descendant matching the selector.
+ *
+ * @param selector Descendant selector
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q has(String selector) {
+ return function(new HasFunction<T>(selector, searchStrategy, provider));
+ }
+
+ /**
+ * Pick such Resources from the collection that have descendant matching the selector.
+ *
+ * @param predicate Descendant selector
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q has(Predicate<T> predicate) {
+ return function(new HasFunction<T>(predicate, searchStrategy, provider));
+ }
+
+ /**
+ * Pick such Resources from the collection that have descendant matching the selector.
+ *
+ * @param iterable Descendant selector
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q has(Iterable<T> iterable) {
+ return function(new HasFunction<T>(iterable, provider));
+ }
+
+ /**
+ * Filter Resource collection to the last element.
+ *
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q last() {
+ return function(new LastFunction<T>());
+ }
+
+ /**
+ * Return the next sibling for each Resource in the collection.
+ *
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q next() {
+ return function(new NextFunction<T>(provider));
+ }
+
+ /**
+ * Return the next sibling for each Resource in the collection and filter it by a selector. If the next
+ * sibling doesn't match it, empty collection will be returned.
+ *
+ * @param selector Next sibling filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q next(String selector) {
+ return function(new NextFunction<T>(provider), selector);
+ }
+
+ /**
+ * Return the next sibling for each Resource in the collection and filter it by a selector. If the next
+ * sibling doesn't match it, empty collection will be returned.
+ *
+ * @param predicate Next sibling filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q next(Predicate<T> predicate) {
+ return function(new NextFunction<T>(provider), predicate);
+ }
+
+ /**
+ * Return the next sibling for each Resource in the collection and filter it by a selector. If the next
+ * sibling doesn't match it, empty collection will be returned.
+ *
+ * @param iterable Next sibling filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q next(Iterable<T> iterable) {
+ return function(new NextFunction<T>(provider), iterable);
+ }
+
+ /**
+ * Return all following siblings for each Resource in the collection.
+ *
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q nextAll() {
+ return function(new NextFunction<T>(new RejectingPredicate<T>(), provider));
+ }
+
+ /**
+ * Return all following siblings for each Resource in the collection, filtering them by a selector.
+ *
+ * @param selector Following siblings filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q nextAll(String selector) {
+ return function(new NextFunction<T>(new RejectingPredicate<T>(), provider), selector);
+ }
+
+ /**
+ * Return all following siblings for each Resource in the collection, filtering them by a selector.
+ *
+ * @param predicate Following siblings filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q nextAll(Predicate<T> predicate) {
+ return function(new NextFunction<T>(new RejectingPredicate<T>(), provider), predicate);
+ }
+
+ /**
+ * Return all following siblings for each Resource in the collection, filtering them by a selector.
+ *
+ * @param iterable Following siblings filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q nextAll(Iterable<T> iterable) {
+ return function(new NextFunction<T>(new RejectingPredicate<T>(), provider), iterable);
+ }
+
+ /**
+ * Return all following siblings for each Resource in the collection up to, but not including, Resource
+ * matched by a selector.
+ *
+ * @param until Selector marking when the operation should stop
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q nextUntil(String until) {
+ return function(new NextFunction<T>(parse(until), provider));
+ }
+
+ /**
+ * Return all following siblings for each Resource in the collection up to, but not including, Resource
+ * matched by a selector.
+ *
+ * @param predicate Selector marking when the operation should stop
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q nextUntil(Predicate<T> predicate) {
+ return function(new NextFunction<T>(predicate, provider));
+ }
+
+ /**
+ * Return all following siblings for each Resource in the collection up to, but not including, Resource
+ * matched by a selector.
+ *
+ * @param iterable Selector marking when the operation should stop
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q nextUntil(Iterable<T> iterable) {
+ return nextUntil(new IterableContainsPredicate<T>(iterable, provider));
+ }
+
+ /**
+ * Remove elements from the collection.
+ *
+ * @param selector Selector used to remove Resources
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q not(String selector) {
+ return function(new NotFunction<T>(parse(selector)));
+ }
+
+ /**
+ * Remove elements from the collection.
+ *
+ * @param predicate Selector used to remove Resources
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q not(Predicate<T> predicate) {
+ return function(new FilterFunction<T>(new RejectingPredicate<T>(predicate)));
+ }
+
+ /**
+ * Remove elements from the collection.
+ *
+ * @param iterable Selector used to remove Resources
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q not(Iterable<T> iterable) {
+ return not(new IterableContainsPredicate<T>(iterable, provider));
+ }
+
+ /**
+ * Replace each element in the collection with its parent.
+ *
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q parent() {
+ return function(new ParentFunction<T>(provider));
+ }
+
+ /**
+ * For each element in the collection find its all ancestor.
+ *
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q parents() {
+ return function(new ParentsFunction<T>(new RejectingPredicate<T>(), provider));
+ }
+
+ /**
+ * For each element in the collection find its all ancestor, filtered by a selector.
+ *
+ * @param selector Parents filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q parents(String selector) {
+ return function(new ParentsFunction<T>(new RejectingPredicate<T>(), provider), selector);
+ }
+
+ /**
+ * For each element in the collection find its all ancestor, filtered by a selector.
+ *
+ * @param predicate Parents filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q parents(Predicate<T> predicate) {
+ return function(new ParentsFunction<T>(new RejectingPredicate<T>(), provider), predicate);
+ }
+
+ /**
+ * For each element in the collection find its all ancestor, filtered by a selector.
+ *
+ * @param predicate Parents filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q parents(Iterable<T> iterable) {
+ return function(new ParentsFunction<T>(new RejectingPredicate<T>(), provider), iterable);
+ }
+
+ /**
+ * For each element in the collection find all of its ancestors until the predicate is met.
+ *
+ * @param until Selector marking when the operation should stop
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q parentsUntil(String until) {
+ return function(new ParentsFunction<T>(parse(until), provider));
+ }
+
+ /**
+ * For each element in the collection find all of its ancestors until the predicate is met.
+ *
+ * @param predicate Selector marking when the operation should stop
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q parentsUntil(Predicate<T> predicate) {
+ return function(new ParentsFunction<T>(predicate, provider));
+ }
+
+ /**
+ * For each element in the collection find all of its ancestors until the predicate is met.
+ *
+ * @param iterable Selector marking when the operation should stop
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q parentsUntil(Iterable<T> iterable) {
+ return parentsUntil(new IterableContainsPredicate<T>(iterable, provider));
+ }
+
+ /**
+ * Return the previous sibling for each Resource in the collection.
+ *
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q prev() {
+ return function(new PrevFunction<T>(provider));
+ }
+
+ /**
+ * Return the previous sibling for each Resource in the collection and filter it by a selector. If the
+ * previous sibling doesn't match it, empty collection will be returned.
+ *
+ * @param selector Previous sibling filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q prev(String selector) {
+ return function(new PrevFunction<T>(null, provider), selector);
+ }
+
+ /**
+ * Return the previous sibling for each Resource in the collection and filter it by a selector. If the
+ * previous sibling doesn't match it, empty collection will be returned.
+ *
+ * @param predicate Previous sibling filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q prev(Predicate<T> predicate) {
+ return function(new PrevFunction<T>(null, provider), predicate);
+ }
+
+ /**
+ * Return the previous sibling for each Resource in the collection and filter it by a selector. If the
+ * previous sibling doesn't match it, empty collection will be returned.
+ *
+ * @param iterable Previous sibling filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q prev(Iterable<T> iterable) {
+ return function(new PrevFunction<T>(null, provider), iterable);
+ }
+
+ /**
+ * Return all previous siblings for each Resource in the collection.
+ *
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q prevAll() {
+ return function(new PrevFunction<T>(new RejectingPredicate<T>(), provider));
+ }
+
+ /**
+ * Return all previous siblings for each Resource in the collection, filtering them by a selector.
+ *
+ * @param selector Previous siblings filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q prevAll(String selector) {
+ return function(new PrevFunction<T>(new RejectingPredicate<T>(), provider), selector);
+ }
+
+ /**
+ * Return all previous siblings for each Resource in the collection, filtering them by a selector.
+ *
+ * @param predicate Previous siblings filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q prevAll(Predicate<T> predicate) {
+ return function(new PrevFunction<T>(new RejectingPredicate<T>(), provider), predicate);
+ }
+
+ /**
+ * Return all previous siblings for each Resource in the collection, filtering them by a selector.
+ *
+ * @param iterable Previous siblings filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q prevAll(Iterable<T> iterable) {
+ return function(new PrevFunction<T>(new RejectingPredicate<T>(), provider), iterable);
+ }
+
+ /**
+ * Return all previous siblings for each Resource in the collection up to, but not including, Resource
+ * matched by a selector.
+ *
+ * @param until Selector marking when the operation should stop
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q prevUntil(String until) {
+ return function(new PrevFunction<T>(parse(until), provider));
+ }
+
+ /**
+ * Return all previous siblings for each Resource in the collection up to, but not including, Resource
+ * matched by a selector.
+ *
+ * @param predicate Selector marking when the operation should stop
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q prevUntil(Predicate<T> predicate) {
+ return function(new PrevFunction<T>(predicate, provider));
+ }
+
+ /**
+ * Return all previous siblings for each Resource in the collection up to, but not including, Resource
+ * matched by a selector.
+ *
+ * @param iterable Selector marking when the operation should stop
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q prevUntil(Iterable<T> iterable) {
+ return prevUntil(new IterableContainsPredicate<T>(iterable, provider));
+ }
+
+ /**
+ * Set new search strategy, which will be used in {@link Q#find()} and {@link Q#has(String)} functions.
+ *
+ * @param strategy Search strategy type
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q searchStrategy(SearchStrategy strategy) {
+ return clone(this, strategy);
+ }
+
+ /**
+ * Return siblings for the given Ts.
+ *
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q siblings() {
+ return siblings("");
+ }
+
+ /**
+ * Return siblings for the given Resources filtered by a selector.
+ *
+ * @param selector Siblings filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q siblings(String selector) {
+ return function(new SiblingsFunction<T>(provider), selector);
+ }
+
+ /**
+ * Return siblings for the given Resources filtered by a selector.
+ *
+ * @param predicate Siblings filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q siblings(Predicate<T> predicate) {
+ return function(new SiblingsFunction<T>(provider), predicate);
+ }
+
+ /**
+ * Return siblings for the given Resources filtered by a selector.
+ *
+ * @param iterable Siblings filter
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q siblings(Iterable<T> iterable) {
+ return function(new SiblingsFunction<T>(provider), iterable);
+ }
+
+ /**
+ * Filter out first {@code from} Resources from the collection.
+ *
+ * @param from How many Resources to cut out
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q slice(int from) {
+ if (from < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ return function(new SliceFunction<T>(from));
+ }
+
+ /**
+ * Reduce the collection to a subcollection specified by a given range. Both from and to are inclusive,
+ * 0-based indices.
+ *
+ * @param from Low endpoint (inclusive) of the subcollection
+ * @param to High endpoint (inclusive) of the subcollection
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q slice(int from, int to) {
+ if (from < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ if (from > to) {
+ throw new IllegalArgumentException();
+ }
+ return function(new SliceFunction<T>(from, to));
+ }
+
+ /**
+ * Filter out repeated adjacent resources.
+ *
+ * @return new SlingQuery object transformed by this operation
+ */
+ public Q unique() {
+ return function(new UniqueFunction<T>(provider));
+ }
+
+ private Q function(Function<?, ?> function, Iterable<T> iterable) {
+ Q newQuery = clone(this, this.searchStrategy);
+ newQuery.functions.add(function);
+ newQuery.functions.add(new FilterFunction<T>(new IterableContainsPredicate<T>(iterable, provider)));
+ return newQuery;
+ }
+
+ private Q function(Function<?, ?> function, Predicate<T> predicate) {
+ Q newQuery = clone(this, this.searchStrategy);
+ newQuery.functions.add(function);
+ newQuery.functions.add(new FilterFunction<T>(predicate));
+ return newQuery;
+ }
+
+ private Q function(Function<?, ?> function, String selector) {
+ Q newQuery = clone(this, this.searchStrategy);
+ newQuery.functions.add(function);
+ newQuery.functions.add(new SelectorFunction<T>(selector, provider, searchStrategy));
+ return newQuery;
+ }
+
+ private Q function(Function<?, ?> function) {
+ Q newQuery = clone(this, this.searchStrategy);
+ newQuery.functions.add(function);
+ return newQuery;
+ }
+
+ private SelectorFunction<T> parse(String selector) {
+ return new SelectorFunction<T>(selector, provider, searchStrategy);
+ }
+
+ protected abstract Q clone(AbstractQuery<T, Q> original, SearchStrategy strategy);
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("$(");
+ Iterator<T> iterator = this.iterator();
+ while (iterator.hasNext()) {
+ builder.append('[');
+ builder.append(iterator.next());
+ builder.append(']');
+ if (iterator.hasNext()) {
+ builder.append(", ");
+ }
+ }
+ builder.append(")");
+ return builder.toString();
+ }
+}
\ No newline at end of file
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/IteratorUtils.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/IteratorUtils.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/IteratorUtils.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/IteratorUtils.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,43 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+public final class IteratorUtils {
+
+ private IteratorUtils() {
+ }
+
+ public static <T> Iterator<T> arrayIterator(T... elements) {
+ return Arrays.asList(elements).iterator();
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> Iterator<T> singleElementIterator(T element) {
+ return Arrays.asList(element).iterator();
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> Iterator<T> emptyIterator() {
+ return Arrays.<T> asList().iterator();
+ }
+}
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/LazyList.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/LazyList.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/LazyList.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/LazyList.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,278 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+public class LazyList<E> implements List<E> {
+
+ private final class LazyListIterator implements ListIterator<E> {
+ private int index = 0;
+
+ private LazyListIterator() {
+ this.index = 0;
+ }
+
+ private LazyListIterator(int index) {
+ this.index = index;
+ }
+
+ @Override
+ public boolean hasNext() {
+ fillToSize(index + 1);
+ return arrayList.size() > index;
+ }
+
+ @Override
+ public E next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ return arrayList.get(index++);
+ }
+
+ @Override
+ public boolean hasPrevious() {
+ return index > 0;
+ }
+
+ @Override
+ public E previous() {
+ if (!hasPrevious()) {
+ throw new NoSuchElementException();
+ }
+ fillToSize(index);
+ return arrayList.get(--index);
+ }
+
+ @Override
+ public int nextIndex() {
+ return index;
+ }
+
+ @Override
+ public int previousIndex() {
+ return index - 1;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void set(E e) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void add(E e) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private final List<E> arrayList;
+
+ private final Iterator<E> iterator;
+
+ public LazyList(Iterator<E> iterator) {
+ this.arrayList = new ArrayList<E>();
+ this.iterator = iterator;
+ }
+
+ private void fillAll() {
+ while (fillNext() != -1)
+ ;
+ }
+
+ private void fillToSize(int size) {
+ for (int s = arrayList.size(); s < size; s++) {
+ if (fillNext() == -1) {
+ break;
+ }
+ }
+ }
+
+ private int fillNext() {
+ if (iterator.hasNext()) {
+ E element = iterator.next();
+ arrayList.add(element);
+ return arrayList.size() - 1;
+ }
+ return -1;
+ }
+
+ @Override
+ public int size() {
+ fillAll();
+ return arrayList.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return arrayList.isEmpty() && !iterator.hasNext();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return indexOf(o) != -1;
+ }
+
+ @Override
+ public Iterator<E> iterator() {
+ return new LazyListIterator();
+ }
+
+ @Override
+ public Object[] toArray() {
+ fillAll();
+ return arrayList.toArray();
+ }
+
+ @Override
+ public <T> T[] toArray(T[] a) {
+ fillAll();
+ return arrayList.toArray(a);
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> c) {
+ for (Object o : c) {
+ if (!contains(o)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public E get(int index) {
+ fillToSize(index + 1);
+ return arrayList.get(index);
+ }
+
+ @Override
+ public int indexOf(Object o) {
+ int index = arrayList.indexOf(o);
+ if (index > -1) {
+ return index;
+ }
+ int addedIndex;
+ while ((addedIndex = fillNext()) != -1) {
+ E element = arrayList.get(addedIndex);
+ if (element == null && o == null) {
+ return addedIndex;
+ } else if (element != null && element.equals(o)) {
+ return addedIndex;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ public int lastIndexOf(Object o) {
+ fillAll();
+ return arrayList.lastIndexOf(o);
+ }
+
+ @Override
+ public ListIterator<E> listIterator() {
+ return new LazyListIterator();
+ }
+
+ @Override
+ public ListIterator<E> listIterator(int index) {
+ return new LazyListIterator(index);
+ }
+
+ @Override
+ public List<E> subList(int fromIndex, int toIndex) {
+ fillToSize(toIndex);
+ return arrayList.subList(fromIndex, toIndex);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ fillAll();
+ return arrayList.equals(o);
+ }
+
+ @Override
+ public int hashCode() {
+ fillAll();
+ return arrayList.hashCode();
+ }
+
+ @Override
+ public boolean add(E e) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends E> c) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean addAll(int index, Collection<? extends E> c) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> c) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> c) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public E set(int index, E element) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void add(int index, E element) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public E remove(int index) {
+ throw new UnsupportedOperationException();
+ }
+
+}
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/SlingQuery.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/SlingQuery.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/SlingQuery.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/SlingQuery.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,95 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query;
+
+import java.util.Iterator;
+
+import org.apache.sling.api.adapter.Adaptable;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.query.api.SearchStrategy;
+import org.apache.sling.query.iterator.AdaptToIterator;
+import org.apache.sling.query.resource.ResourceTreeProvider;
+
+/**
+ * SlingQuery is a Sling resource tree traversal tool inspired by the jQuery.
+ *
+ * @author Tomasz RÄkawek
+ */
+public class SlingQuery extends AbstractQuery<Resource, SlingQuery> {
+
+ private SlingQuery(AbstractQuery<Resource, SlingQuery> original, SearchStrategy strategy) {
+ super(original, strategy);
+ }
+
+ private SlingQuery(Resource[] resources, SearchStrategy strategy) {
+ super(new ResourceTreeProvider(resources[0].getResourceResolver()), resources, strategy);
+ }
+
+ public static SlingQuery $(Resource... resources) {
+ if (resources.length == 0) {
+ throw new IllegalArgumentException("Initial collection can't be empty");
+ } else {
+ return new SlingQuery(resources, SearchStrategy.QUERY);
+ }
+ }
+
+ public static SlingQuery $(ResourceResolver resolver) {
+ return $(resolver.getResource("/"));
+ }
+
+ /**
+ * Transform the whole collection to a new {@link Iterable} object, invoking
+ * {@link Adaptable#adaptTo(Class)} method on each Resource. If some Resource can't be adapted to the
+ * class (eg. {@code adaptTo()} returns {@code null}), it will be skipped.
+ *
+ * @param clazz Class used to adapt the Resources
+ * @return new iterable containing succesfully adapted Resources
+ */
+ public <E> Iterable<E> map(final Class<? extends E> clazz) {
+ return new Iterable<E>() {
+ @Override
+ public Iterator<E> iterator() {
+ return new AdaptToIterator<Resource, E>(SlingQuery.this.iterator(), clazz);
+ }
+ };
+ }
+
+ @Override
+ protected SlingQuery clone(AbstractQuery<Resource, SlingQuery> original, SearchStrategy strategy) {
+ return new SlingQuery(original, strategy);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("$(");
+ Iterator<Resource> iterator = this.iterator();
+ while (iterator.hasNext()) {
+ builder.append(iterator.next().getPath());
+ if (iterator.hasNext()) {
+ builder.append(", ");
+ }
+ }
+ builder.append(")");
+ return builder.toString();
+ }
+
+}
\ No newline at end of file
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/Function.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/Function.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/Function.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/Function.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,38 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query.api;
+
+/**
+ * Function can transform one value into another.
+ *
+ * @author Tomasz RÄkawek
+ *
+ * @param <F> Input type
+ * @param <T> Output type
+ */
+public interface Function<F, T> {
+ /**
+ * Take input F and transform it into output T.
+ *
+ * @param input Input value
+ * @return Output value
+ */
+ T apply(F input);
+}
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/Predicate.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/Predicate.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/Predicate.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/Predicate.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,36 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query.api;
+
+/**
+ * ResourcePredicate determine true or false value for a given T.
+ *
+ * @author Tomasz RÄkawek
+ *
+ */
+public interface Predicate<T> {
+ /**
+ * Accept or reject given resource.
+ *
+ * @param element Object to test
+ * @return {@code true} or {@code false}
+ */
+ boolean accepts(T element);
+}
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/SearchStrategy.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/SearchStrategy.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/SearchStrategy.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/SearchStrategy.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,24 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query.api;
+
+public enum SearchStrategy {
+ BFS, DFS, QUERY;
+}
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/TreeProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/TreeProvider.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/TreeProvider.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/TreeProvider.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,42 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query.api;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.sling.query.selector.parser.Attribute;
+import org.apache.sling.query.selector.parser.SelectorSegment;
+
+public interface TreeProvider<T> {
+ Iterator<T> listChildren(T parent);
+
+ T getParent(T element);
+
+ String getName(T element);
+
+ Predicate<T> getPredicate(String type, String name, List<Attribute> attributes);
+
+ Iterator<T> query(List<SelectorSegment> segment, T resource);
+
+ boolean sameElement(T o1, T o2);
+
+ boolean isDescendant(T root, T testedElement);
+}
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/ElementToIteratorFunction.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/ElementToIteratorFunction.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/ElementToIteratorFunction.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/ElementToIteratorFunction.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,27 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query.api.function;
+
+import java.util.Iterator;
+
+import org.apache.sling.query.api.Function;
+
+public interface ElementToIteratorFunction<T> extends Function<T, Iterator<T>> {
+}
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/IteratorToIteratorFunction.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/IteratorToIteratorFunction.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/IteratorToIteratorFunction.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/IteratorToIteratorFunction.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,27 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query.api.function;
+
+import java.util.Iterator;
+
+import org.apache.sling.query.api.Function;
+
+public interface IteratorToIteratorFunction<T> extends Function<Iterator<Option<T>>, Iterator<Option<T>>> {
+}
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/Option.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/Option.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/Option.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/api/function/Option.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,82 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query.api.function;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+public class Option<T> {
+ private final T element;
+
+ private final int argumentId;
+
+ private Option(T element, int argumentId) {
+ this.element = element;
+ this.argumentId = argumentId;
+ }
+
+ public static <T> Option<T> of(T element, int argumentId) {
+ return new Option<T>(element, argumentId);
+ }
+
+ public static <T> Option<T> empty(int argumentId) {
+ return new Option<T>(null, argumentId);
+ }
+
+ public int getArgumentId() {
+ return argumentId;
+ }
+
+ public T getElement() {
+ return element;
+ }
+
+ public boolean isEmpty() {
+ return element == null;
+ }
+
+ public String toString() {
+ if (isEmpty()) {
+ return "Option[-]";
+ } else {
+ return String.format("Option[%s]", element.toString());
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (obj == this) {
+ return true;
+ }
+ if (obj.getClass() != getClass()) {
+ return false;
+ }
+ Option<?> rhs = (Option<?>) obj;
+ return new EqualsBuilder().append(element, rhs.element).isEquals();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(element).toHashCode();
+ }
+}
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/AddFunction.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/AddFunction.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/AddFunction.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/AddFunction.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,43 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query.function;
+
+import java.util.Iterator;
+
+import org.apache.sling.query.api.function.IteratorToIteratorFunction;
+import org.apache.sling.query.api.function.Option;
+import org.apache.sling.query.iterator.MergingIterator;
+import org.apache.sling.query.iterator.OptionDecoratingIterator;
+
+public class AddFunction<T> implements IteratorToIteratorFunction<T> {
+
+ private final Iterable<T> iterable;
+
+ public AddFunction(Iterable<T> iterable) {
+ this.iterable = iterable;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Iterator<Option<T>> apply(Iterator<Option<T>> input) {
+ return new MergingIterator<Option<T>>(input, new OptionDecoratingIterator<T>(iterable.iterator()));
+ }
+
+}
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/ChildrenFunction.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/ChildrenFunction.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/ChildrenFunction.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/ChildrenFunction.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,39 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query.function;
+
+import java.util.Iterator;
+
+import org.apache.sling.query.api.TreeProvider;
+import org.apache.sling.query.api.function.ElementToIteratorFunction;
+
+public class ChildrenFunction<T> implements ElementToIteratorFunction<T> {
+
+ private final TreeProvider<T> provider;
+
+ public ChildrenFunction(TreeProvider<T> provider) {
+ this.provider = provider;
+ }
+
+ @Override
+ public Iterator<T> apply(T parent) {
+ return provider.listChildren(parent);
+ }
+}
\ No newline at end of file
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/ClosestFunction.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/ClosestFunction.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/ClosestFunction.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/ClosestFunction.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,51 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query.function;
+
+import java.util.Iterator;
+
+import org.apache.sling.query.IteratorUtils;
+import org.apache.sling.query.api.Predicate;
+import org.apache.sling.query.api.TreeProvider;
+import org.apache.sling.query.api.function.ElementToIteratorFunction;
+
+public class ClosestFunction<T> implements ElementToIteratorFunction<T> {
+
+ private final Predicate<T> predicate;
+
+ private final TreeProvider<T> provider;
+
+ public ClosestFunction(Predicate<T> predicate, TreeProvider<T> provider) {
+ this.predicate = predicate;
+ this.provider = provider;
+ }
+
+ @Override
+ public Iterator<T> apply(T resource) {
+ T current = resource;
+ while (current != null) {
+ if (predicate.accepts(current)) {
+ return IteratorUtils.singleElementIterator(current);
+ }
+ current = provider.getParent(current);
+ }
+ return IteratorUtils.emptyIterator();
+ }
+}
\ No newline at end of file
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/CompositeFunction.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/CompositeFunction.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/CompositeFunction.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/CompositeFunction.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,45 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query.function;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.sling.query.api.Function;
+import org.apache.sling.query.api.function.IteratorToIteratorFunction;
+import org.apache.sling.query.api.function.Option;
+
+public class CompositeFunction<T> implements IteratorToIteratorFunction<T> {
+
+ private final List<Function<?, ?>> functions;
+
+ public CompositeFunction(List<Function<?, ?>> functions) {
+ this.functions = functions;
+ }
+
+ @Override
+ public Iterator<Option<T>> apply(Iterator<Option<T>> input) {
+ Iterator<Option<T>> iterator = input;
+ for (Function<?, ?> f : functions) {
+ iterator = new IteratorToIteratorFunctionWrapper<T>(f).apply(iterator);
+ }
+ return iterator;
+ }
+}
Added: sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/DescendantFunction.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/DescendantFunction.java?rev=1613419&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/DescendantFunction.java (added)
+++ sling/trunk/contrib/extensions/sling-query/src/main/java/org/apache/sling/query/function/DescendantFunction.java Fri Jul 25 12:45:33 2014
@@ -0,0 +1,45 @@
+/*-
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.query.function;
+
+import java.util.Iterator;
+
+import org.apache.sling.query.api.TreeProvider;
+import org.apache.sling.query.api.function.IteratorToIteratorFunction;
+import org.apache.sling.query.api.function.Option;
+import org.apache.sling.query.iterator.DescendantsIterator;
+
+public class DescendantFunction<T> implements IteratorToIteratorFunction<T> {
+
+ private final Iterable<T> descendants;
+
+ private final TreeProvider<T> provider;
+
+ public DescendantFunction(Iterable<T> descendants, TreeProvider<T> provider) {
+ this.descendants = descendants;
+ this.provider = provider;
+ }
+
+ @Override
+ public Iterator<Option<T>> apply(Iterator<Option<T>> input) {
+ return new DescendantsIterator<T>(input, descendants.iterator(), provider);
+ }
+
+}