You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by dk...@apache.org on 2018/01/26 04:01:56 UTC

[sling-org-apache-sling-scripting-jsp-taglib] branch master updated: Adding the GetParent and GetParents Tags and EL Functions as per SLING-7448

This is an automated email from the ASF dual-hosted git repository.

dklco pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-jsp-taglib.git


The following commit(s) were added to refs/heads/master by this push:
     new bac1c8c  Adding the GetParent and GetParents Tags and EL Functions as per SLING-7448
bac1c8c is described below

commit bac1c8c36d04bf8f3d4feb29fe9f72f926d77225
Author: Dan Klco <da...@gmail.com>
AuthorDate: Thu Jan 25 20:00:36 2018 -0800

    Adding the GetParent and GetParents Tags and EL Functions as per SLING-7448
---
 .../sling/scripting/jsp/taglib/GetParentTag.java   | 127 ++++++++++++++++++++
 .../sling/scripting/jsp/taglib/GetParentsTag.java  | 132 +++++++++++++++++++++
 .../sling/scripting/jsp/taglib/SlingFunctions.java |  88 +++++++++++---
 .../sling/scripting/jsp/taglib/package-info.java   |   2 +-
 src/main/resources/META-INF/sling.tld              |  96 +++++++++++++++
 .../sling/scripting/jsp/taglib/TestEncodeTag.java  |   6 +-
 .../scripting/jsp/taglib/TestGetParentTag.java     | 127 ++++++++++++++++++++
 .../scripting/jsp/taglib/TestGetParentsTag.java    | 131 ++++++++++++++++++++
 8 files changed, 684 insertions(+), 25 deletions(-)

diff --git a/src/main/java/org/apache/sling/scripting/jsp/taglib/GetParentTag.java b/src/main/java/org/apache/sling/scripting/jsp/taglib/GetParentTag.java
new file mode 100644
index 0000000..ec26142
--- /dev/null
+++ b/src/main/java/org/apache/sling/scripting/jsp/taglib/GetParentTag.java
@@ -0,0 +1,127 @@
+/*
+ * 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.scripting.jsp.taglib;
+
+import java.util.Arrays;
+
+import javax.servlet.jsp.tagext.TagSupport;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.sling.api.resource.Resource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tag for retrieving a parent resource based on the absolute parent level
+ */
+public class GetParentTag extends TagSupport {
+
+	/** The Constant log. */
+	private static final Logger log = LoggerFactory.getLogger(GetParentTag.class);
+
+	/** The Constant serialVersionUID. */
+	private static final long serialVersionUID = -3419869755342010983L;
+
+	/** The current resource. */
+	private Resource resource;
+
+	/** The level. */
+	private String level;
+
+	/** The var. */
+	private String var;
+
+	@Override
+	public int doEndTag() {
+		log.trace("doEndTag");
+
+		Resource parent = null;
+
+		if (level != null) {
+			String[] segments = resource.getPath().split("\\/");
+			int end = Integer.parseInt(level, 10);
+			String parentPath = "/"+StringUtils.join(Arrays.copyOfRange(segments, 1, end + 1), "/");
+			log.debug("Retrieving {} parent resource at path {}", level, parentPath);
+			parent = resource.getResourceResolver().getResource(parentPath);
+		} else {
+			log.debug("Retrieving parent resource");
+			parent = resource.getParent();
+		}
+
+		log.debug("Saving {} to variable {}", parent, var);
+		pageContext.setAttribute(var, parent);
+
+		return EVAL_PAGE;
+	}
+
+	/**
+	 * Gets the resource.
+	 * 
+	 * @return the base resource
+	 */
+	public Resource getResource() {
+		return resource;
+	}
+	
+	/**
+	 * Get the level of the parent resource to retrieve.
+	 * 
+	 * @return the level
+	 */
+	public String getLevel() {
+		return level;
+	}
+
+	/**
+	 * Gets the variable name to which to save the list of children.
+	 * 
+	 * @return the variable name
+	 */
+	public String getVar() {
+		return var;
+	}
+
+	/**
+	 * Sets the resource.
+	 * 
+	 * @param base
+	 *            the new resource
+	 */
+	public void setResource(Resource resource) {
+		this.resource = resource;
+	}
+
+	/**
+	 * Set the level of the parent resource to retrieve.
+	 * 
+	 * @param level
+	 *            the level
+	 */
+	public void setLevel(String level) {
+		this.level = level;
+	}
+
+	/**
+	 * Sets the variable name to which to save the parent resource.
+	 * 
+	 * @param var
+	 *            the variable name
+	 */
+	public void setVar(String var) {
+		this.var = var;
+	}
+}
diff --git a/src/main/java/org/apache/sling/scripting/jsp/taglib/GetParentsTag.java b/src/main/java/org/apache/sling/scripting/jsp/taglib/GetParentsTag.java
new file mode 100644
index 0000000..67c1b16
--- /dev/null
+++ b/src/main/java/org/apache/sling/scripting/jsp/taglib/GetParentsTag.java
@@ -0,0 +1,132 @@
+/*
+ * 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.scripting.jsp.taglib;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.servlet.jsp.tagext.TagSupport;
+
+import org.apache.sling.api.resource.Resource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tag for retrieving all of the parent resources of a specified resource,
+ * returning them in hierarchy order.
+ */
+public class GetParentsTag extends TagSupport {
+
+	/** The Constant log. */
+	private static final Logger log = LoggerFactory.getLogger(GetParentsTag.class);
+
+	/** The Constant serialVersionUID. */
+	private static final long serialVersionUID = -7519905660523764503L;
+
+	/** The current resource. */
+	private Resource resource;
+
+	/** The startDepth. */
+	private String startDepth = "0";
+
+	/** The var. */
+	private String var;
+
+	@Override
+	public int doEndTag() {
+		log.trace("doEndTag");
+
+		List<Resource> parents = new ArrayList<Resource>();
+		Resource current = resource;
+		while (true) {
+			Resource parent = current.getParent();
+			if(parent != null){
+				parents.add(parent);
+				current = parent;
+			} else {
+				break;
+			}
+		}
+		Collections.reverse(parents);
+	
+		parents = parents.subList(Integer.parseInt(startDepth,10), parents.size());
+
+		log.debug("Saving {} to variable {}", parents, var);
+		pageContext.setAttribute(var, parents.iterator());
+
+		return EVAL_PAGE;
+	}
+
+	/**
+	 * Gets the resource.
+	 * 
+	 * @return the base resource
+	 */
+	public Resource getResource() {
+		return resource;
+	}
+
+	/**
+	 * Retrieves the start depth
+	 * 
+	 * @return the start depth to retrieve
+	 */
+	public String getStartDepth() {
+		return startDepth;
+	}
+
+	/**
+	 * Gets the variable name to which to save the list of children.
+	 * 
+	 * @return the variable name
+	 */
+	public String getVar() {
+		return var;
+	}
+
+	/**
+	 * Sets the resource.
+	 * 
+	 * @param base
+	 *            the new resource
+	 */
+	public void setResource(Resource resource) {
+		this.resource = resource;
+	}
+
+	/**
+	 * The depth at which to start, for example given a path of:
+	 * /content/page1/page2/page3 and a start depth of 3, the parents
+	 * page2/page3 would be returned
+	 * 
+	 * @param startDepth
+	 */
+	public void setStartDepth(String startDepth) {
+		this.startDepth = startDepth;
+	}
+
+	/**
+	 * Sets the variable name to which to save the parent resource.
+	 * 
+	 * @param var
+	 *            the variable name
+	 */
+	public void setVar(String var) {
+		this.var = var;
+	}
+}
diff --git a/src/main/java/org/apache/sling/scripting/jsp/taglib/SlingFunctions.java b/src/main/java/org/apache/sling/scripting/jsp/taglib/SlingFunctions.java
index a86ad39..80dcef0 100644
--- a/src/main/java/org/apache/sling/scripting/jsp/taglib/SlingFunctions.java
+++ b/src/main/java/org/apache/sling/scripting/jsp/taglib/SlingFunctions.java
@@ -16,8 +16,13 @@
  */
 package org.apache.sling.scripting.jsp.taglib;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.Iterator;
+import java.util.List;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.sling.api.adapter.Adaptable;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
@@ -34,8 +39,7 @@ public class SlingFunctions {
 	/**
 	 * The SLF4J Logger.
 	 */
-	private static final Logger log = LoggerFactory
-			.getLogger(SlingFunctions.class);
+	private static final Logger log = LoggerFactory.getLogger(SlingFunctions.class);
 
 	/**
 	 * Adapt the adaptable to the adapter class.
@@ -46,8 +50,7 @@ public class SlingFunctions {
 	 *            the class to which to adapt the adaptable
 	 * @return the adapted class instance
 	 */
-	public static Object adaptTo(Adaptable adaptable, String adapter)
-			throws ClassNotFoundException {
+	public static Object adaptTo(Adaptable adaptable, String adapter) throws ClassNotFoundException {
 		log.trace("adaptTo");
 		Object adapted = null;
 
@@ -71,7 +74,8 @@ public class SlingFunctions {
 	 * @param value
 	 *            The text to encode
 	 * @param mode
-	 *            The XSS mode to use, see XSSSupport for the list of available modes
+	 *            The XSS mode to use, see XSSSupport for the list of available
+	 *            modes
 	 * @return the encoded text
 	 */
 	public static String encode(String value, String mode) {
@@ -89,14 +93,12 @@ public class SlingFunctions {
 	 *            The language in which the query is formulated.
 	 * @return An Iterator of Resource objects matching the query.
 	 */
-	public static Iterator<Resource> findResources(
-			ResourceResolver resourceResolver, String query, String language) {
+	public static Iterator<Resource> findResources(ResourceResolver resourceResolver, String query, String language) {
 		log.trace("findResources");
 
 		Iterator<Resource> resources = null;
 		if (resourceResolver != null) {
-			log.debug("Finding resources with query {} of type {}", query,
-					language);
+			log.debug("Finding resources with query {} of type {}", query, language);
 			resources = resourceResolver.findResources(query, language);
 		} else {
 			log.warn("Null resolver specified");
@@ -105,6 +107,59 @@ public class SlingFunctions {
 	}
 
 	/**
+	 * Method for retrieving an absolute parent resource.
+	 * 
+	 * @param current
+	 *            the current resource
+	 * @param level
+	 *            the absolute level for the parent resource to retrieve
+	 * @return the parent resource at the level
+	 */
+	public static final Resource getAbsoluteParent(Resource current, String level) {
+		log.trace("getAbsoluteParent");
+		Resource parent = null;
+		if (level != null) {
+			String[] segments = current.getPath().split("\\/");
+			int end = Integer.parseInt(level, 10);
+			String parentPath = "/" + StringUtils.join(Arrays.copyOfRange(segments, 1, end + 1), "/");
+			log.debug("Retrieving {} parent resource at path {}", level, parentPath);
+			parent = current.getResourceResolver().getResource(parentPath);
+		} else {
+			log.debug("Retrieving parent resource");
+			parent = current.getParent();
+		}
+		return parent;
+	}
+
+	/**
+	 * Function for retrieving all of the parent resources of a specified
+	 * resource, returning them in hierarchy order.
+	 * 
+	 * @param current
+	 *            the current resource for which to retrieve the parents
+	 * @param startDepth
+	 *            The depth at which to start, for example given a path of:
+	 *            /content/page1/page2/page3 and a start depth of 3, the parents
+	 *            page2/page3 would be returned
+	 * @return an iterator of the parent resources in order
+	 */
+	public static final Iterator<Resource> getParents(Resource current, String startDepth) {
+		List<Resource> parents = new ArrayList<Resource>();
+		while (true) {
+			Resource parent = current.getParent();
+			if (parent != null) {
+				parents.add(parent);
+				current = parent;
+			} else {
+				break;
+			}
+		}
+		Collections.reverse(parents);
+
+		return parents.subList(Integer.parseInt(startDepth, 10), parents.size()).iterator();
+	}
+
+	/**
 	 * Gets the resource at the relative path to the provided resource.
 	 * 
 	 * @param base
@@ -118,8 +173,7 @@ public class SlingFunctions {
 
 		Resource relative = null;
 		if (base != null) {
-			log.debug("Getting relative resource of {} at path {}",
-					base.getPath(), path);
+			log.debug("Getting relative resource of {} at path {}", base.getPath(), path);
 			relative = base.getResourceResolver().getResource(base, path);
 		} else {
 			log.warn("Null base resource specified");
@@ -137,8 +191,7 @@ public class SlingFunctions {
 	 *            the path of the resource to retrieve
 	 * @return the resource at the path or null
 	 */
-	public static final Resource getResource(ResourceResolver resolver,
-			String path) {
+	public static final Resource getResource(ResourceResolver resolver, String path) {
 		log.trace("getResource");
 
 		log.debug("Getting resource at path {}", path);
@@ -163,8 +216,7 @@ public class SlingFunctions {
 	 * @return
 	 */
 	@SuppressWarnings("unchecked")
-	public static final <E> E getValue(ValueMap properties, String key,
-			Object defaultOrType) {
+	public static final <E> E getValue(ValueMap properties, String key, Object defaultOrType) {
 		if (defaultOrType instanceof Class<?>) {
 			return properties.get(key, (Class<E>) defaultOrType);
 		} else {
@@ -215,10 +267,8 @@ public class SlingFunctions {
 	 * @throws ClassNotFoundException
 	 *             a class with the specified name could not be found
 	 */
-	private static Class<?> loadClass(String className)
-			throws ClassNotFoundException {
-		return Thread.currentThread().getContextClassLoader()
-				.loadClass(className);
+	private static Class<?> loadClass(String className) throws ClassNotFoundException {
+		return Thread.currentThread().getContextClassLoader().loadClass(className);
 	}
 
 }
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/scripting/jsp/taglib/package-info.java b/src/main/java/org/apache/sling/scripting/jsp/taglib/package-info.java
index 97e188b..687395e 100644
--- a/src/main/java/org/apache/sling/scripting/jsp/taglib/package-info.java
+++ b/src/main/java/org/apache/sling/scripting/jsp/taglib/package-info.java
@@ -16,6 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-@org.osgi.annotation.versioning.Version("2.2.0")
+@org.osgi.annotation.versioning.Version("2.3.0")
 package org.apache.sling.scripting.jsp.taglib;
 
diff --git a/src/main/resources/META-INF/sling.tld b/src/main/resources/META-INF/sling.tld
index 8d784ad..878c91b 100644
--- a/src/main/resources/META-INF/sling.tld
+++ b/src/main/resources/META-INF/sling.tld
@@ -35,6 +35,18 @@
 		<function-class>org.apache.sling.scripting.jsp.taglib.SlingFunctions</function-class>
 		<function-signature>java.util.Iterator findResources(org.apache.sling.api.resource.ResourceResolver, java.lang.String, java.lang.String)</function-signature>
 	</function>
+	
+	<function>
+		<name>getAbsoluteParent</name>
+		<function-class>org.apache.sling.scripting.jsp.taglib.SlingFunctions</function-class>
+		<function-signature>org.apache.sling.api.resource.Resource getAbsoluteParent(org.apache.sling.api.resource.Resource,java.lang.String)</function-signature>
+	</function>
+
+	<function>
+		<name>getParents</name>
+		<function-class>org.apache.sling.scripting.jsp.taglib.SlingFunctions</function-class>
+		<function-signature>java.util.Iterator getParents(org.apache.sling.api.resource.Resource,java.lang.String)</function-signature>
+	</function>
 
 	<function>
 		<name>getRelativeResource</name>
@@ -518,6 +530,90 @@
 			<rtexprvalue>true</rtexprvalue>
 		</attribute>
 	</tag>
+	
+	<tag>
+		<description>
+			Retrieves the parent of the resource or the absolute parent 
+			at the level if specified.
+		</description>
+		<name>getParent</name>
+		<tag-class>
+			org.apache.sling.scripting.jsp.taglib.GetParentTag
+		</tag-class>
+        <tei-class>
+            org.apache.sling.scripting.jsp.taglib.tei.ResourceVariableTEI
+        </tei-class>
+		<body-content>empty</body-content>
+		<attribute>
+			<description>
+				The name of the variable to which to save the parent resource.
+			</description>
+			<name>var</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+		<attribute>
+			<description>
+				The resource for which to retrieve the parent resource.
+			</description>
+			<name>resource</name>
+			<required>true</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+		<attribute>
+			<description>
+				The level of the parent resource to retrieve
+			</description>
+			<name>level</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+	</tag>
+	
+	
+	<tag>
+		<description>
+			Retrieves all of the parent resources of a specified
+			resource, returning them
+			in hierarchy order.
+		</description>
+		<name>getParents</name>
+		<tag-class>
+			org.apache.sling.scripting.jsp.taglib.GetParentsTag
+		</tag-class>
+		<tei-class>
+			org.apache.sling.scripting.jsp.taglib.tei.ResourceIteratorVariableTEI
+		</tei-class>
+		<body-content>empty</body-content>
+		<attribute>
+			<description>
+				The name of the variable to which to save the parent
+				resources.
+			</description>
+			<name>var</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+		<attribute>
+			<description>
+				The resource for which to retrieve the parent resources.
+			</description>
+			<name>resource</name>
+			<required>true</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+		<attribute>
+			<description>
+				The depth at which to start, for example given a path
+				of: /content/page1/page2/page3 and a start depth of 3, the parents
+				page2/page3 would be returned
+			</description>
+			<name>startDepth</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+	</tag>
+	
 
 	<tag>
 		<description>
diff --git a/src/test/java/org/apache/sling/scripting/jsp/taglib/TestEncodeTag.java b/src/test/java/org/apache/sling/scripting/jsp/taglib/TestEncodeTag.java
index a418fb7..75aa81b 100644
--- a/src/test/java/org/apache/sling/scripting/jsp/taglib/TestEncodeTag.java
+++ b/src/test/java/org/apache/sling/scripting/jsp/taglib/TestEncodeTag.java
@@ -17,15 +17,12 @@
 package org.apache.sling.scripting.jsp.taglib;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
 
 import javax.servlet.jsp.JspException;
 import javax.servlet.jsp.JspWriter;
 
-import org.apache.sling.api.resource.ValueMap;
 import org.junit.Before;
 import org.junit.Test;
 import org.slf4j.Logger;
@@ -43,12 +40,11 @@ public class TestEncodeTag {
 	private EncodeTag encodeTag;
 	private MockPageContext pageContext;
 	private StringBuilder sb;
-	private static final String VAR_KEY = "properties";
+
 
 	/**
 	 * Initializes the fields for this test.
 	 */
-	@SuppressWarnings("serial")
 	@Before
 	public void init() {
 		log.info("init");
diff --git a/src/test/java/org/apache/sling/scripting/jsp/taglib/TestGetParentTag.java b/src/test/java/org/apache/sling/scripting/jsp/taglib/TestGetParentTag.java
new file mode 100644
index 0000000..5b15892
--- /dev/null
+++ b/src/test/java/org/apache/sling/scripting/jsp/taglib/TestGetParentTag.java
@@ -0,0 +1,127 @@
+/*
+ * 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.scripting.jsp.taglib;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.commons.testing.sling.MockResource;
+import org.apache.sling.commons.testing.sling.MockResourceResolver;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Unit Tests for the Class GetResourceTag.
+ * 
+ * @see org.apache.sling.scripting.jsp.taglib.GetResourceTag
+ */
+public class TestGetParentTag {
+
+	private static final Logger log = LoggerFactory
+			.getLogger(TestGetParentTag.class);
+	private GetParentTag getParentTag;
+	private MockResource resource;
+	private MockPageContext pageContext;
+	private MockResource child;
+	private static final String VAR_KEY = "resource";
+	private static final String TEST_ABSOLUTE_PATH = "/content";
+	private static final String TEST_RELATIVE_PATH = "test";
+
+	/**
+	 * Initializes the fields for this test.
+	 */
+	@Before
+	public void init() {
+		log.info("init");
+
+		final MockResourceResolver resolver = new MockResourceResolver();
+
+		resource = new MockResource(resolver, TEST_ABSOLUTE_PATH, "test");
+		resolver.addResource(resource);
+
+		child = new MockResource(resolver, TEST_ABSOLUTE_PATH
+				+ "/" + TEST_RELATIVE_PATH, "test");
+		resolver.addResource(child);
+
+		getParentTag = new GetParentTag();
+
+		pageContext = new MockPageContext();
+		getParentTag.setPageContext(pageContext);
+
+		log.info("init Complete");
+	}
+
+	/**
+	 * Tests using an absolute path.
+	 */
+	@Test
+	public void testAbsoluteParent() {
+		log.info("testAbsoluteParent");
+
+		getParentTag.setVar(VAR_KEY);
+		getParentTag.setResource(child);
+		getParentTag.setLevel("1");
+		getParentTag.doEndTag();
+		Object result = pageContext.getAttribute(VAR_KEY);
+		assertNotNull(result);
+		assertTrue(result instanceof Resource);
+		assertEquals(TEST_ABSOLUTE_PATH, ((Resource) result).getPath());
+
+		log.info("Test successful!");
+	}
+
+	/**
+	 * Tests using an relative path.
+	 */
+	@Test
+	public void testParent() {
+		log.info("testParent");
+
+		getParentTag.setVar(VAR_KEY);
+		getParentTag.setResource(child);
+		getParentTag.doEndTag();
+		Object result = pageContext.getAttribute(VAR_KEY);
+		assertNotNull(result);
+		assertTrue(result instanceof Resource);
+		assertEquals(TEST_ABSOLUTE_PATH, ((Resource) result).getPath());
+
+		log.info("Test successful!");
+	}
+
+	/**
+	 * Tests to see what happens if a bad path is specified, this should just
+	 * return a null value instead of a resource.
+	 */
+	@Test
+	public void testBadPath() {
+		log.info("testBadPath");
+
+		getParentTag.setVar(VAR_KEY);
+		getParentTag.setResource(child);
+		getParentTag.setLevel("4");
+		getParentTag.doEndTag();
+		Object result = pageContext.getAttribute(VAR_KEY);
+		assertNull(result);
+
+		log.info("Test successful!");
+	}
+}
diff --git a/src/test/java/org/apache/sling/scripting/jsp/taglib/TestGetParentsTag.java b/src/test/java/org/apache/sling/scripting/jsp/taglib/TestGetParentsTag.java
new file mode 100644
index 0000000..122b454
--- /dev/null
+++ b/src/test/java/org/apache/sling/scripting/jsp/taglib/TestGetParentsTag.java
@@ -0,0 +1,131 @@
+/*
+ * 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.scripting.jsp.taglib;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Iterator;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.commons.testing.sling.MockResource;
+import org.apache.sling.commons.testing.sling.MockResourceResolver;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Unit Tests for the Class GetResourceTag.
+ * 
+ * @see org.apache.sling.scripting.jsp.taglib.GetResourceTag
+ */
+public class TestGetParentsTag {
+
+	private static final Logger log = LoggerFactory
+			.getLogger(TestGetParentsTag.class);
+	private GetParentsTag getParentsTag;
+	private MockResource resource;
+	private MockPageContext pageContext;
+	private MockResource child;
+	private MockResource root;
+	private static final String VAR_KEY = "resource";
+	private static final String TEST_ABSOLUTE_PATH = "/content";
+	private static final String TEST_RELATIVE_PATH = "test";
+
+	/**
+	 * Initializes the fields for this test.
+	 */
+	@Before
+	public void init() {
+		log.info("init");
+
+		final MockResourceResolver resolver = new MockResourceResolver();
+
+
+		root = new MockResource(resolver, "/", "test");
+		resolver.addResource(root);
+		
+		resource = new MockResource(resolver, TEST_ABSOLUTE_PATH, "test");
+		resolver.addResource(resource);
+
+		child = new MockResource(resolver, TEST_ABSOLUTE_PATH
+				+ "/" + TEST_RELATIVE_PATH, "test");
+		resolver.addResource(child);
+
+		getParentsTag = new GetParentsTag();
+
+		pageContext = new MockPageContext();
+		getParentsTag.setPageContext(pageContext);
+
+		log.info("init Complete");
+	}
+
+	/**
+	 * Tests basic functionality.
+	 */
+	@Test
+	public void testParents() {
+		log.info("testParents");
+
+		getParentsTag.setVar(VAR_KEY);
+		getParentsTag.setResource(child);
+		getParentsTag.setStartDepth("0");
+		getParentsTag.doEndTag();
+		Object result = pageContext.getAttribute(VAR_KEY);
+		assertNotNull(result);
+		assertTrue(result instanceof Iterator);
+		@SuppressWarnings("unchecked")
+		Iterator<Resource> parents = (Iterator<Resource>)result;
+		assertTrue(parents.hasNext());
+	
+		assertEquals("/", parents.next().getPath());
+		assertTrue(parents.hasNext());
+		assertEquals(TEST_ABSOLUTE_PATH, parents.next().getPath());
+		assertFalse(parents.hasNext());
+
+		log.info("Test successful!");
+	}
+	
+
+	/**
+	 * Tests basic functionality.
+	 */
+	@Test
+	public void testParentsWithStartDepth() {
+		log.info("testParentsWithStartDepth");
+
+		getParentsTag.setVar(VAR_KEY);
+		getParentsTag.setResource(child);
+		getParentsTag.setStartDepth("1");
+		getParentsTag.doEndTag();
+		Object result = pageContext.getAttribute(VAR_KEY);
+		assertNotNull(result);
+		assertTrue(result instanceof Iterator);
+		@SuppressWarnings("unchecked")
+		Iterator<Resource> parents = (Iterator<Resource>)result;
+		assertTrue(parents.hasNext());
+	
+		assertEquals(TEST_ABSOLUTE_PATH, parents.next().getPath());
+		assertFalse(parents.hasNext());
+
+		log.info("Test successful!");
+	}
+
+}

-- 
To stop receiving notification emails like this one, please contact
dklco@apache.org.