View Javadoc

1   /**
2    * Copyright (c) 2007-2011 Southern Cross IT. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 3 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  package com.scit.sling.test;
15  
16  import java.util.Arrays;
17  import java.util.LinkedList;
18  import java.util.Map;
19  
20  import org.apache.sling.api.resource.ValueMap;
21  
22  /**
23   * This class is used to represent a JRC subtree. You can use it directly to create a tree then build a {@link MockResourceResolver}
24   * via {@link MockResourceFactory#buildMockRepository(ResourceNode)} or you can use the provided {@link MockResourceFactory#buildRepositoryFromJson(String, java.io.InputStream)}
25   * factory methods.<br/>
26   * 
27   * <h1>Direct Usage</h1>
28   * <code>
29   * base = new ResourceNode("/content/geometrixx/en", "products");<br>
30   * base.addProperty("jcr:createdBy", "system");<br>
31   * base.addProperty("jcr:primaryType", "cq:Page");<br>
32   * jcrContent = new ResourceNode("base", "jcr:content");<br>
33   * base.addChild(jcrContent);<br>
34   * jcrContent.addProperty("sling:resourceType", "geometrixx/components/contentpage");<br>
35   * jcrContent.addProperty("jcr:createdBy", "system");<br>
36   * </code>
37   */
38  public class ResourceNode {
39  	private final String name;
40  	private final ResourceNode parent;
41  	private final String basePath;
42  	private final LinkedList<ResourceNode> children = new LinkedList<ResourceNode>();
43  	private final ValueMap properties = new MockValueMap();
44  
45  	/**
46  	 * Create a root node that represents a location somewhere on a resource tree.
47  	 * 
48  	 * @param basePath the parent path of this node (blank if it's meant to be the root)
49  	 * @param name the name of this node
50  	 */
51  	public ResourceNode(String basePath, String name) {
52  		this(basePath, null, name);
53  	}
54  
55  	public ResourceNode(ResourceNode parent, String name) {
56  		this(null, parent, name);
57  	}
58  
59  	private ResourceNode(String basePath, ResourceNode parent, String name) {
60  		this.basePath = basePath;
61  		this.parent = parent;
62  		this.name = name;
63  	}
64  
65  	public LinkedList<ResourceNode> getChildren() {
66  		return children;
67  	}
68  
69  	/**
70  	 * Add a property node
71  	 * 
72  	 * @param name the property name
73  	 * @param value the value
74  	 */
75  	public void addProperty(String name, Object value) {
76  		properties.put(name, value);
77  	}
78  
79  	/**
80  	 * @return the full "jcr:path" of the resource
81  	 */
82  	public String getPath() {
83  		return (basePath == null ? "" : (basePath + "/")) + (parent == null ? "" : (parent.getPath() + "/")) + name;
84  	}
85  
86  	@Override
87  	public String toString() {
88  		return getPath() + ", " + properties.get("jcr:primaryType", "");
89  	}
90  
91  	/**
92  	 * @return the whole tree (this node and all sub nodes) as a nicely formatted tree upto depth
93  	 */
94  	public String fullContent(int depth) {
95  		StringBuilder sb = new StringBuilder("{\n");
96  		toString("\t", sb, depth);
97  		sb.append("}");
98  		return sb.toString();
99  	}
100 
101 	private void toString(String indent, StringBuilder sb, int depth) {
102 		sb.append(indent).append("jcr:path").append("= ").append(getPath()).append("\n");
103 		for (Map.Entry<String,Object> prop : properties.entrySet()) {
104 			sb.append(indent).append(prop.getKey()).append("= ").append(jsonStringValue(prop.getValue())).append("\n");
105 		}
106 		if (depth > 0) {
107 			depth--;
108 			if (children.size() > 0) {
109 				String newIndent = indent + "\t";
110 				for (ResourceNode child : children) {
111 					sb.append(indent).append(child.name).append(": {\n");
112 					child.toString(newIndent, sb, depth);
113 					sb.append(indent).append("}\n");
114 				}
115 			}
116 		}
117 	}
118 
119 	private String jsonStringValue(Object value) {
120 		if (value == null) {
121 			return "";
122 		}
123 		if (value.getClass().isArray()) {
124 			return Arrays.asList((Object[])value).toString();
125 		}
126 		return value.toString();
127 	}
128 
129 	/**
130 	 * Add a child and possibly another subtree
131 	 * 
132 	 * @param node
133 	 */
134 	public void addChild(ResourceNode node) {
135 		children.add(node);
136 	}
137 
138 	/**
139 	 * @return a list of all properties
140 	 */
141 	public ValueMap getProperties() {
142 		return this.properties;
143 	}
144 }