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.Item;
27  import javax.jcr.ItemNotFoundException;
28  import javax.jcr.RepositoryException;
29  import javax.jcr.Session;
30  import net.jcip.annotations.Immutable;
31  import org.modeshape.graph.ExecutionContext;
32  import org.modeshape.graph.property.Name;
33  import org.modeshape.graph.property.NamespaceRegistry;
34  import org.modeshape.graph.property.Path;
35  
36  /**
37   * An abstract {@link Item} implementation.
38   */
39  @Immutable
40  abstract class AbstractJcrItem implements Item {
41  
42      protected final SessionCache cache;
43  
44      protected AbstractJcrItem( SessionCache cache ) {
45          assert cache != null;
46          this.cache = cache;
47      }
48  
49      /**
50       * Check that the session is still valid and {@link Session#isLive() live}.
51       * 
52       * @throws RepositoryException if the session is not valid or live
53       */
54      protected final void checkSession() throws RepositoryException {
55          cache.session().checkLive();
56      }
57  
58      /**
59       * {@inheritDoc}
60       * 
61       * @see javax.jcr.Item#getSession()
62       */
63      public Session getSession() {
64          // Do not check whether the session is valid, because we need to be able to get the session to check isLive()
65          // checkSession();
66          return cache.session();
67      }
68  
69      final JcrSession session() {
70          return cache.session();
71      }
72  
73      final ExecutionContext context() {
74          return cache.context();
75      }
76  
77      final Name nameFrom( String name ) {
78          return context().getValueFactories().getNameFactory().create(name);
79      }
80  
81      final Path pathFrom( String path ) {
82          return context().getValueFactories().getPathFactory().create(path);
83      }
84  
85      final Path.Segment segmentFrom( String segment ) {
86          return context().getValueFactories().getPathFactory().createSegment(segment);
87      }
88  
89      final Path.Segment segmentFrom( Name segment ) {
90          return context().getValueFactories().getPathFactory().createSegment(segment);
91      }
92  
93      final NamespaceRegistry namespaces() {
94          return context().getNamespaceRegistry();
95      }
96  
97      abstract Path path() throws RepositoryException;
98  
99      /**
100      * {@inheritDoc}
101      * 
102      * @see javax.jcr.Item#isSame(javax.jcr.Item)
103      */
104     public boolean isSame( Item otherItem ) throws RepositoryException {
105         assert getSession() != null;
106         assert otherItem.getSession() != null;
107         assert getSession().getRepository() != null;
108         assert otherItem.getSession().getRepository() != null;
109 
110         if (getSession().getRepository() != otherItem.getSession().getRepository()) {
111             return false;
112         }
113 
114         assert getSession().getWorkspace() != null;
115         assert otherItem.getSession().getWorkspace() != null;
116 
117         String workspaceName = getSession().getWorkspace().getName();
118         String otherWorkspaceName = otherItem.getSession().getWorkspace().getName();
119 
120         if (workspaceName == null) {
121             return otherWorkspaceName == null;
122         }
123 
124         return workspaceName.equals(otherWorkspaceName);
125     }
126 
127     /**
128      * {@inheritDoc}
129      * 
130      * @see javax.jcr.Item#getAncestor(int)
131      */
132     public Item getAncestor( int depth ) throws RepositoryException {
133         checkSession();
134 
135         if (depth < 0) {
136             throw new ItemNotFoundException(JcrI18n.noNegativeDepth.text(depth));
137         }
138 
139         /*
140          * depth argument is absolute depth from root of content graph, not relative depth from current node.
141          * That is, if current node is at path /foo/bar/baz, getAncestor(1) returns node at /foo, getAncestor(2)
142          * returns node at /foo/bar, getAncestor(3) returns node at /foo/bar/baz, getAncestor(0) returns root node,
143          * and any other argument results in ItemNotFoundException.
144          * Next statement converts depth parameter from a relative depth to an absolute depth.
145          */
146         depth = getDepth() - depth;
147 
148         if (depth < 0) {
149             throw new ItemNotFoundException(JcrI18n.tooDeep.text(depth));
150         }
151 
152         Item ancestor = this;
153         while (--depth >= 0) {
154             ancestor = ancestor.getParent();
155         }
156         return ancestor;
157     }
158 
159     /**
160      * {@inheritDoc}
161      * 
162      * @see javax.jcr.Item#getDepth()
163      */
164     public int getDepth() throws RepositoryException {
165         checkSession();
166         return path().size();
167     }
168 
169 }