1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.portals.graffito.jcr.persistence.impl;
17
18
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24
25 import javax.jcr.InvalidItemStateException;
26 import javax.jcr.Item;
27 import javax.jcr.Node;
28 import javax.jcr.NodeIterator;
29 import javax.jcr.PathNotFoundException;
30 import javax.jcr.RepositoryException;
31 import javax.jcr.Session;
32 import javax.jcr.UnsupportedRepositoryOperationException;
33 import javax.jcr.lock.Lock;
34 import javax.jcr.lock.LockException;
35 import javax.jcr.nodetype.NoSuchNodeTypeException;
36 import javax.jcr.query.InvalidQueryException;
37 import javax.jcr.query.QueryResult;
38 import javax.jcr.version.VersionHistory;
39
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.apache.portals.graffito.jcr.exception.IllegalUnlockException;
43 import org.apache.portals.graffito.jcr.exception.JcrMappingException;
44 import org.apache.portals.graffito.jcr.exception.LockedException;
45 import org.apache.portals.graffito.jcr.exception.PersistenceException;
46 import org.apache.portals.graffito.jcr.exception.VersionException;
47 import org.apache.portals.graffito.jcr.mapper.Mapper;
48 import org.apache.portals.graffito.jcr.mapper.impl.DigesterMapperImpl;
49 import org.apache.portals.graffito.jcr.mapper.model.ClassDescriptor;
50 import org.apache.portals.graffito.jcr.persistence.PersistenceManager;
51 import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.impl.DefaultAtomicTypeConverterProvider;
52 import org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter;
53 import org.apache.portals.graffito.jcr.persistence.objectconverter.impl.ObjectConverterImpl;
54 import org.apache.portals.graffito.jcr.query.Query;
55 import org.apache.portals.graffito.jcr.query.QueryManager;
56 import org.apache.portals.graffito.jcr.query.impl.QueryManagerImpl;
57 import org.apache.portals.graffito.jcr.version.Version;
58 import org.apache.portals.graffito.jcr.version.VersionIterator;
59
60 /***
61 *
62 * Default implementation for {@link org.apache.portals.graffito.jcr.persistence.PersistenceManager}
63 *
64 * @author Sandro Boehme
65 * @author <a href="mailto:christophe.lombart@sword-technologies.com">Lombart Christophe</a>
66 * @author Martin Koci
67 * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
68 */
69 public class PersistenceManagerImpl implements PersistenceManager {
70 /***
71 * Logger.
72 */
73 private final static Log log = LogFactory.getLog(PersistenceManagerImpl.class);
74
75 /***
76 * JCR session.
77 */
78 protected Session session;
79
80 protected Mapper mapper;
81
82 /***
83 * The Graffito query manager
84 */
85 protected QueryManager queryManager;
86
87 /***
88 * Object Converter
89 */
90 protected ObjectConverter objectConverter;
91
92
93 /***
94 * Creates a new <code>PersistenceManager</code> that uses the passed in
95 * <code>Mapper</code>, <code>QueryManager</code> and a default
96 * <code>ObjectConverter</code>
97 *
98 * @param mapper the Mapper component
99 * @param queryManager the query manager to used
100 * @param session The JCR session
101 */
102 public PersistenceManagerImpl(Mapper mapper,
103 QueryManager queryManager,
104 Session session) {
105 this.mapper = mapper;
106 this.session = session;
107 this.objectConverter = new ObjectConverterImpl(mapper, new DefaultAtomicTypeConverterProvider());
108 this.queryManager = queryManager;
109 }
110
111 /***
112 * Creates a new <code>PersistenceManager</code> based on a JCR session and some xml mapping files.
113 *
114 * @param session The JCR session
115 * @param xmlMappingFiles Graffito JCR mapping file used mainly to create the <code>Mapper</code> component
116 */
117 public PersistenceManagerImpl(Session session,String[] xmlMappingFiles )
118 {
119 this.session = session;
120 this.mapper = new DigesterMapperImpl(xmlMappingFiles);
121 DefaultAtomicTypeConverterProvider converterProvider = new DefaultAtomicTypeConverterProvider();
122 Map atomicTypeConverters = converterProvider.getAtomicTypeConverters();
123 this.queryManager = new QueryManagerImpl(mapper, atomicTypeConverters);
124 this.objectConverter = new ObjectConverterImpl(mapper, converterProvider);
125
126
127 }
128
129
130 /***
131 * Full constructor.
132 *
133 * @param mapper the Mapper component
134 * @param converter the <code>ObjectConverter</code> to be used internally
135 * @param queryManager the query manager to used
136 * @param session The JCR session
137 */
138 public PersistenceManagerImpl(Mapper mapper,
139 ObjectConverter converter,
140 QueryManager queryManager,
141 Session session) {
142 this.mapper = mapper;
143 this.session = session;
144 this.objectConverter = converter;
145 this.queryManager = queryManager;
146 }
147
148 /***
149 * Sets the <code>Mapper</code> used by this persistence manager.
150 *
151 * @param mapper mapping solver
152 */
153 public void setMapper(Mapper mapper) {
154 this.mapper = mapper;
155 }
156
157 /***
158 * Sets the <code>ObjectConverter</code> that is used internally by this persistence manager.
159 *
160 * @param objectConverter the internal <code>ObjectConverter</code>
161 */
162 public void setObjectConverter(ObjectConverter objectConverter) {
163 this.objectConverter = objectConverter;
164 }
165
166 /***
167 * Sets the <code>QueryManager</code> used by the persistence manager.
168 *
169 * @param queryManager a <code>QueryManager</code>
170 */
171 public void setQueryManager(QueryManager queryManager) {
172 this.queryManager= queryManager;
173 }
174
175 /***
176 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getObject(java.lang.Class, java.lang.String)
177 * @throws org.apache.portals.graffito.jcr.exception.RepositoryException if the underlying repository
178 * has thrown a javax.jcr.RepositoryException
179 * @throws JcrMappingException if the mapping for the class is not correct
180 * @throws PersistenceException if the object cannot be retrieved from the path
181 */
182 public Object getObject( String path) {
183 try {
184 if (!session.itemExists(path)) {
185 return null;
186 }
187 }
188 catch(RepositoryException e) {
189 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
190 "Impossible to get the object at " + path, e);
191 }
192
193 return objectConverter.getObject(session, path);
194
195 }
196
197 /***
198 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getObject(java.lang.Class, java.lang.String, java.lang.String)
199 */
200 public Object getObject( String path, String versionName) {
201 String pathVersion = null;
202 try {
203 if (!session.itemExists(path)) {
204 return null;
205 }
206
207 Version version = this.getVersion(path, versionName);
208 pathVersion = version.getPath() + "/jcr:frozenNode";
209
210 }
211 catch(RepositoryException e) {
212 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
213 "Impossible to get the object at " + path + " - version :" + versionName,
214 e);
215 }
216
217 return objectConverter.getObject(session, pathVersion);
218 }
219
220 /***
221 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getObject(java.lang.Class, java.lang.String)
222 * @throws org.apache.portals.graffito.jcr.exception.RepositoryException if the underlying repository
223 * has thrown a javax.jcr.RepositoryException
224 * @throws JcrMappingException if the mapping for the class is not correct
225 * @throws PersistenceException if the object cannot be retrieved from the path
226 */
227 public Object getObject(Class objectClass, String path) {
228 try {
229 if (!session.itemExists(path)) {
230 return null;
231 }
232 }
233 catch(RepositoryException e) {
234 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
235 "Impossible to get the object at " + path, e);
236 }
237
238 return objectConverter.getObject(session, objectClass, path);
239
240 }
241
242 /***
243 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getObject(java.lang.Class, java.lang.String, java.lang.String)
244 */
245 public Object getObject(Class objectClass, String path, String versionName) {
246 String pathVersion = null;
247 try {
248 if (!session.itemExists(path)) {
249 return null;
250 }
251
252 Version version = this.getVersion(path, versionName);
253 pathVersion = version.getPath() + "/jcr:frozenNode";
254
255 }
256 catch(RepositoryException e) {
257 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
258 "Impossible to get the object at " + path + " - version :" + versionName,
259 e);
260 }
261
262 return objectConverter.getObject(session, objectClass, pathVersion);
263 }
264
265 /***
266 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#retrieveAllMappedAttributes(Object)
267 */
268 public void retrieveAllMappedAttributes(Object object) {
269 objectConverter.retrieveAllMappedAttributes(session, object);
270
271 }
272
273 /***
274 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#retrieveMappedAttribute(Object, String)
275 */
276 public void retrieveMappedAttribute(Object object, String attributeName) {
277 objectConverter.retrieveMappedAttribute(session, object, attributeName);
278
279 }
280
281 /***
282 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#insert(java.lang.Object)
283 */
284 public void insert(Object object) {
285 String path = objectConverter.getPath(session, object);
286
287 try {
288 if (session.itemExists(path)) {
289 Item item = session.getItem(path);
290 if (item.isNode()) {
291 if (!((Node) item).getDefinition().allowsSameNameSiblings()) {
292 throw new PersistenceException("Path already exists and it is not supporting the same name sibling : "
293 + path);
294 }
295 }
296 else {
297 throw new PersistenceException("Path already exists and it is a property : "
298 + path);
299 }
300
301 }
302 }
303 catch(RepositoryException e) {
304 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
305 "Impossible to insert the object at " + path, e);
306 }
307
308 objectConverter.insert(session, object);
309 }
310
311 /***
312 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#update(java.lang.Object)
313 */
314 public void update(Object object) {
315 String path = objectConverter.getPath(session, object);
316 try {
317 if (!session.itemExists(path)) {
318 throw new PersistenceException("Path is not existing : " + path);
319 }
320 else {
321 checkIfNodeLocked(path);
322 }
323 }
324 catch(javax.jcr.RepositoryException e) {
325 throw new org.apache.portals.graffito.jcr.exception.RepositoryException("Impossible to update", e);
326 }
327
328 objectConverter.update(session, object);
329 }
330
331 /***
332 *
333 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#remove(java.lang.String)
334 */
335 public void remove(String path) {
336 try {
337 if (!session.itemExists(path)) {
338 throw new PersistenceException("Path does not exist : " + path);
339 }
340 else {
341 checkIfNodeLocked(path);
342 }
343
344 Item item = session.getItem(path);
345 item.remove();
346
347 }
348 catch(RepositoryException e) {
349 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
350 "Impossible to remove the object at " + path);
351 }
352 }
353
354 /***
355 *
356 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#remove(java.lang.Object)
357 */
358 public void remove(Object object) {
359 this.remove(objectConverter.getPath(session, object));
360 }
361
362 /***
363 *
364 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#remove(org.apache.portals.graffito.jcr.query.Query)
365 */
366 public void remove(Query query) {
367 try {
368 String jcrExpression = this.queryManager.buildJCRExpression(query);
369 log.debug("Remove Objects with expression : " + jcrExpression);
370
371 javax.jcr.query.Query jcrQuery = session.getWorkspace().getQueryManager()
372 .createQuery(jcrExpression, javax.jcr.query.Query.XPATH);
373
374 QueryResult queryResult = jcrQuery.execute();
375 NodeIterator nodeIterator = queryResult.getNodes();
376 List nodes = new ArrayList();
377
378 while (nodeIterator.hasNext()) {
379 Node node = nodeIterator.nextNode();
380 log.debug("Remove node : " + node.getPath());
381
382
383
384 nodes.add(node);
385 }
386
387
388 for (int i = 0; i < nodes.size(); i++) {
389 Node node = (Node) nodes.get(i);
390 checkIfNodeLocked(node.getPath());
391 try {
392 node.remove();
393 }
394 catch(javax.jcr.RepositoryException re) {
395 throw new PersistenceException("Cannot remove node at path "
396 + node.getPath() + " returned from query "
397 + jcrExpression,
398 re);
399 }
400 }
401
402 }
403 catch(InvalidQueryException iqe) {
404 throw new org.apache.portals.graffito.jcr.exception.RepositoryException("Invalid query expression", iqe);
405 }
406 catch(RepositoryException e) {
407 throw new org.apache.portals.graffito.jcr.exception.RepositoryException("Impossible to get the object collection", e);
408 }
409 }
410
411 /***
412 *
413 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#objectExists(java.lang.String)
414 */
415 public boolean objectExists(String path) {
416 try {
417
418 return session.itemExists(path);
419 }
420 catch(RepositoryException e) {
421 throw new org.apache.portals.graffito.jcr.exception.RepositoryException("Impossible to check if the object exist", e);
422 }
423 }
424
425 /***
426 *
427 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#isPersistent(java.lang.Class)
428 */
429 public boolean isPersistent(final Class clazz) {
430 boolean isPersistent = false;
431 ClassDescriptor classDescriptor = mapper.getClassDescriptorByClass(clazz);
432 if (classDescriptor != null) {
433 isPersistent = true;
434 }
435
436 return isPersistent;
437 }
438
439 /***
440 *
441 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getObject(org.apache.portals.graffito.jcr.query.Query)
442 */
443 public Object getObject(Query query) {
444 try {
445 String jcrExpression = this.queryManager.buildJCRExpression(query);
446 log.debug("Get Object with expression : " + jcrExpression);
447
448 javax.jcr.query.Query jcrQuery = session.getWorkspace().getQueryManager().createQuery(
449 jcrExpression, javax.jcr.query.Query.XPATH);
450 QueryResult queryResult = jcrQuery.execute();
451 NodeIterator nodeIterator = queryResult.getNodes();
452
453 if (nodeIterator.getSize() > 1) {
454 throw new PersistenceException("Impossible to get the object - the query returns more than one object");
455 }
456
457 Object object = null;
458 if (nodeIterator.hasNext()) {
459 Node node = nodeIterator.nextNode();
460 object = objectConverter.getObject(session, node.getPath());
461 }
462
463 return object;
464 }
465 catch(InvalidQueryException iqe) {
466 throw new org.apache.portals.graffito.jcr.exception.RepositoryException("Invalid query expression", iqe);
467 }
468 catch(RepositoryException e) {
469 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
470 "Impossible to get the object collection", e);
471 }
472 }
473
474 /***
475 *
476 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getObjects(org.apache.portals.graffito.jcr.query.Query)
477 */
478 public Collection getObjects(Query query) {
479 try {
480 String jcrExpression = this.queryManager.buildJCRExpression(query);
481 log.debug("Get Objects with expression : " + jcrExpression);
482
483 javax.jcr.query.Query jcrQuery = session.getWorkspace().getQueryManager()
484 .createQuery(jcrExpression, javax.jcr.query.Query.XPATH);
485 QueryResult queryResult = jcrQuery.execute();
486 NodeIterator nodeIterator = queryResult.getNodes();
487
488 List result = new ArrayList();
489 while (nodeIterator.hasNext()) {
490 Node node = nodeIterator.nextNode();
491 log.debug("Node found : " + node.getPath());
492 result.add(objectConverter.getObject(session, node.getPath()));
493 }
494
495 return result;
496 }
497 catch(InvalidQueryException iqe) {
498 throw new org.apache.portals.graffito.jcr.exception.RepositoryException("Invalid query expression", iqe);
499 }
500 catch(RepositoryException e) {
501 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
502 "Impossible to get the object collection", e);
503 }
504 }
505
506 /***
507 *
508 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getObjectIterator(org.apache.portals.graffito.jcr.query.Query)
509 */
510 public Iterator getObjectIterator(Query query) {
511 try {
512 String jcrExpression = this.queryManager.buildJCRExpression(query);
513 log.debug("Get Object with expression : " + jcrExpression);
514
515 javax.jcr.query.Query jcrQuery = session.getWorkspace().getQueryManager()
516 .createQuery(jcrExpression, javax.jcr.query.Query.XPATH);
517 QueryResult queryResult = jcrQuery.execute();
518 NodeIterator nodeIterator = queryResult.getNodes();
519
520 return new ObjectIterator(nodeIterator,
521 query.getFilter().getFilterClass(),
522 this.objectConverter,
523 this.session);
524
525 }
526 catch(InvalidQueryException iqe) {
527 throw new org.apache.portals.graffito.jcr.exception.RepositoryException("Invalid query expression", iqe);
528 }
529 catch(RepositoryException e) {
530 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
531 "Impossible to get the object collection", e);
532 }
533 }
534
535 /***
536 *
537 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#checkin(java.lang.String)
538 */
539 public void checkin(String path) {
540 this.checkin(path, null);
541 }
542
543 /***
544 *
545 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#checkin(java.lang.String, java.lang.String[])
546 */
547 public void checkin(String path, String[] versionLabels) {
548 try {
549 Node node = (Node) session.getItem(path);
550 checkIfNodeLocked(node.getPath());
551 if (!node.isNodeType("mix:versionable")) {
552 throw new VersionException("The object " + path + "is not versionable");
553 }
554 javax.jcr.version.Version newVersion = node.checkin();
555
556 if (versionLabels != null) {
557 VersionHistory versionHistory = node.getVersionHistory();
558 for (int i = 0; i < versionLabels.length; i++) {
559 versionHistory.addVersionLabel(newVersion.getName(),
560 versionLabels[i], false);
561 }
562 }
563 }
564 catch(ClassCastException cce) {
565 throw new PersistenceException("Cannot retrieve an object from a property path " + path);
566 }
567 catch(PathNotFoundException pnfe) {
568 throw new PersistenceException("Cannot retrieve an object at path " + path, pnfe);
569 }
570 catch(InvalidItemStateException iise) {
571 throw new PersistenceException("Cannot checking modified object at path " + path, iise);
572 }
573 catch(javax.jcr.version.VersionException ve) {
574 throw new VersionException("Impossible to checkin the object " + path, ve);
575 }
576 catch(UnsupportedRepositoryOperationException uroe) {
577 throw new VersionException("Cannot checkin unversionable node at path " + path, uroe);
578 }
579 catch(LockException le) {
580 throw new VersionException("Cannot checkin locked node at path " + path, le);
581 }
582 catch (RepositoryException e) {
583 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
584 "Impossible to checkin the object " + path, e);
585 }
586
587 }
588
589 /***
590 *
591 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#checkout(java.lang.String)
592 */
593 public void checkout(String path) {
594 Node node = null;
595 try {
596 node = (Node) session.getItem(path);
597 if (!node.isNodeType("mix:versionable")) {
598 throw new VersionException("The object " + path + "is not versionable");
599 }
600
601 node.checkout();
602 }
603 catch(ClassCastException cce) {
604 throw new PersistenceException("Cannot retrieve an object from a property path " + path);
605 }
606 catch(PathNotFoundException pnfe) {
607 throw new PersistenceException("Cannot retrieve an object at path " + path, pnfe);
608 }
609 catch(UnsupportedRepositoryOperationException uroe) {
610 throw new VersionException("Cannot checkout unversionable node at path " + path, uroe);
611 }
612 catch(LockException le) {
613 throw new VersionException("Cannot checkout locked node at path " + path, le);
614 }
615 catch(javax.jcr.RepositoryException e) {
616 throw new org.apache.portals.graffito.jcr.exception.RepositoryException("Impossible to checkout the object " + path, e);
617 }
618
619 }
620
621 /***
622 *
623 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#addVersionLabel(java.lang.String, java.lang.String, java.lang.String)
624 */
625 public void addVersionLabel(String path, String versionName, String versionLabel) {
626 try {
627 Node node = (Node) session.getItem(path);
628 checkIfNodeLocked(path);
629 if (!node.isNodeType("mix:versionable")) {
630 throw new VersionException("The object " + path + "is not versionable");
631 }
632
633 VersionHistory history = node.getVersionHistory();
634 history.addVersionLabel(versionName, versionLabel, false);
635 }
636 catch(ClassCastException cce) {
637 throw new PersistenceException("Cannot retrieve an object from a property path " + path);
638 }
639 catch(PathNotFoundException pnfe) {
640 throw new PersistenceException("Cannot retrieve an object at path " + path, pnfe);
641 }
642 catch(javax.jcr.version.VersionException ve) {
643 throw new VersionException("Impossible to add a new version label to " + path
644 + " - version name : " + versionName,
645 ve);
646 }
647 catch(UnsupportedRepositoryOperationException uroe) {
648 throw new VersionException("Impossible to add a new version label to " + path
649 + " - version name : " + versionName,
650 uroe);
651 }
652 catch(javax.jcr.RepositoryException e) {
653 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(e);
654 }
655 }
656
657 /***
658 *
659 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getVersion(java.lang.String, java.lang.String)
660 */
661 public Version getVersion(String path, String versionName) {
662 try {
663 Node node = (Node) session.getItem(path);
664 if (!node.isNodeType("mix:versionable")) {
665 throw new VersionException("The object " + path + "is not versionable");
666 }
667
668 VersionHistory history = node.getVersionHistory();
669
670 return new Version(history.getVersion(versionName));
671 }
672 catch(ClassCastException cce) {
673 throw new PersistenceException("Cannot retrieve an object from a property path " + path);
674 }
675 catch(PathNotFoundException pnfe) {
676 throw new PersistenceException("Cannot retrieve an object at path " + path, pnfe);
677 }
678 catch(javax.jcr.version.VersionException ve) {
679 throw new VersionException("The version name " + versionName + "does not exist", ve);
680 }
681 catch(UnsupportedRepositoryOperationException uroe) {
682 throw new VersionException("Impossible to retrieve versions for path " + path, uroe);
683 }
684 catch(javax.jcr.RepositoryException e) {
685 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(e);
686 }
687 }
688
689 /***
690 *
691 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getVersionLabels(java.lang.String, java.lang.String)
692 */
693 public String[] getVersionLabels(String path, String versionName) {
694 try {
695 Node node = (Node) session.getItem(path);
696 if (!node.isNodeType("mix:versionable")) {
697 throw new VersionException("The object " + path + "is not versionable");
698 }
699
700 VersionHistory history = node.getVersionHistory();
701 javax.jcr.version.Version version = history.getVersion(versionName);
702
703 return history.getVersionLabels(version);
704 }
705 catch(ClassCastException cce) {
706 throw new PersistenceException("Cannot retrieve an object from a property path " + path);
707 }
708 catch(PathNotFoundException pnfe) {
709 throw new PersistenceException("Cannot retrieve an object at path " + path, pnfe);
710 }
711 catch(javax.jcr.version.VersionException ve) {
712 throw new VersionException("Impossible to get the version labels : " + path
713 + " - version name : " + versionName,
714 ve);
715 }
716 catch(UnsupportedRepositoryOperationException uroe) {
717 throw new VersionException("Impossible to retrieve versions for path " + path, uroe);
718 }
719 catch(RepositoryException e) {
720 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(e);
721 }
722 }
723
724 /***
725 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getAllVersionLabels(java.lang.String)
726 */
727 public String[] getAllVersionLabels(String path) {
728 try {
729 Node node = (Node) session.getItem(path);
730 if (!node.isNodeType("mix:versionable")) {
731 throw new VersionException("The object " + path + "is not versionable");
732 }
733
734 VersionHistory history = node.getVersionHistory();
735
736 return history.getVersionLabels();
737 }
738 catch(ClassCastException cce) {
739 throw new PersistenceException("Cannot retrieve an object from a property path " + path);
740 }
741 catch(PathNotFoundException pnfe) {
742 throw new PersistenceException("Cannot retrieve an object at path " + path, pnfe);
743 }
744 catch(UnsupportedRepositoryOperationException uroe) {
745 throw new VersionException("Impossible to retrieve version history for path " + path, uroe);
746 }
747 catch(RepositoryException e) {
748 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(e);
749 }
750 }
751
752 /***
753 *
754 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getAllVersions(java.lang.String)
755 */
756 public VersionIterator getAllVersions(String path) {
757 try {
758 Node node = (Node) session.getItem(path);
759 if (!node.isNodeType("mix:versionable")) {
760 throw new VersionException("The object " + path
761 + "is not versionable");
762 }
763
764 VersionHistory history = node.getVersionHistory();
765
766 return new VersionIterator(history.getAllVersions());
767 }
768 catch(ClassCastException cce) {
769 throw new PersistenceException("Cannot retrieve an object from a property path " + path);
770 }
771 catch(PathNotFoundException pnfe) {
772 throw new PersistenceException("Cannot retrieve an object at path " + path, pnfe);
773 }
774 catch(UnsupportedRepositoryOperationException uroe) {
775 throw new VersionException("Impossible to retrieve version history for path " + path, uroe);
776 }
777 catch(RepositoryException e) {
778 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(e);
779 }
780 }
781
782 /***
783 *
784 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getRootVersion(java.lang.String)
785 */
786 public Version getRootVersion(String path) {
787 try {
788 Node node = (Node) session.getItem(path);
789 if (!node.isNodeType("mix:versionable")) {
790 throw new VersionException("The object " + path + "is not versionable");
791 }
792
793 VersionHistory history = node.getVersionHistory();
794
795 return new Version(history.getRootVersion());
796 }
797 catch(ClassCastException cce) {
798 throw new PersistenceException("Cannot retrieve an object from a property path " + path);
799 }
800 catch(PathNotFoundException pnfe) {
801 throw new PersistenceException("Cannot retrieve an object at path " + path, pnfe);
802 }
803 catch(UnsupportedRepositoryOperationException uroe) {
804 throw new VersionException("Impossible to get the root version for the object " + path,
805 uroe);
806 }
807 catch(RepositoryException e) {
808 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(e);
809 }
810 }
811
812 /***
813 *
814 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getBaseVersion(java.lang.String)
815 */
816 public Version getBaseVersion(String path) {
817 try {
818 Node node = (Node) session.getItem(path);
819 if (!node.isNodeType("mix:versionable")) {
820 throw new VersionException("The object " + path + "is not versionable");
821 }
822
823 return new Version(node.getBaseVersion());
824 }
825 catch(ClassCastException cce) {
826 throw new PersistenceException("Cannot retrieve an object from a property path " + path);
827 }
828 catch(PathNotFoundException pnfe) {
829 throw new PersistenceException("Cannot retrieve an object at path " + path, pnfe);
830 }
831 catch(UnsupportedRepositoryOperationException uroe) {
832 throw new VersionException("Impossible to get the base version for the object " + path,
833 uroe);
834 }
835 catch(javax.jcr.RepositoryException e) {
836 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(e);
837 }
838 }
839
840 /***
841 *
842 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#lock(java.lang.String, java.lang.Object, boolean, boolean)
843 */
844 public String lock(final String absPath, final boolean isDeep, final boolean isSessionScoped)
845 throws LockedException {
846 try {
847
848
849
850 checkIfNodeLocked(absPath);
851
852 Node node = getNode(absPath);
853 Lock lock = node.lock(isDeep, isSessionScoped);
854
855 return lock.getLockToken();
856 }
857 catch (LockException e) {
858
859 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
860 "Node of type is not type mix:lockable", e);
861 }
862 catch (RepositoryException e) {
863 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(e.getMessage(),
864 e);
865 }
866 }
867
868 /***
869 *
870 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#unlock(java.lang.String, java.lang.Object, java.lang.String)
871 */
872 public void unlock(final String absPath, final String lockToken)
873 throws IllegalUnlockException {
874 String lockOwner = null;
875 try {
876 maybeAddLockToken(lockToken);
877
878 Node node = getNode(absPath);
879 if (node.isLocked() == false) {
880
881 return;
882 }
883
884 Lock lock = node.getLock();
885 lockOwner = lock.getLockOwner();
886
887 node.unlock();
888 }
889 catch (LockException e) {
890
891
892 log.error("Cannot unlock path: "
893 + absPath
894 + " Jcr user: "
895 + session.getUserID()
896 + " has no lock token to do this. Lock was placed with user: "
897 + lockOwner);
898 throw new IllegalUnlockException(lockOwner, absPath);
899 }
900 catch (RepositoryException e) {
901
902 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(e.getMessage(),
903 e);
904 }
905 }
906
907 /***
908 *
909 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#isLocked(java.lang.String)
910 */
911 public boolean isLocked(final String absPath) {
912 try {
913 final Node node = getNode(absPath);
914
915 return node.isLocked();
916 }
917 catch (RepositoryException e) {
918
919 throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
920 "An exception was thrown while checking the lock at path : " + absPath, e);
921 }
922 }
923
924 /***
925 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getQueryManager()
926 */
927 public QueryManager getQueryManager() {
928 return this.queryManager;
929 }
930
931 /***
932 * Throws {@link LockedException} id node is locked so alter nopde cannot be done
933 *
934 * @param absPath
935 * abs path to node
936 * @throws RepositoryException
937 * @throws LockedException
938 * if node is locked
939 */
940 protected void checkIfNodeLocked(final String absPath) throws RepositoryException, LockedException {
941 Node node = getNode(absPath);
942
943
944 if (node.isLocked()) {
945 Lock lock = node.getLock();
946 String lockOwner = lock.getLockOwner();
947 final String path = lock.getNode().getPath();
948 throw new LockedException(lockOwner, path);
949 }
950 }
951
952 protected void maybeAddLockToken(final String lockToken) {
953 if (lockToken != null) {
954
955
956 final String[] lockTokens = getSession().getLockTokens();
957 if (lockTokens != null) {
958 for(int i= 0; i < lockTokens.length; i++) {
959 if(lockTokens[i].equals(lockToken)) {
960
961 break;
962 }
963 }
964 } else {
965 getSession().addLockToken(lockToken);
966 }
967 }
968 }
969
970 protected Node getNode(final String absPath) throws PathNotFoundException, RepositoryException {
971 if (!getSession().itemExists(absPath)) {
972 throw new PersistenceException("No object stored on path: " + absPath);
973 }
974 Item item = getSession().getItem(absPath);
975 if (!item.isNode()) {
976 throw new PersistenceException("No object stored on path: " + absPath
977 + " on absPath is item (leaf)");
978 }
979
980 return (Node) item;
981 }
982
983 /***
984 *
985 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#logout()
986 */
987 public void logout() {
988 try {
989 log.debug("Logout. Persisting current session changes.");
990 this.session.save();
991 this.session.logout();
992 log.debug("Session closed");
993 }
994 catch(NoSuchNodeTypeException nsnte) {
995 throw new JcrMappingException(
996 "Cannot persist current session changes. An unknown node type was used.", nsnte);
997 }
998 catch(javax.jcr.version.VersionException ve) {
999 throw new VersionException(
1000 "Cannot persist current session changes. Attempt to overwrite checked-in node", ve);
1001 }
1002 catch(LockException le) {
1003 throw new PersistenceException(
1004 "Cannot persist current session changes. Violation of a lock detected", le);
1005 }
1006 catch(javax.jcr.RepositoryException e) {
1007 throw new PersistenceException(
1008 "Cannot persist current session changes.", e);
1009 }
1010 }
1011
1012 /***
1013 *
1014 * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#save()
1015 */
1016 public void save() {
1017 try {
1018 this.session.save();
1019 }
1020 catch(NoSuchNodeTypeException nsnte) {
1021 throw new JcrMappingException(
1022 "Cannot persist current session changes. An unknown node type was used.", nsnte);
1023 }
1024 catch(javax.jcr.version.VersionException ve) {
1025 throw new VersionException(
1026 "Cannot persist current session changes. Attempt to overwrite checked-in node", ve);
1027 }
1028 catch(LockException le) {
1029 throw new PersistenceException(
1030 "Cannot persist current session changes. Violation of a lock detected", le);
1031 }
1032 catch(RepositoryException e) {
1033 throw new PersistenceException(
1034 "Cannot persist current session changes.", e);
1035 }
1036 }
1037
1038 /***
1039 * @return The JCR Session
1040 */
1041 public Session getSession() {
1042 return this.session;
1043 }
1044
1045 }