001: /*
002: * Copyright 2006 Day Management AG, Switzerland. All rights reserved.
003: */
004: package javax.jcr;
005:
006: import javax.jcr.lock.LockException;
007: import javax.jcr.nodetype.ConstraintViolationException;
008: import javax.jcr.nodetype.NoSuchNodeTypeException;
009: import javax.jcr.version.VersionException;
010:
011: /**
012: * The <code>Item</code> is the base interface of <code>{@link Node}</code>
013: * and <code>{@link Property}</code>.
014: */
015: public interface Item {
016:
017: /**
018: * Returns the absolute path to this item.
019: * If the path includes items that are same-name sibling nodes properties
020: * then those elements in the path will include the appropriate
021: * "square bracket" index notation (for example, <code>/a/b[3]/c</code>).
022: *
023: * @return the path of this <code>Item</code>.
024: * @throws RepositoryException if an error occurs.
025: */
026: public String getPath() throws RepositoryException;
027:
028: /**
029: * Returns the name of this <code>Item</code>. The name of an item is the
030: * last element in its path, minus any square-bracket index that may exist.
031: * If this <code>Item</code> is the root node of the workspace (i.e., if
032: * <code>this.getDepth() == 0</code>), an empty string will be returned.
033: * <p>
034: *
035: * @return the (or a) name of this <code>Item</code> or an empty string
036: * if this <code>Item</code> is the root node.
037: *
038: * @throws RepositoryException if an error occurs.
039: */
040: public String getName() throws RepositoryException;
041:
042: /**
043: * Returns the ancestor of the specified depth.
044: * An ancestor of depth <i>x</i> is the <code>Item</code> that is <i>x</i>
045: * levels down along the path from the root node to <i>this</i>
046: * <code>Item</code>.
047: * <ul>
048: * <li><i>depth</i> = 0 returns the root node.
049: * <li><i>depth</i> = 1 returns the child of the root node along the path
050: * to <i>this</i> <code>Item</code>.
051: * <li><i>depth</i> = 2 returns the grandchild of the root node along the
052: * path to <i>this</i> <code>Item</code>.
053: * <li>And so on to <i>depth</i> = <i>n</i>, where <i>n</i> is the depth
054: * of <i>this</i> <code>Item</code>, which returns <i>this</i>
055: * <code>Item</code> itself.
056: * </ul>
057: * If <i>depth</i> > <i>n</i> is specified then a
058: * <code>ItemNotFoundException</code> is thrown.
059: * <p>
060: *
061: * @param depth An integer, 0 <= <i>depth</i> <= <i>n</i> where <i>n</i> is the depth
062: * of <i>this</i> <code>Item</code>.
063: *
064: * @return The ancestor of this
065: * <code>Item</code> at the specified <code>depth</code>.
066: *
067: * @throws ItemNotFoundException if <i>depth</i> < 0 or
068: * <i>depth</i> > <i>n</i> where <i>n</i> is the is the depth of
069: * this item.
070: *
071: * @throws AccessDeniedException if the current session does not have
072: * sufficient access rights to retrieve the specified node.
073: *
074: * @throws RepositoryException if another error occurs.
075: */
076: public Item getAncestor(int depth) throws ItemNotFoundException,
077: AccessDeniedException, RepositoryException;
078:
079: /**
080: * Returns the parent of this <code>Item</code>.
081: *
082: * @return The parent of this <code>Item</code>.
083: *
084: * @throws ItemNotFoundException if there is no parent. This only happens
085: * if this item is the root node of a workspace.
086: *
087: * @throws AccessDeniedException if the current session does not have
088: * sufficient access rights to retrieve the parent of this item.
089: *
090: * @throws RepositoryException if another error occurs.
091: */
092: public Node getParent() throws ItemNotFoundException,
093: AccessDeniedException, RepositoryException;
094:
095: /**
096: * Returns the depth of this <code>Item</code> in the workspace tree.
097: * Returns the depth below the root node of <i>this</i> <code>Item</code>
098: * (counting <i>this</i> <code>Item</code> itself).
099: * <ul>
100: * <li>The root node returns 0.
101: * <li>A property or child node of the root node returns 1.
102: * <li>A property or child node of a child node of the root returns 2.
103: * <li>And so on to <i>this</i> <code>Item</code>.
104: * </ul>
105: *
106: * @return The depth of this <code>Item</code> in the workspace hierarchy.
107: * @throws RepositoryException if an error occurs.
108: */
109: public int getDepth() throws RepositoryException;
110:
111: /**
112: * Returns the <code>Session</code> through which this <code>Item</code>
113: * was acquired.
114: * Every <code>Item</code> can ultimately be traced back through a series
115: * of method calls to the call <code>{@link Session#getRootNode}</code>,
116: * <code>{@link Session#getItem}</code> or
117: * <code>{@link Session#getNodeByUUID}</code>. This method returns that
118: * <code>Session</code> object.
119: *
120: * @return the <code>Session</code> through which this <code>Item</code> was
121: * acquired.
122: * @throws RepositoryException if an error occurs.
123: */
124: public Session getSession() throws RepositoryException;
125:
126: /**
127: * Indicates whether this <code>Item</code> is a <code>Node</code> or a
128: * <code>Property</code>.
129: * Returns <code>true</code> if this <code>Item</code> is a <code>Node</code>;
130: * Returns <code>false</code> if this <code>Item</code> is a <code>Property</code>.
131: *
132: * @return <code>true</code> if this <code>Item</code> is a
133: * <code>Node</code>, <code>false</code> if it is a <code>Property</code>.
134: */
135: public boolean isNode();
136:
137: /**
138: * Returns <code>true</code> if this is a new item, meaning that it exists only in transient
139: * storage on the <code>Session</code> and has not yet been saved. Within a transaction,
140: * <code>isNew</code> on an <code>Item</code> may return <code>false</code> (because the item
141: * has been saved) even if that <code>Item</code> is not in persistent storage (because the
142: * transaction has not yet been committed).
143: * <p>
144: * Note that if an item returns <code>true</code> on <code>isNew</code>,
145: * then by definition is parent will return <code>true</code> on <code>isModified</code>.
146: * <p>
147: * Note that in level 1 (that is, read-only) implementations,
148: * this method will always return <code>false</code>.
149: *
150: * @return <code>true</code> if this item is new; <code>false</code> otherwise.
151: */
152: public boolean isNew();
153:
154: /**
155: * Returns <code>true</code> if this <code>Item</code> has been saved but has subsequently
156: * been modified through the current session and therefore the state of this item as recorded
157: * in the session differs from the state of this item as saved. Within a transaction,
158: * <code>isModified</code> on an <code>Item</code> may return <code>false</code> (because the
159: * <code>Item</code> has been saved since the modification) even if the modification in question
160: * is not in persistent storage (because the transaction has not yet been committed).
161: * <p>
162: * Note that in level 1 (that is, read-only) implementations,
163: * this method will always return <code>false</code>.
164: *
165: * @return <code>true</code> if this item is modified; <code>false</code> otherwise.
166: */
167: public boolean isModified();
168:
169: /**
170: * Returns <code>true</code> if this <code>Item</code> object
171: * (the Java object instance) represents the same actual workspace item as the
172: * object <code>otherItem</code>.
173: * <p>
174: * Two <code>Item</code> objects represent the same workspace item if all the following
175: * are true:
176: * <ul>
177: * <li>Both objects were acquired through <code>Session</code> objects that were created
178: * by the same <code>Repository</code> object.</li>
179: * <li>Both objects were acquired through <code>Session</code> objects bound to the same
180: * repository workspace.</li>
181: * <li>The objects are either both <code>Node</code> objects or both <code>Property</code>
182: * objects.</li>
183: * <li>If they are <code>Node</code> objects, they have the same correspondence identifier.
184: * Note that this is the identifier used to determine whether two nodes in different
185: * workspaces correspond but obviously it is also true that any node has the same
186: * correspondence identifier as itself. Hence, this identifier is used here to
187: * determine whether two different Java <code>Node</code> objects actually represent the same
188: * workspace node.</li>
189: * <li>If they are <code>Property</code> objects they have identical names and
190: * <code>isSame</code> is true of their parent nodes.</li>
191: * </ul>
192: * This method does not compare the <i>states</i> of the two items. For example, if two
193: * <code>Item</code> objects representing the same actual workspace item have been
194: * retrieved through two different sessions and one has been modified, then this method
195: * will still return <code>true</code> when comparing these two objects. Note that if two
196: * <code>Item</code> objects representing the same workspace item
197: * are retrieved through the <i>same</i> session they will always reflect the
198: * same state (see section 5.1.3 <i>Reflecting Item State</i> in the JSR 283 specification
199: * document) so comparing state is not an issue.
200: *
201: * @param otherItem the <code>Item</code> object to be tested for identity with this <code>Item</code>.
202: *
203: * @return <code>true</code> if this <code>Item</code> object and <code>otherItem</code> represent the same actual repository
204: * item; <code>false</code> otherwise.
205: *
206: * @throws RepositoryException if an error occurs.
207: */
208: public boolean isSame(Item otherItem) throws RepositoryException;
209:
210: /**
211: * Accepts an <code>ItemVistor</code>.
212: * Calls the appropriate <code>ItemVistor</code>
213: * <code>visit</code> method of the according to whether <i>this</i>
214: * <code>Item</code> is a <code>Node</code> or a <code>Property</code>.
215: *
216: * @param visitor The ItemVisitor to be accepted.
217: *
218: * @throws RepositoryException if an error occurs.
219: */
220: public void accept(ItemVisitor visitor) throws RepositoryException;
221:
222: /**
223: * Validates all pending changes currently recorded in this <code>Session</code> that apply to this <code>Item</code>
224: * or any of its descendants (that is, the subtree rooted at this Item). If validation of <i>all</i>
225: * pending changes succeeds, then this change information is cleared from the <code>Session</code>.
226: * If the <code>save</code> occurs outside a transaction, the changes are persisted and thus
227: * made visible to other <code>Sessions</code>. If the <code>save</code> occurs within a transaction,
228: * the changes are not persisted until the transaction is committed.
229: * <p/>
230: * If validation fails, then no pending changes are saved and they remain recorded on the <code>Session</code>.
231: * There is no best-effort or partial save.
232: * <p/>
233: * The item in persistent storage to which a transient item is saved is
234: * determined by matching identifiers and paths.
235: * <p/>
236: * An <code>AccessDeniedException</code> will be thrown if any of the changes
237: * to be persisted would violate the access privileges of this
238: * <code>Session</code>.
239: * <p/>
240: * If any of the changes to be persisted would cause the removal of a node
241: * that is currently the target of a <code>REFERENCE</code> property then a
242: * <code>ReferentialIntegrityException</code> is thrown, provided that this <code>Session</code> has
243: * read access to that <code>REFERENCE</code> property. If, on the other hand, this
244: * <code>Session</code> does not have read access to the <code>REFERENCE</code> property in question,
245: * then an <code>AccessDeniedException</code> is thrown instead.
246: * <p/>
247: * An <code>ItemExistsException</code> will be thrown if any of the changes
248: * to be persisted would be prevented by the presence of an already existing
249: * item in the workspace.
250: * <p/>
251: * A <code>ConstraintViolationException</code> will be thrown if any of the
252: * changes to be persisted would violate a node type restriction.
253: * Additionally, a repository may use this exception to enforce
254: * implementation- or configuration-dependant restrictions.
255: * <p/>
256: * An <code>InvalidItemStateException</code> is thrown if any of the
257: * changes to be persisted conflicts with a change already persisted
258: * through another session and the implementation is such that this
259: * conflict can only be detected at <code>save</code>-time and therefore was not
260: * detected earlier, at change-time.
261: * <p/>
262: * A <code>VersionException</code> is thrown if the <code>save</code> would make a result in
263: * a change to persistent storage that would violate the read-only status of a
264: * checked-in node.
265: * <p/>
266: * A <code>LockException</code> is thrown if the <code>save</code> would result
267: * in a change to persistent storage that would violate a lock.
268: * <p/>
269: * A <code>NoSuchNodeTypeException</code> is thrown if the <code>save</code> would result in the
270: * addition of a node with an unrecognized node type.
271: * <p/>
272: * A <code>RepositoryException</code> will be thrown if another error
273: * occurs.
274: *
275: * @throws AccessDeniedException if any of the changes to be persisted would violate
276: * the access privileges of the this <code>Session</code>. Also thrown if any of the
277: * changes to be persisted would cause the removal of a node that is currently
278: * referenced by a <code>REFERENCE</code> property that this Session
279: * <i>does not</i> have read access to.
280: * @throws ItemExistsException if any of the changes
281: * to be persisted would be prevented by the presence of an already existing
282: * item in the workspace.
283: * @throws ConstraintViolationException if any of the changes to be persisted would
284: * violate a node type or restriction. Additionally, a repository may use this
285: * exception to enforce implementation- or configuration-dependent restrictions.
286: * @throws InvalidItemStateException if any of the
287: * changes to be persisted conflicts with a change already persisted
288: * through another session and the implementation is such that this
289: * conflict can only be detected at <code>save</code>-time and therefore was not
290: * detected earlier, at change-time.
291: * @throws ReferentialIntegrityException if any of the
292: * changes to be persisted would cause the removal of a node that is currently
293: * referenced by a <code>REFERENCE</code> property that this <code>Session</code>
294: * has read access to.
295: * @throws VersionException if the <code>save</code> would make a result in
296: * a change to persistent storage that would violate the read-only status of a
297: * checked-in node.
298: * @throws LockException if the <code>save</code> would result in a
299: * change to persistent storage that would violate a lock.
300: * @throws NoSuchNodeTypeException if the <code>save</code> would result in the
301: * addition of a node with an unrecognized node type.
302: * @throws RepositoryException if another error occurs.
303: */
304: public void save() throws AccessDeniedException,
305: ItemExistsException, ConstraintViolationException,
306: InvalidItemStateException, ReferentialIntegrityException,
307: VersionException, LockException, NoSuchNodeTypeException,
308: RepositoryException;
309:
310: /**
311: * If <code>keepChanges</code> is <code>false</code>, this method discards all pending changes
312: * currently recorded in this <code>Session</code> that apply to this Item or any of its descendants
313: * (that is, the subtree rooted at this Item)and returns all items to reflect the current
314: * saved state. Outside a transaction this state is simple the current state of persistent storage.
315: * Within a transaction, this state will reflect persistent storage as modified by changes that have
316: * been saved but not yet committed.
317: * <p>
318: * If <code>keepChanges</code> is true then pending change are not discarded but items that do not
319: * have changes pending have their state refreshed to reflect the current saved state, thus revealing
320: * changes made by other sessions.
321: * <p>
322: * An <code>InvalidItemStateException</code> is thrown if this <code>Item</code> object represents a
323: * workspace item that has been removed (either by this session or another).
324: *
325: * @param keepChanges a boolean
326: * @throws InvalidItemStateException if this
327: * <code>Item</code> object represents a workspace item that has been
328: * removed (either by this session or another).
329: *
330: * @throws RepositoryException if another error occurs.
331: */
332: public void refresh(boolean keepChanges)
333: throws InvalidItemStateException, RepositoryException;
334:
335: /**
336: * Removes <code>this</code> item (and its subtree).
337: * <p/>
338: * To persist a removal, a <code>save</code> must be
339: * performed that includes the (former) parent of the
340: * removed item within its scope.
341: * <p/>
342: * If a node with same-name siblings is removed, this decrements by one the
343: * indices of all the siblings with indices greater than that of the removed
344: * node. In other words, a removal compacts the array of same-name siblings
345: * and causes the minimal re-numbering required to maintain the original
346: * order but leave no gaps in the numbering.
347: * <p/>
348: * A <code>ReferentialIntegrityException</code> will be thrown on <code>save</code>
349: * if this item or an item in its subtree is currently the target of a <code>REFERENCE</code>
350: * property located in this workspace but outside this item's subtree and the current <code>Session</code>
351: * has read access to that <code>REFERENCE</code> property.
352: * <p/>
353: * An <code>AccessDeniedException</code> will be thrown on <code>save</code>
354: * if this item or an item in its subtree is currently the target of a <code>REFERENCE</code>
355: * property located in this workspace but outside this item's subtree and the current <code>Session</code>
356: * <i>does not</i> have read access to that <code>REFERENCE</code> property.
357: * <p/>
358: * A <code>ConstraintViolationException</code> will be thrown either immediately
359: * or on <code>save</code>, if removing this item would violate a node type or implementation-specific
360: * constraint. Implementations may differ on when this validation is performed.
361: * <p/>
362: * A <code>VersionException</code> will be thrown either immediately
363: * or on <code>save</code>, if the parent node of this item is versionable and checked-in
364: * or is non-versionable but its nearest versionable ancestor is checked-in. Implementations
365: * may differ on when this validation is performed.
366: * <p/>
367: * A <code>LockException</code> will be thrown either immediately or on <code>save</code>
368: * if a lock prevents the removal of this item. Implementations may differ on when this validation is performed.
369: *
370: * @throws VersionException if the parent node of this item is versionable and checked-in
371: * or is non-versionable but its nearest versionable ancestor is checked-in and this
372: * implementation performs this validation immediately instead of waiting until <code>save</code>.
373: * @throws LockException if a lock prevents the removal of this item and this
374: * implementation performs this validation immediately instead of waiting until <code>save</code>.
375: * @throws ConstraintViolationException if removing the specified item would violate a node type or
376: * implementation-specific constraint and this implementation performs this validation immediately
377: * instead of waiting until <code>save</code>.
378: * @throws RepositoryException if another error occurs.
379: */
380: public void remove() throws VersionException, LockException,
381: ConstraintViolationException, RepositoryException;
382: }
|