1 /*
2 * ModeShape (http://www.modeshape.org)
3 * See the COPYRIGHT.txt file distributed with this work for information
4 * regarding copyright ownership. Some portions may be licensed
5 * to Red Hat, Inc. under one or more contributor license agreements.
6 * See the AUTHORS.txt file in the distribution for a full listing of
7 * individual contributors.
8 *
9 * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10 * is licensed to you under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
13 *
14 * ModeShape is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this software; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23 */
24 package org.modeshape.jcr;
25
26 import javax.jcr.Node;
27 import javax.jcr.NodeIterator;
28 import javax.jcr.PathNotFoundException;
29 import javax.jcr.RepositoryException;
30 import javax.jcr.Session;
31 import org.modeshape.common.util.CheckArg;
32
33 /**
34 * Utility methods for working with JCR nodes.
35 */
36 public class JcrTools {
37
38 /**
39 * Remove all children from the specified node
40 *
41 * @param node
42 * @return the number of children removed.
43 * @throws RepositoryException
44 * @throws IllegalArgumentException if the node argument is null
45 */
46 public int removeAllChildren( Node node ) throws RepositoryException {
47 CheckArg.isNotNull(node, "node");
48 int childrenRemoved = 0;
49 NodeIterator iter = node.getNodes();
50 while (iter.hasNext()) {
51 Node child = iter.nextNode();
52 child.remove();
53 ++childrenRemoved;
54 }
55 return childrenRemoved;
56 }
57
58 /**
59 * Get the node under a specified node at a location defined by the specified relative path. If node is required, then a problem
60 * is created and added to the Problems list.
61 *
62 * @param node a parent node from which to obtain a node relative to. may not be null
63 * @param relativePath the path of the desired node. may not be null
64 * @param required true if node is required to exist under the given node.
65 * @return the node located relative the the input node
66 * @throws RepositoryException
67 * @throws IllegalArgumentException if the node, relativePath or problems argument is null
68 */
69 public Node getNode( Node node,
70 String relativePath,
71 boolean required) throws RepositoryException {
72 CheckArg.isNotNull(node, "node");
73 CheckArg.isNotNull(relativePath, "relativePath");
74 Node result = null;
75 try {
76 result = node.getNode(relativePath);
77 } catch (PathNotFoundException e) {
78 if (required) {
79 throw e;
80 }
81 }
82
83 return result;
84 }
85
86 /**
87 * Get the readable string form for a specified node.
88 *
89 * @param node the node to obtain the readable string form. may be null
90 * @return the readable string form for a specified node.
91 */
92 public String getReadable( Node node ) {
93 if (node == null) return "";
94 try {
95 return node.getPath();
96 } catch (RepositoryException err) {
97 return node.toString();
98 }
99 }
100
101 /**
102 * Get or create a node at the specified path.
103 *
104 * @param session the JCR session. may not be null
105 * @param path the path of the desired node to be found or created. may not be null
106 * @return the existing or newly created node
107 * @throws RepositoryException
108 * @throws IllegalArgumentException if either the session or path argument is null
109 */
110 public Node findOrCreateNode( Session session,
111 String path ) throws RepositoryException {
112 return findOrCreateNode(session, path, null, null);
113 }
114
115 /**
116 * Get or create a node at the specified path and node type.
117 *
118 * @param session the JCR session. may not be null
119 * @param path the path of the desired node to be found or created. may not be null
120 * @param nodeType the node type. may be null
121 * @return the existing or newly created node
122 * @throws RepositoryException
123 * @throws IllegalArgumentException if either the session or path argument is null
124 */
125 public Node findOrCreateNode( Session session,
126 String path,
127 String nodeType ) throws RepositoryException {
128 return findOrCreateNode(session, path, nodeType, nodeType);
129 }
130
131 /**
132 * Get or create a node at the specified path.
133 *
134 * @param session the JCR session. may not be null
135 * @param path the path of the desired node to be found or created. may not be null
136 * @param defaultNodeType the default node type. may be null
137 * @param finalNodeType the optional final node type. may be null
138 * @return the existing or newly created node
139 * @throws RepositoryException
140 * @throws IllegalArgumentException if either the session or path argument is null
141 */
142 public Node findOrCreateNode( Session session,
143 String path,
144 String defaultNodeType,
145 String finalNodeType ) throws RepositoryException {
146 CheckArg.isNotNull(session, "session");
147 Node root = session.getRootNode();
148 return findOrCreateNode(root, path, defaultNodeType, finalNodeType);
149 }
150
151 /**
152 * Get or create a node at the specified path.
153 *
154 * @param parentNode the parent node. may not be null
155 * @param path the path of the desired child node. may not be null
156 * @param defaultNodeType the default node type. may be null
157 * @param finalNodeType the optional final node type. may be null
158 * @return the existing or newly created node
159 * @throws RepositoryException
160 * @throws IllegalArgumentException if either the parentNode or path argument is null
161 */
162 public Node findOrCreateNode( Node parentNode,
163 String path,
164 String defaultNodeType,
165 String finalNodeType ) throws RepositoryException {
166 CheckArg.isNotNull(parentNode, "parentNode");
167 CheckArg.isNotNull(path, "path");
168 // Remove leading and trailing slashes ...
169 String relPath = path.replaceAll("^/+", "").replaceAll("/+$", "");
170
171 // Look for the node first ...
172 try {
173 return parentNode.getNode(relPath);
174 } catch (PathNotFoundException e) {
175 // continue
176 }
177 // Create the node, which has to be done segment by segment ...
178 String[] pathSegments = relPath.split("/");
179 Node node = parentNode;
180 for (int i = 0, len = pathSegments.length; i != len; ++i) {
181 String pathSegment = pathSegments[i];
182 pathSegment = pathSegment.trim();
183 if (pathSegment.length() == 0) continue;
184 if (node.hasNode(pathSegment)) {
185 // Find the existing node ...
186 node = node.getNode(pathSegment);
187 } else {
188 // Make sure there is no index on the final segment ...
189 String pathSegmentWithNoIndex = pathSegment.replaceAll("(\\[\\d+\\])+$", "");
190 // Create the node ...
191 String nodeType = defaultNodeType;
192 if (i == len - 1 && finalNodeType != null) nodeType = finalNodeType;
193 if (nodeType != null) {
194 node = node.addNode(pathSegmentWithNoIndex, nodeType);
195 } else {
196 node = node.addNode(pathSegmentWithNoIndex);
197 }
198 }
199 }
200 return node;
201 }
202
203 /**
204 * Get or create a node with the specified node under the specified parent node.
205 *
206 * @param parent the parent node. may not be null
207 * @param name the name of the child node. may not be null
208 * @return the existing or newly created child node
209 * @throws RepositoryException
210 * @throws IllegalArgumentException if either the parent or name argument is null
211 */
212 public Node findOrCreateChild( Node parent,
213 String name ) throws RepositoryException {
214 return findOrCreateChild( parent, name, null);
215 }
216
217 /**
218 * Get or create a node with the specified node and node type under the specified parent node.
219 *
220 * @param parent the parent node. may not be null
221 * @param name the name of the child node. may not be null
222 * @param nodeType the node type. may be null
223 * @return the existing or newly created child node
224 * @throws RepositoryException
225 */
226 public Node findOrCreateChild( Node parent,
227 String name,
228 String nodeType ) throws RepositoryException {
229 return findOrCreateNode( parent, name, nodeType, nodeType);
230 }
231
232 }