1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.modeshape.jcr;
25
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.security.AccessControlException;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.HashSet;
32 import java.util.LinkedList;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36 import java.util.UUID;
37 import javax.jcr.AccessDeniedException;
38 import javax.jcr.InvalidSerializedDataException;
39 import javax.jcr.ItemExistsException;
40 import javax.jcr.ItemNotFoundException;
41 import javax.jcr.NoSuchWorkspaceException;
42 import javax.jcr.NodeIterator;
43 import javax.jcr.PathNotFoundException;
44 import javax.jcr.RepositoryException;
45 import javax.jcr.Session;
46 import javax.jcr.UnsupportedRepositoryOperationException;
47 import javax.jcr.Workspace;
48 import javax.jcr.lock.Lock;
49 import javax.jcr.lock.LockException;
50 import javax.jcr.lock.LockManager;
51 import javax.jcr.nodetype.ConstraintViolationException;
52 import javax.jcr.nodetype.NodeTypeManager;
53 import javax.jcr.observation.ObservationManager;
54 import javax.jcr.query.QueryManager;
55 import javax.jcr.version.Version;
56 import javax.jcr.version.VersionException;
57 import javax.jcr.version.VersionManager;
58 import net.jcip.annotations.NotThreadSafe;
59 import org.modeshape.common.util.CheckArg;
60 import org.modeshape.graph.ExecutionContext;
61 import org.modeshape.graph.Location;
62 import org.modeshape.graph.Subgraph;
63 import org.modeshape.graph.SubgraphNode;
64 import org.modeshape.graph.connector.RepositoryConnectionFactory;
65 import org.modeshape.graph.connector.RepositorySource;
66 import org.modeshape.graph.connector.RepositorySourceException;
67 import org.modeshape.graph.connector.UuidAlreadyExistsException;
68 import org.modeshape.graph.property.Name;
69 import org.modeshape.graph.property.NameFactory;
70 import org.modeshape.graph.property.NamespaceRegistry;
71 import org.modeshape.graph.property.Path;
72 import org.modeshape.graph.property.PathFactory;
73 import org.modeshape.graph.property.Property;
74 import org.modeshape.graph.property.PropertyFactory;
75 import org.modeshape.graph.property.ValueFormatException;
76 import org.modeshape.graph.property.basic.LocalNamespaceRegistry;
77 import org.modeshape.graph.request.InvalidWorkspaceException;
78 import org.modeshape.graph.request.ReadBranchRequest;
79 import org.modeshape.graph.session.GraphSession;
80 import org.modeshape.graph.session.GraphSession.Node;
81 import org.modeshape.jcr.JcrContentHandler.EnclosingSAXException;
82 import org.modeshape.jcr.JcrContentHandler.SaveMode;
83 import org.modeshape.jcr.SessionCache.JcrNodePayload;
84 import org.modeshape.jcr.SessionCache.JcrPropertyPayload;
85 import org.modeshape.jcr.WorkspaceLockManager.ModeShapeLock;
86 import org.xml.sax.ContentHandler;
87 import org.xml.sax.InputSource;
88 import org.xml.sax.SAXException;
89 import org.xml.sax.SAXParseException;
90 import org.xml.sax.XMLReader;
91 import org.xml.sax.helpers.XMLReaderFactory;
92
93
94
95
96 @NotThreadSafe
97 class JcrWorkspace implements Workspace {
98
99
100
101
102
103
104 private final String name;
105
106
107
108
109 private final ExecutionContext context;
110
111
112
113
114
115
116 private final JcrRepository repository;
117
118
119
120
121
122
123
124 private final JcrGraph graph;
125
126
127
128
129
130
131 private final JcrNamespaceRegistry workspaceRegistry;
132
133
134
135
136 private final JcrNodeTypeManager nodeTypeManager;
137
138
139
140
141 private final JcrVersionManager versionManager;
142
143
144
145
146 private final JcrQueryManager queryManager;
147
148
149
150
151 private final JcrObservationManager observationManager;
152
153 private final JcrLockManager lockManager;
154
155
156
157
158 private final JcrSession session;
159
160 JcrWorkspace( JcrRepository repository,
161 String workspaceName,
162 ExecutionContext context,
163 Map<String, Object> sessionAttributes ) {
164
165 assert workspaceName != null;
166 assert context != null;
167 assert context.getSecurityContext() != null;
168 assert repository != null;
169 this.name = workspaceName;
170 this.repository = repository;
171
172
173 NamespaceRegistry globalRegistry = context.getNamespaceRegistry();
174 LocalNamespaceRegistry localRegistry = new LocalNamespaceRegistry(globalRegistry);
175 this.context = context.with(localRegistry);
176
177
178
179 localRegistry.getNamespaces();
180
181
182 this.graph = this.repository.createWorkspaceGraph(this.name, this.context);
183
184
185 this.session = new JcrSession(this.repository, this, this.context, globalRegistry, sessionAttributes);
186
187
188 this.nodeTypeManager = new JcrNodeTypeManager(session, this.repository.getRepositoryTypeManager());
189 this.versionManager = new JcrVersionManager(this.session);
190 this.queryManager = new JcrQueryManager(this.session);
191 this.observationManager = new JcrObservationManager(this.session, this.repository.getRepositoryObservable());
192
193
194
195
196
197
198
199 this.workspaceRegistry = new JcrNamespaceRegistry(this.repository.getPersistentRegistry(), this.session);
200 this.lockManager = new JcrLockManager(session, repository.getRepositoryLockManager().getLockManager(workspaceName));
201
202 }
203
204 final JcrGraph graph() {
205 return this.graph;
206 }
207
208 final String getSourceName() {
209 return this.repository.getRepositorySourceName();
210 }
211
212 final JcrNodeTypeManager nodeTypeManager() {
213 return this.nodeTypeManager;
214 }
215
216 final ExecutionContext context() {
217 return this.context;
218 }
219
220 final JcrLockManager lockManager() {
221 return this.lockManager;
222 }
223
224 final JcrObservationManager observationManager() {
225 return this.observationManager;
226 }
227
228 final JcrQueryManager queryManager() {
229 return this.queryManager;
230 }
231
232
233
234
235 public final String getName() {
236 return name;
237 }
238
239
240
241
242 public final Session getSession() {
243 return this.session;
244 }
245
246
247
248
249
250
251 public final javax.jcr.NamespaceRegistry getNamespaceRegistry() {
252 return workspaceRegistry;
253 }
254
255
256
257
258 public String[] getAccessibleWorkspaceNames() throws RepositoryException {
259 session.checkLive();
260 try {
261 Set<String> workspaceNamesFromGraph = graph.getWorkspaces();
262 Set<String> workspaceNames = new HashSet<String>(workspaceNamesFromGraph.size());
263
264 for (String workspaceName : workspaceNamesFromGraph) {
265 try {
266 session.checkPermission(workspaceName, null, ModeShapePermissions.READ);
267 workspaceNames.add(workspaceName);
268 } catch (AccessControlException ace) {
269
270 }
271 }
272
273 return workspaceNames.toArray(new String[workspaceNames.size()]);
274 } catch (RepositorySourceException e) {
275 throw new RepositoryException(JcrI18n.errorObtainingWorkspaceNames.text(getSourceName(), e.getMessage()), e);
276 }
277 }
278
279
280
281
282 public final NodeTypeManager getNodeTypeManager() {
283 return nodeTypeManager;
284 }
285
286
287
288
289
290
291 public final ObservationManager getObservationManager() {
292 return this.observationManager;
293 }
294
295
296
297
298 public LockManager getLockManager() {
299 return lockManager;
300 }
301
302
303
304
305 public final QueryManager getQueryManager() {
306 return queryManager;
307 }
308
309 final JcrVersionManager versionManager() {
310 return versionManager;
311 }
312
313
314
315
316
317
318 public void clone( String srcWorkspace,
319 String srcAbsPath,
320 String destAbsPath,
321 boolean removeExisting )
322 throws ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException,
323 LockException, RepositoryException {
324 CheckArg.isNotNull(srcWorkspace, "source workspace name");
325 CheckArg.isNotNull(srcAbsPath, "source path");
326 CheckArg.isNotNull(destAbsPath, "destination path");
327
328 final boolean sameWorkspace = getName().equals(srcWorkspace);
329 if (sameWorkspace && removeExisting) {
330
331 move(srcAbsPath, destAbsPath);
332 return;
333 }
334
335 session.checkLive();
336 if (!sameWorkspace && !graph.getWorkspaces().contains(srcWorkspace)) {
337 throw new NoSuchWorkspaceException(JcrI18n.workspaceNameIsInvalid.text(graph.getSourceName(), this.name));
338 }
339
340
341 PathFactory factory = context.getValueFactories().getPathFactory();
342 Path srcPath = null;
343 Path destPath = null;
344 try {
345 srcPath = factory.create(srcAbsPath);
346 } catch (ValueFormatException e) {
347 throw new PathNotFoundException(JcrI18n.invalidPathParameter.text(srcAbsPath, "srcAbsPath"), e);
348 }
349 try {
350 destPath = factory.create(destAbsPath);
351 } catch (ValueFormatException e) {
352 throw new PathNotFoundException(JcrI18n.invalidPathParameter.text(destAbsPath, "destAbsPath"), e);
353 }
354
355
356 if (!sameWorkspace && !destPath.isIdentifier() && destAbsPath.endsWith("]")) {
357 throw new RepositoryException(JcrI18n.pathCannotHaveSameNameSiblingIndex.text(destAbsPath));
358 }
359
360 try {
361
362
363 SessionCache cache = this.session.cache();
364 AbstractJcrNode parentNode = null;
365 Name newNodeName = null;
366 if (destPath.isIdentifier()) {
367 AbstractJcrNode existingDestNode = cache.findJcrNode(Location.create(destPath));
368 parentNode = existingDestNode.getParent();
369 newNodeName = existingDestNode.segment().getName();
370 destPath = factory.create(parentNode.path(), newNodeName);
371 } else {
372 parentNode = cache.findJcrNode(null, destPath.getParent());
373 newNodeName = destPath.getLastSegment().getName();
374 }
375
376
377
378
379 org.modeshape.graph.Node sourceNode = repository.createWorkspaceGraph(srcWorkspace, context).getNodeAt(srcPath);
380 Property uuidProp = sourceNode.getProperty(ModeShapeLexicon.UUID);
381 UUID sourceUuid = null;
382
383 if (uuidProp != null) {
384 sourceUuid = this.context.getValueFactories().getUuidFactory().create(uuidProp.getFirstValue());
385
386 ModeShapeLock sourceLock = lockManager().lockFor(sourceUuid);
387 if (sourceLock != null && sourceLock.getLockToken() == null) {
388 throw new LockException(JcrI18n.lockTokenNotHeld.text(srcAbsPath));
389 }
390 }
391
392 if (parentNode.isLocked()) {
393 Lock newParentLock = parentNode.getLock();
394 if (newParentLock != null && newParentLock.getLockToken() == null) {
395 throw new LockException(destAbsPath);
396 }
397 }
398
399 if (!parentNode.isCheckedOut()) {
400 throw new VersionException(JcrI18n.nodeIsCheckedIn.text(parentNode.getPath()));
401 }
402
403
404 Node<JcrNodePayload, JcrPropertyPayload> parent = cache.findNode(parentNode.nodeId, parentNode.path());
405 JcrNodeDefinition childDefn = null;
406 try {
407 childDefn = cache.findBestNodeDefinition(parent, newNodeName, parent.getPayload().getPrimaryTypeName());
408 } catch (RepositoryException e) {
409 if (sameWorkspace) {
410
411
412 AbstractJcrNode originalShareable = cache.findJcrNode(Location.create(sourceUuid));
413 Name originalShareablePrimaryType = originalShareable.getPrimaryTypeName();
414 childDefn = cache.findBestNodeDefinition(parent, newNodeName, originalShareablePrimaryType);
415 } else {
416 throw e;
417 }
418 }
419
420 if (sameWorkspace) {
421 assert !removeExisting;
422
423
424 Property primaryType = sourceNode.getProperty(JcrLexicon.PRIMARY_TYPE);
425 NameFactory nameFactory = context.getValueFactories().getNameFactory();
426 boolean shareable = false;
427 if (primaryType != null) {
428 Name primaryTypeName = nameFactory.create(primaryType.getFirstValue());
429 JcrNodeType nodeType = nodeTypeManager().getNodeType(primaryTypeName);
430 if (nodeType != null && nodeType.isNodeType(JcrMixLexicon.SHAREABLE)) shareable = true;
431 }
432 if (!shareable) {
433 Property mixinTypes = sourceNode.getProperty(JcrLexicon.MIXIN_TYPES);
434 if (mixinTypes != null) {
435 for (Object value : mixinTypes) {
436 Name mixinTypeName = nameFactory.create(value);
437 JcrNodeType nodeType = nodeTypeManager().getNodeType(mixinTypeName);
438 if (nodeType != null && nodeType.isNodeType(JcrMixLexicon.SHAREABLE)) {
439 shareable = true;
440 break;
441 }
442 }
443 }
444 }
445 if (shareable) {
446
447
448
449 assert sourceUuid != null;
450 assert childDefn != null;
451 PropertyFactory propertyFactory = context.getPropertyFactory();
452 Collection<Property> properties = new ArrayList<Property>(2);
453 properties.add(propertyFactory.create(JcrLexicon.PRIMARY_TYPE, ModeShapeLexicon.SHARE));
454 properties.add(propertyFactory.create(ModeShapeLexicon.SHARED_UUID, sourceUuid));
455 properties.add(propertyFactory.create(ModeShapeIntLexicon.NODE_DEFINITON, childDefn.getId().getString()));
456 cache.graphSession().immediateCreateOrReplace(destPath, properties);
457 return;
458 }
459
460
461 }
462 if (removeExisting) {
463
464
465
466
467 Set<UUID> uuidsInCloneBranch = getUuidsInBranch(srcPath, srcWorkspace);
468 if (!uuidsInCloneBranch.isEmpty()) {
469
470
471 GraphSession<JcrNodePayload, JcrPropertyPayload> graphSession = cache.graphSession();
472 Node<JcrNodePayload, JcrPropertyPayload> node = null;
473 for (UUID uuid : uuidsInCloneBranch) {
474 Location location = Location.create(uuid);
475 try {
476 node = graphSession.findNodeWith(location);
477 } catch (org.modeshape.graph.property.PathNotFoundException e) {
478
479 continue;
480 }
481
482 NodeDefinitionId childDefnId = node.getPayload().getDefinitionId();
483 JcrNodeType nodeType = nodeTypeManager().getNodeType(childDefnId.getNodeTypeName());
484 childDefn = nodeType.childNodeDefinition(childDefnId);
485 if (childDefn.isMandatory()) {
486
487 String path = node.getPath().getString(context.getNamespaceRegistry());
488 throw new ConstraintViolationException(JcrI18n.cannotRemoveNodeFromClone.text(path, uuid));
489 }
490
491 if (node.isChanged(true)) {
492
493 String path = node.getPath().getString(context.getNamespaceRegistry());
494 throw new RepositoryException(JcrI18n.cannotRemoveNodeFromCloneDueToChangesInSession.text(path, uuid));
495 }
496 }
497 }
498 }
499
500
501 cache.graphSession().immediateClone(srcPath, srcWorkspace, destPath, removeExisting, false);
502 } catch (ItemNotFoundException e) {
503
504 throw new PathNotFoundException(e.getLocalizedMessage(), e);
505 } catch (org.modeshape.graph.property.PathNotFoundException e) {
506 throw new PathNotFoundException(e.getLocalizedMessage(), e);
507 } catch (UuidAlreadyExistsException e) {
508 throw new ItemExistsException(e.getLocalizedMessage(), e);
509 } catch (InvalidWorkspaceException e) {
510 throw new NoSuchWorkspaceException(e.getLocalizedMessage(), e);
511 } catch (RepositorySourceException e) {
512 throw new RepositoryException(e.getLocalizedMessage(), e);
513 } catch (AccessControlException ace) {
514 throw new AccessDeniedException(ace);
515 }
516 }
517
518 protected Set<UUID> getUuidsInBranch( Path sourcePath,
519 String workspace ) {
520 String existingWorkspace = graph.getCurrentWorkspaceName();
521 try {
522 graph.useWorkspace(workspace);
523 Location location = Location.create(sourcePath);
524 Subgraph subgraph = graph.getSubgraphOfDepth(ReadBranchRequest.NO_MAXIMUM_DEPTH).at(location);
525
526 Set<UUID> uuids = new HashSet<UUID>();
527 for (SubgraphNode nodeInSubgraph : subgraph) {
528 UUID uuid = nodeInSubgraph.getLocation().getUuid();
529 if (uuid != null) uuids.add(uuid);
530 }
531 return uuids;
532 } finally {
533 graph.useWorkspace(existingWorkspace);
534 }
535 }
536
537
538
539
540
541
542 public void copy( String srcAbsPath,
543 String destAbsPath )
544 throws ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException,
545 LockException, RepositoryException {
546 this.copy(this.name, srcAbsPath, destAbsPath);
547 }
548
549
550
551
552 public void copy( String srcWorkspace,
553 String srcAbsPath,
554 String destAbsPath )
555 throws ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException,
556 LockException, RepositoryException {
557 CheckArg.isNotNull(srcWorkspace, "source workspace name");
558 CheckArg.isNotNull(srcAbsPath, "source path");
559 CheckArg.isNotNull(destAbsPath, "destination path");
560 session.checkLive();
561
562 if (!graph.getWorkspaces().contains(srcWorkspace)) {
563 throw new NoSuchWorkspaceException(JcrI18n.workspaceNameIsInvalid.text(graph.getSourceName(), this.name));
564 }
565
566
567 PathFactory factory = context.getValueFactories().getPathFactory();
568 Path srcPath = null;
569 Path destPath = null;
570 try {
571 srcPath = factory.create(srcAbsPath);
572 } catch (ValueFormatException e) {
573 throw new PathNotFoundException(JcrI18n.invalidPathParameter.text(srcAbsPath, "srcAbsPath"), e);
574 }
575 try {
576 destPath = factory.create(destAbsPath);
577 } catch (ValueFormatException e) {
578 throw new PathNotFoundException(JcrI18n.invalidPathParameter.text(destAbsPath, "destAbsPath"), e);
579 }
580
581
582 if (!destPath.isIdentifier() && destAbsPath.endsWith("]")) {
583 throw new RepositoryException(JcrI18n.pathCannotHaveSameNameSiblingIndex.text(destAbsPath));
584 }
585
586 try {
587
588
589 SessionCache cache = this.session.cache();
590 AbstractJcrNode parentNode = null;
591 Name newNodeName = null;
592 if (destPath.isIdentifier()) {
593 AbstractJcrNode existingDestNode = cache.findJcrNode(Location.create(destPath));
594 parentNode = existingDestNode.getParent();
595 newNodeName = existingDestNode.segment().getName();
596 destPath = factory.create(parentNode.path(), newNodeName);
597 } else {
598 parentNode = cache.findJcrNode(null, destPath.getParent());
599 newNodeName = destPath.getLastSegment().getName();
600 }
601
602
603
604
605 org.modeshape.graph.Node sourceNode = repository.createWorkspaceGraph(srcWorkspace, context).getNodeAt(srcPath);
606 Property uuidProp = sourceNode.getProperty(ModeShapeLexicon.UUID);
607
608 if (uuidProp != null) {
609 UUID sourceUuid = this.context.getValueFactories().getUuidFactory().create(uuidProp.getFirstValue());
610
611 ModeShapeLock sourceLock = lockManager().lockFor(sourceUuid);
612 if (sourceLock != null && sourceLock.getLockToken() == null) {
613 throw new LockException(srcAbsPath);
614 }
615 }
616
617
618
619
620 Property primaryTypeProp = sourceNode.getProperty(JcrLexicon.PRIMARY_TYPE);
621 Name primaryTypeName = this.context.getValueFactories().getNameFactory().create(primaryTypeProp.getFirstValue());
622
623 if (parentNode.isLocked()) {
624 Lock newParentLock = parentNode.getLock();
625 if (newParentLock != null && newParentLock.getLockToken() == null) {
626 throw new LockException(destAbsPath);
627 }
628 }
629
630 if (!parentNode.isCheckedOut()) {
631 throw new VersionException(JcrI18n.nodeIsCheckedIn.text(parentNode.getPath()));
632 }
633
634 cache.findBestNodeDefinition(parentNode.nodeInfo(), newNodeName, primaryTypeName);
635
636
637 cache.graphSession().immediateCopy(srcPath, srcWorkspace, destPath);
638
639 List<AbstractJcrNode> nodesToCheck = new LinkedList<AbstractJcrNode>();
640 nodesToCheck.add(cache.findJcrNode(Location.create(destPath)));
641
642 while (!nodesToCheck.isEmpty()) {
643 AbstractJcrNode node = nodesToCheck.remove(0);
644
645 if (node.isNodeType(JcrMixLexicon.VERSIONABLE)) {
646
647 Path nodeDestPath = node.path().relativeTo(destPath);
648 Path nodeSourcePath = nodeDestPath.resolveAgainst(srcPath);
649
650 AbstractJcrNode fromNode = cache.findJcrNode(Location.create(nodeSourcePath));
651 if (!(fromNode instanceof JcrSharedNode)) {
652 UUID originalVersion = fromNode.getBaseVersion().uuid();
653 versionManager.initializeVersionHistoryFor(node, originalVersion);
654 }
655 }
656
657 for (NodeIterator iter = node.getNodes(); iter.hasNext();) {
658 nodesToCheck.add((AbstractJcrNode)iter.nextNode());
659 }
660 }
661
662 } catch (ItemNotFoundException e) {
663
664 throw new PathNotFoundException(e.getLocalizedMessage(), e);
665 } catch (org.modeshape.graph.property.PathNotFoundException e) {
666 throw new PathNotFoundException(e.getLocalizedMessage(), e);
667 } catch (UuidAlreadyExistsException e) {
668 throw new ItemExistsException(e.getLocalizedMessage(), e);
669 } catch (InvalidWorkspaceException e) {
670 throw new NoSuchWorkspaceException(e.getLocalizedMessage(), e);
671 } catch (RepositorySourceException e) {
672 throw new RepositoryException(e.getLocalizedMessage(), e);
673 } catch (AccessControlException ace) {
674 throw new AccessDeniedException(ace);
675 }
676 }
677
678
679
680
681
682
683 public ContentHandler getImportContentHandler( String parentAbsPath,
684 int uuidBehavior )
685 throws PathNotFoundException, ConstraintViolationException, VersionException, LockException, AccessDeniedException,
686 RepositoryException {
687
688 CheckArg.isNotNull(parentAbsPath, "parentAbsPath");
689 session.checkLive();
690 Path parentPath = this.context.getValueFactories().getPathFactory().create(parentAbsPath);
691 return new JcrContentHandler(this.session, parentPath, uuidBehavior, SaveMode.WORKSPACE);
692 }
693
694
695
696
697
698
699 public void importXML( String parentAbsPath,
700 InputStream in,
701 int uuidBehavior )
702 throws IOException, PathNotFoundException, ItemExistsException, ConstraintViolationException,
703 InvalidSerializedDataException, LockException, AccessDeniedException, RepositoryException {
704
705 CheckArg.isNotNull(parentAbsPath, "parentAbsPath");
706 CheckArg.isNotNull(in, "in");
707 session.checkLive();
708
709 try {
710 XMLReader parser = XMLReaderFactory.createXMLReader();
711 parser.setContentHandler(getImportContentHandler(parentAbsPath, uuidBehavior));
712 parser.parse(new InputSource(in));
713 } catch (EnclosingSAXException ese) {
714 Exception cause = ese.getException();
715 if (cause instanceof ItemExistsException) {
716 throw (ItemExistsException)cause;
717 } else if (cause instanceof ConstraintViolationException) {
718 throw (ConstraintViolationException)cause;
719 }
720 throw new RepositoryException(cause);
721 } catch (SAXParseException se) {
722 throw new InvalidSerializedDataException(se);
723 } catch (SAXException se) {
724 throw new RepositoryException(se);
725 }
726
727 }
728
729
730
731
732
733
734 public void move( String srcAbsPath,
735 String destAbsPath ) throws PathNotFoundException, RepositoryException {
736 CheckArg.isNotEmpty(srcAbsPath, "srcAbsPath");
737 CheckArg.isNotEmpty(destAbsPath, "destAbsPath");
738 session.checkLive();
739
740
741 PathFactory factory = context.getValueFactories().getPathFactory();
742 Path srcPath = null;
743 Path destPath = null;
744 try {
745 srcPath = factory.create(srcAbsPath);
746 } catch (ValueFormatException e) {
747 throw new PathNotFoundException(JcrI18n.invalidPathParameter.text(srcAbsPath, "srcAbsPath"), e);
748 }
749 try {
750 destPath = factory.create(destAbsPath);
751 } catch (ValueFormatException e) {
752 throw new PathNotFoundException(JcrI18n.invalidPathParameter.text(destAbsPath, "destAbsPath"), e);
753 }
754
755
756 if (!destPath.isIdentifier() && destAbsPath.endsWith("]")) {
757 throw new RepositoryException(JcrI18n.pathCannotHaveSameNameSiblingIndex.text(destAbsPath));
758 }
759
760 try {
761
762
763 SessionCache cache = this.session.cache();
764 Node<JcrNodePayload, JcrPropertyPayload> newParent = null;
765 Name newNodeName = null;
766 if (destPath.isIdentifier()) {
767 Node<JcrNodePayload, JcrPropertyPayload> existingDestNode = cache.findNodeWith(Location.create(destPath));
768 newParent = existingDestNode.getParent();
769 newNodeName = existingDestNode.getName();
770 destPath = factory.create(newParent.getPath(), newNodeName);
771 } else {
772 newParent = cache.findNode(null, destPath.getParent());
773 newNodeName = destPath.getLastSegment().getName();
774 }
775
776 cache.findBestNodeDefinition(newParent, newNodeName, newParent.getPayload().getPrimaryTypeName());
777
778 AbstractJcrNode sourceNode = cache.findJcrNode(Location.create(srcPath));
779
780 if (sourceNode.isLocked()) {
781 Lock sourceLock = sourceNode.getLock();
782 if (sourceLock != null && sourceLock.getLockToken() == null) {
783 throw new LockException(srcAbsPath);
784 }
785 }
786
787 AbstractJcrNode parentNode = cache.findJcrNode(newParent.getNodeId(), newParent.getPath());
788
789 if (parentNode.isLocked()) {
790 Lock newParentLock = parentNode.getLock();
791 if (newParentLock != null && newParentLock.getLockToken() == null) {
792 throw new LockException(destAbsPath);
793 }
794 }
795
796 if (!sourceNode.isCheckedOut()) {
797 throw new VersionException(JcrI18n.nodeIsCheckedIn.text(sourceNode.getPath()));
798 }
799
800 if (!parentNode.isCheckedOut()) {
801 throw new VersionException(JcrI18n.nodeIsCheckedIn.text(parentNode.getPath()));
802 }
803
804
805 cache.graphSession().immediateMove(srcPath, destPath);
806 } catch (AccessControlException ace) {
807 throw new AccessDeniedException(ace);
808 } catch (ItemNotFoundException infe) {
809 throw new PathNotFoundException(infe);
810 } catch (org.modeshape.graph.property.PathNotFoundException pnfe) {
811 throw new PathNotFoundException(pnfe);
812 }
813 }
814
815
816
817
818
819
820 public void restore( Version[] versions,
821 boolean removeExisting ) throws RepositoryException {
822 versionManager().restore(versions, removeExisting);
823 }
824
825
826
827
828
829
830
831
832
833
834 @Override
835 public void createWorkspace( String name,
836 String srcWorkspace )
837 throws AccessDeniedException, UnsupportedRepositoryOperationException, NoSuchWorkspaceException, RepositoryException {
838 CheckArg.isNotNull(name, "name");
839 CheckArg.isNotNull(srcWorkspace, "srcWorkspace");
840 session.checkLive();
841 try {
842 session.checkPermission(srcWorkspace, null, ModeShapePermissions.READ);
843 session.checkPermission(name, null, ModeShapePermissions.CREATE_WORKSPACE);
844 repository.createWorkspace(name, srcWorkspace);
845 } catch (AccessControlException e) {
846 throw new AccessDeniedException(e);
847 } catch (InvalidWorkspaceException e) {
848 throw new NoSuchWorkspaceException(e);
849 } catch (RepositorySourceException e) {
850 throw new RepositoryException(e);
851 }
852 }
853
854
855
856
857
858
859
860
861
862 @Override
863 public void createWorkspace( String name )
864 throws AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
865 CheckArg.isNotNull(name, "name");
866 session.checkLive();
867 try {
868 session.checkPermission(name, null, ModeShapePermissions.CREATE_WORKSPACE);
869 repository.createWorkspace(name, null);
870 } catch (AccessControlException e) {
871 throw new AccessDeniedException(e);
872 } catch (InvalidWorkspaceException e) {
873 throw new RepositoryException(e);
874 } catch (RepositorySourceException e) {
875 throw new RepositoryException(e);
876 }
877 }
878
879
880
881
882
883
884
885
886
887
888 @Override
889 public void deleteWorkspace( String name )
890 throws AccessDeniedException, UnsupportedRepositoryOperationException, NoSuchWorkspaceException, RepositoryException {
891 CheckArg.isNotNull(name, "name");
892 session.checkLive();
893 try {
894 session.checkPermission(name, null, ModeShapePermissions.DELETE_WORKSPACE);
895 repository.destroyWorkspace(name, this);
896 } catch (AccessControlException e) {
897 throw new AccessDeniedException(e);
898 } catch (InvalidWorkspaceException e) {
899 throw new RepositoryException(e);
900 } catch (RepositorySourceException e) {
901 throw new RepositoryException(e);
902 }
903 }
904
905
906
907
908
909
910 @Override
911 public VersionManager getVersionManager() {
912 return versionManager;
913 }
914
915 }