View Javadoc

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 }