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.connector.jcr;
25
26 import java.util.Calendar;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.Map;
31 import java.util.Set;
32 import java.util.UUID;
33 import javax.jcr.Credentials;
34 import javax.jcr.ItemNotFoundException;
35 import javax.jcr.NoSuchWorkspaceException;
36 import javax.jcr.Node;
37 import javax.jcr.NodeIterator;
38 import javax.jcr.PropertyIterator;
39 import javax.jcr.Repository;
40 import javax.jcr.RepositoryException;
41 import javax.jcr.Session;
42 import javax.jcr.Value;
43 import net.jcip.annotations.NotThreadSafe;
44 import org.modeshape.graph.ExecutionContext;
45 import org.modeshape.graph.JcrLexicon;
46 import org.modeshape.graph.Location;
47 import org.modeshape.graph.ModeShapeIntLexicon;
48 import org.modeshape.graph.ModeShapeLexicon;
49 import org.modeshape.graph.cache.CachePolicy;
50 import org.modeshape.graph.observe.Observer;
51 import org.modeshape.graph.property.Binary;
52 import org.modeshape.graph.property.Name;
53 import org.modeshape.graph.property.NameFactory;
54 import org.modeshape.graph.property.NamespaceRegistry;
55 import org.modeshape.graph.property.Path;
56 import org.modeshape.graph.property.PathNotFoundException;
57 import org.modeshape.graph.property.Property;
58 import org.modeshape.graph.property.PropertyFactory;
59 import org.modeshape.graph.property.PropertyType;
60 import org.modeshape.graph.property.ValueFactories;
61 import org.modeshape.graph.property.ValueFactory;
62 import org.modeshape.graph.property.ValueFormatException;
63 import org.modeshape.graph.request.CloneBranchRequest;
64 import org.modeshape.graph.request.CloneWorkspaceRequest;
65 import org.modeshape.graph.request.CopyBranchRequest;
66 import org.modeshape.graph.request.CreateNodeRequest;
67 import org.modeshape.graph.request.CreateWorkspaceRequest;
68 import org.modeshape.graph.request.DeleteBranchRequest;
69 import org.modeshape.graph.request.DestroyWorkspaceRequest;
70 import org.modeshape.graph.request.GetWorkspacesRequest;
71 import org.modeshape.graph.request.InvalidRequestException;
72 import org.modeshape.graph.request.InvalidWorkspaceException;
73 import org.modeshape.graph.request.MoveBranchRequest;
74 import org.modeshape.graph.request.ReadAllChildrenRequest;
75 import org.modeshape.graph.request.ReadAllPropertiesRequest;
76 import org.modeshape.graph.request.ReadNodeRequest;
77 import org.modeshape.graph.request.Request;
78 import org.modeshape.graph.request.UnsupportedRequestException;
79 import org.modeshape.graph.request.UpdatePropertiesRequest;
80 import org.modeshape.graph.request.VerifyWorkspaceRequest;
81 import org.modeshape.graph.request.processor.RequestProcessor;
82
83
84
85
86 @NotThreadSafe
87 public class JcrRequestProcessor extends RequestProcessor {
88
89 private final Map<String, Workspace> workspaces = new HashMap<String, Workspace>();
90
91 private final Repository repository;
92 private final Credentials credentials;
93
94
95
96
97
98
99
100
101
102 public JcrRequestProcessor( String sourceName,
103 ExecutionContext context,
104 Repository repository,
105 Observer observer,
106 Credentials credentials,
107 CachePolicy defaultCachePolicy ) {
108 super(sourceName, context, observer, null, defaultCachePolicy);
109 this.repository = repository;
110 this.credentials = credentials;
111 }
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128 protected Workspace workspaceFor( String workspaceName ) throws RepositoryException {
129 Workspace workspace = workspaces.get(workspaceName);
130 if (workspace == null) {
131 Session session = null;
132 try {
133
134 if (credentials != null) {
135
136 session = repository.login(credentials, workspaceName);
137 } else {
138
139 session = repository.login(workspaceName);
140 }
141 } catch (NoSuchWorkspaceException e) {
142 throw new InvalidWorkspaceException(e.getLocalizedMessage());
143 }
144 assert session != null;
145 workspace = new Workspace(session);
146 workspaces.put(workspaceName, workspace);
147 if (workspaceName == null) {
148
149 workspaces.put(null, workspace);
150 }
151 }
152 return workspace;
153 }
154
155
156
157
158
159
160
161 protected Workspace workspace() throws RepositoryException {
162 if (workspaces.isEmpty()) {
163
164 return workspaceFor(null);
165 }
166
167 return workspaces.values().iterator().next();
168 }
169
170
171
172
173
174
175
176
177 protected boolean workspaceExistsNamed( String workspaceName ) throws RepositoryException {
178 if (workspaces.containsKey(workspaceName)) return true;
179 for (String actualName : workspace().session().getWorkspace().getAccessibleWorkspaceNames()) {
180 if (actualName == null) continue;
181 if (actualName.equals(workspaceName)) return true;
182 }
183 return false;
184 }
185
186
187
188
189
190
191 public void commit() throws RepositoryException {
192 for (Workspace workspace : workspaces.values()) {
193
194 workspace.session().save();
195
196
197 }
198 }
199
200
201
202
203
204
205 public void rollback() throws RepositoryException {
206
207 }
208
209
210
211
212
213
214 @Override
215 public void close() {
216 try {
217 RuntimeException problem = null;
218 for (Workspace workspace : workspaces.values()) {
219 try {
220 workspace.session().logout();
221 } catch (RuntimeException e) {
222 if (problem == null) problem = e;
223 }
224 }
225 if (problem != null) throw problem;
226 } finally {
227 try {
228 workspaces.clear();
229 } finally {
230 super.close();
231 }
232 }
233 }
234
235
236
237
238
239
240 @Override
241 public void process( VerifyWorkspaceRequest request ) {
242 if (request == null) return;
243 try {
244 Workspace workspace = workspaceFor(request.workspaceName());
245 request.setActualWorkspaceName(workspace.name());
246 request.setActualRootLocation(workspace.locationForRootNode());
247 } catch (Throwable e) {
248 request.setError(e);
249 }
250 }
251
252
253
254
255
256
257 @Override
258 public void process( GetWorkspacesRequest request ) {
259 if (request == null) return;
260 try {
261 Set<String> workspaceNames = new HashSet<String>();
262 for (String workspaceName : workspace().session().getWorkspace().getAccessibleWorkspaceNames()) {
263 workspaceNames.add(workspaceName);
264 }
265 request.setAvailableWorkspaceNames(workspaceNames);
266 setCacheableInfo(request);
267 } catch (Throwable e) {
268 request.setError(e);
269 }
270 }
271
272
273
274
275
276
277 @Override
278 public void process( CreateWorkspaceRequest request ) {
279 if (request == null) return;
280 try {
281
282 String desiredName = request.desiredNameOfNewWorkspace();
283 if (workspaceExistsNamed(desiredName)) {
284 String msg = JcrConnectorI18n.workspaceAlreadyExistsInRepository.text(desiredName, getSourceName());
285 request.setError(new InvalidWorkspaceException(msg));
286 } else {
287
288 String msg = JcrConnectorI18n.unableToCreateWorkspaceInRepository.text(desiredName, getSourceName());
289 request.setError(new InvalidRequestException(msg));
290 }
291 } catch (Throwable e) {
292 request.setError(e);
293 }
294 assert request.hasError();
295 }
296
297
298
299
300
301
302 @Override
303 public void process( CloneWorkspaceRequest request ) {
304 if (request == null) return;
305 try {
306
307 String desiredName = request.desiredNameOfTargetWorkspace();
308 if (workspaceExistsNamed(desiredName)) {
309 switch (request.cloneConflictBehavior()) {
310 case DO_NOT_CLONE:
311 String msg = JcrConnectorI18n.workspaceAlreadyExistsInRepository.text(desiredName, getSourceName());
312 request.setError(new InvalidWorkspaceException(msg));
313 break;
314 case SKIP_CLONE:
315
316 Workspace workspace = workspaceFor(desiredName);
317 workspace.session().getWorkspace().clone(request.nameOfWorkspaceToBeCloned(), "/", "/", true);
318 Location actualLocation = workspace.locationForRootNode();
319 request.setActualWorkspaceName(workspace.name());
320 request.setActualRootLocation(actualLocation);
321 break;
322 }
323 return;
324 }
325
326 String msg = JcrConnectorI18n.unableToCreateWorkspaceInRepository.text(desiredName, getSourceName());
327 request.setError(new InvalidRequestException(msg));
328 } catch (Throwable e) {
329 request.setError(e);
330 }
331 }
332
333
334
335
336
337
338 @Override
339 public void process( DestroyWorkspaceRequest request ) {
340 if (request == null) return;
341 String msg = JcrConnectorI18n.unableToDestroyWorkspaceInRepository.text(request.workspaceName(), getSourceName());
342 request.setError(new UnsupportedRequestException(msg));
343 }
344
345
346
347
348
349
350 @Override
351 public void process( ReadNodeRequest request ) {
352 if (request == null) return;
353 try {
354 Workspace workspace = workspaceFor(request.inWorkspace());
355 Node node = workspace.node(request.at());
356 Location actualLocation = workspace.locationFor(node);
357 request.setActualLocationOfNode(actualLocation);
358
359 for (NodeIterator iter = node.getNodes(); iter.hasNext();) {
360 request.addChild(workspace.locationFor(iter.nextNode()));
361 }
362
363 for (PropertyIterator iter = node.getProperties(); iter.hasNext();) {
364 request.addProperty(workspace.propertyFor(iter.nextProperty()));
365 }
366
367 if (actualLocation.hasIdProperties()) {
368 request.addProperty(workspace.propertyFor(ModeShapeLexicon.UUID, actualLocation.getUuid()));
369 }
370 setCacheableInfo(request);
371 } catch (Throwable e) {
372 request.setError(e);
373 }
374 }
375
376
377
378
379
380
381 @Override
382 public void process( ReadAllChildrenRequest request ) {
383 if (request == null) return;
384 try {
385 Workspace workspace = workspaceFor(request.inWorkspace());
386 Node parent = workspace.node(request.of());
387 request.setActualLocationOfNode(workspace.locationFor(parent));
388 for (NodeIterator iter = parent.getNodes(); iter.hasNext();) {
389 request.addChild(workspace.locationFor(iter.nextNode()));
390 }
391 setCacheableInfo(request);
392 } catch (Throwable e) {
393 request.setError(e);
394 }
395 }
396
397
398
399
400
401
402 @Override
403 public void process( ReadAllPropertiesRequest request ) {
404 if (request == null) return;
405 try {
406 Workspace workspace = workspaceFor(request.inWorkspace());
407 Node node = workspace.node(request.at());
408 Location actualLocation = workspace.locationFor(node);
409 request.setActualLocationOfNode(actualLocation);
410
411 for (PropertyIterator iter = node.getProperties(); iter.hasNext();) {
412 request.addProperty(workspace.propertyFor(iter.nextProperty()));
413 }
414
415 if (actualLocation.hasIdProperties()) {
416 request.addProperty(workspace.propertyFor(ModeShapeLexicon.UUID, actualLocation.getUuid()));
417 }
418
419 NodeIterator childIter = node.getNodes();
420 int numChildren = (int)childIter.getSize();
421 if (numChildren == -1) {
422 numChildren = 0;
423 while (childIter.hasNext()) {
424 childIter.nextNode();
425 ++numChildren;
426 }
427 }
428 request.setNumberOfChildren(numChildren);
429 setCacheableInfo(request);
430 } catch (Throwable e) {
431 request.setError(e);
432 }
433 }
434
435
436
437
438
439
440 @Override
441 public void process( CreateNodeRequest request ) {
442 if (request == null) return;
443 try {
444 Workspace workspace = workspaceFor(request.inWorkspace());
445 Node parent = workspace.node(request.under());
446 String childName = workspace.stringFor(request.named());
447
448
449 String primaryTypeName = null;
450 for (Property property : request.properties()) {
451 if (property.getName().equals(JcrLexicon.PRIMARY_TYPE)) {
452 primaryTypeName = workspace.stringFor(property.getFirstValue());
453 break;
454 }
455 }
456
457
458 Node child = null;
459 if (primaryTypeName != null) {
460 child = parent.addNode(childName, primaryTypeName);
461 } else {
462 child = parent.addNode(childName);
463 }
464 assert child != null;
465
466
467 workspace.setProperties(child, request);
468
469
470 request.setActualLocationOfNode(workspace.locationFor(child));
471 } catch (Throwable e) {
472 request.setError(e);
473 }
474 }
475
476
477
478
479
480
481 @Override
482 public void process( CloneBranchRequest request ) {
483 if (request == null) return;
484 try {
485 String fromWorkspaceName = request.fromWorkspace();
486 String intoWorkspaceName = request.intoWorkspace();
487 boolean sameWorkspace = fromWorkspaceName.equals(intoWorkspaceName);
488 Workspace fromWorkspace = workspaceFor(fromWorkspaceName);
489 Workspace intoWorkspace = sameWorkspace ? fromWorkspace : workspaceFor(intoWorkspaceName);
490 Node sourceNode = fromWorkspace.node(request.from());
491 Node targetNode = fromWorkspace.node(request.into());
492 Location fromLocation = fromWorkspace.locationFor(sourceNode);
493
494
495 String srcAbsPath = sourceNode.getPath();
496 String destAbsPath = targetNode.getPath();
497 String copyName = request.desiredName() != null ? intoWorkspace.stringFor(request.desiredName()) : sourceNode.getName();
498 destAbsPath += '/' + copyName;
499
500
501 javax.jcr.Workspace workspace = intoWorkspace.session().getWorkspace();
502 workspace.clone(fromWorkspaceName, srcAbsPath, destAbsPath, request.removeExisting());
503
504
505 Node last = null;
506 for (NodeIterator iter = targetNode.getNodes(copyName); iter.hasNext();) {
507 last = iter.nextNode();
508 }
509 Location intoLocation = intoWorkspace.locationFor(last);
510 request.setActualLocations(fromLocation, intoLocation);
511 } catch (Throwable e) {
512 request.setError(e);
513 }
514 }
515
516
517
518
519
520
521 @Override
522 public void process( CopyBranchRequest request ) {
523 if (request == null) return;
524 try {
525 String fromWorkspaceName = request.fromWorkspace();
526 String intoWorkspaceName = request.intoWorkspace();
527 boolean sameWorkspace = fromWorkspaceName.equals(intoWorkspaceName);
528 Workspace fromWorkspace = workspaceFor(fromWorkspaceName);
529 Workspace intoWorkspace = sameWorkspace ? fromWorkspace : workspaceFor(intoWorkspaceName);
530 Node sourceNode = fromWorkspace.node(request.from());
531 Node targetNode = fromWorkspace.node(request.into());
532 Location fromLocation = fromWorkspace.locationFor(sourceNode);
533
534
535 String srcAbsPath = sourceNode.getPath();
536 String destAbsPath = targetNode.getPath();
537 String copyName = request.desiredName() != null ? intoWorkspace.stringFor(request.desiredName()) : sourceNode.getName();
538 destAbsPath += '/' + copyName;
539
540
541 javax.jcr.Workspace workspace = intoWorkspace.session().getWorkspace();
542 if (sameWorkspace) {
543 workspace.copy(srcAbsPath, destAbsPath);
544 } else {
545 workspace.copy(fromWorkspaceName, srcAbsPath, destAbsPath);
546 }
547
548
549 Node last = null;
550 for (NodeIterator iter = targetNode.getNodes(copyName); iter.hasNext();) {
551 last = iter.nextNode();
552 }
553 Location intoLocation = intoWorkspace.locationFor(last);
554 request.setActualLocations(fromLocation, intoLocation);
555 } catch (Throwable e) {
556 request.setError(e);
557 }
558 }
559
560
561
562
563
564
565 @Override
566 public void process( DeleteBranchRequest request ) {
567 if (request == null) return;
568 try {
569 Workspace workspace = workspaceFor(request.inWorkspace());
570 Node node = workspace.node(request.at());
571 Location actual = workspace.locationFor(node);
572 node.remove();
573 request.setActualLocationOfNode(actual);
574 } catch (Throwable e) {
575 request.setError(e);
576 }
577 }
578
579
580
581
582
583
584 @Override
585 public void process( MoveBranchRequest request ) {
586 if (request == null) return;
587 try {
588 Workspace workspace = workspaceFor(request.inWorkspace());
589 Node orig = workspace.node(request.from());
590 Node into = request.into() != null ? workspace.node(request.into()) : null;
591 Node before = request.before() != null ? workspace.node(request.before()) : null;
592 Location originalLocation = workspace.locationFor(orig);
593 Location newLocation = workspace.move(orig, into, request.desiredName(), before);
594 request.setActualLocations(originalLocation, newLocation);
595 } catch (Throwable e) {
596 request.setError(e);
597 }
598 }
599
600
601
602
603
604
605 @Override
606 public void process( UpdatePropertiesRequest request ) {
607 if (request == null) return;
608 try {
609 Workspace workspace = workspaceFor(request.inWorkspace());
610 Node node = workspace.node(request.on());
611 Set<Name> newProperties = new HashSet<Name>();
612 for (Map.Entry<Name, Property> entry : request.properties().entrySet()) {
613 Name propertyName = entry.getKey();
614 String name = workspace.stringFor(propertyName);
615 Property property = entry.getValue();
616
617
618
619 javax.jcr.Property existing = node.hasProperty(name) ? node.getProperty(name) : null;
620 if (existing != null && (property == null || existing.getDefinition().isMultiple() == property.isSingle())) {
621
622 if (!existing.getDefinition().isProtected()) {
623 existing.remove();
624 }
625 }
626 if (property != null) {
627 if (property.size() == 1) {
628
629 try {
630 workspace.setProperty(node, property, false);
631 } catch (ValueFormatException e) {
632 workspace.setProperty(node, property, true);
633 }
634 } else {
635
636 workspace.setProperty(node, property, true);
637 }
638 if (existing == null) newProperties.add(propertyName);
639 }
640 }
641
642 if (request.removeOtherProperties()) {
643 Set<String> stringNames = new HashSet<String>();
644 for (Name name : request.properties().keySet()) {
645 stringNames.add(workspace.stringFor(name));
646 }
647 stringNames.add(workspace.stringFor(JcrLexicon.PRIMARY_TYPE));
648 stringNames.add(workspace.stringFor(JcrLexicon.MIXIN_TYPES));
649 PropertyIterator propertyIter = node.getProperties();
650 while (propertyIter.hasNext()) {
651 javax.jcr.Property property = propertyIter.nextProperty();
652 if (!stringNames.contains(property.getName()) && !property.getDefinition().isProtected()) {
653 property.remove();
654 }
655 }
656 }
657
658
659 request.setActualLocationOfNode(workspace.locationFor(node));
660 request.setNewProperties(newProperties);
661 } catch (Throwable e) {
662 request.setError(e);
663 }
664 }
665
666
667
668
669
670 protected class Workspace {
671 private final Session session;
672
673 private final ExecutionContext context;
674
675 private final ValueFactories factories;
676
677 private final PropertyFactory propertyFactory;
678 private final NameFactory nameFactory;
679 private final ValueFactory<String> stringFactory;
680 private final String name;
681 private final javax.jcr.ValueFactory jcrValueFactory;
682
683 protected Workspace( Session jcrSession ) throws RepositoryException {
684 this.session = jcrSession;
685 this.name = this.session.getWorkspace().getName();
686 ExecutionContext connectorContext = getExecutionContext();
687 NamespaceRegistry connectorRegistry = connectorContext.getNamespaceRegistry();
688 this.context = connectorContext.with(new JcrNamespaceRegistry(getSourceName(), this.session, connectorRegistry));
689 this.factories = context.getValueFactories();
690 this.propertyFactory = context.getPropertyFactory();
691 this.nameFactory = this.factories.getNameFactory();
692 this.stringFactory = this.factories.getStringFactory();
693 this.jcrValueFactory = this.session.getValueFactory();
694 }
695
696 public Location move( Node original,
697 Node newParent,
698 Name newName,
699 Node beforeSibling ) throws RepositoryException {
700
701 if (newParent == null && beforeSibling != null) {
702 newParent = beforeSibling.getParent();
703 }
704
705 if (newName != null || (newParent != null && !original.getParent().equals(newParent))) {
706
707 String destAbsPath = newParent != null ? newParent.getPath() : original.getParent().getPath();
708 assert !destAbsPath.endsWith("/");
709 String newNameStr = newName != null ? stringFor(newName) : original.getName();
710 destAbsPath += '/' + newNameStr;
711 session.move(original.getPath(), destAbsPath);
712 }
713
714 if (beforeSibling != null) {
715
716 String siblingName = nameFor(beforeSibling);
717 String originalName = nameFor(original);
718 original.getParent().orderBefore(originalName, siblingName);
719 }
720 return locationFor(original);
721 }
722
723 public String name() {
724 return name;
725 }
726
727 public Session session() {
728 return session;
729 }
730
731 protected String stringFor( Object value ) {
732 return stringFactory.create(value);
733 }
734
735 protected String nameFor( Node node ) throws RepositoryException {
736 String name = node.getName();
737 int snsIndex = node.getIndex();
738 return snsIndex == 1 ? name : name + '[' + snsIndex + ']';
739 }
740
741 public Property propertyFor( Name name,
742 Object... values ) {
743 return propertyFactory.create(name, values);
744 }
745
746
747
748
749
750
751
752
753 public Property propertyFor( javax.jcr.Property jcrProperty ) throws RepositoryException {
754
755 Object[] values = null;
756 if (jcrProperty.getDefinition().isMultiple()) {
757 Value[] jcrValues = jcrProperty.getValues();
758 values = new Object[jcrValues.length];
759 for (int i = 0; i < jcrValues.length; i++) {
760 values[i] = convert(jcrValues[i], jcrProperty);
761 }
762 } else {
763 values = new Object[] {convert(jcrProperty.getValue(), jcrProperty)};
764 }
765
766 Name name = nameFactory.create(jcrProperty.getName());
767 return propertyFactory.create(name, values);
768 }
769
770
771
772
773
774
775
776
777
778 public Object convert( Value value,
779 javax.jcr.Property jcrProperty ) throws RepositoryException {
780 if (value == null) return null;
781 try {
782 switch (value.getType()) {
783 case javax.jcr.PropertyType.BINARY:
784 return factories.getBinaryFactory().create(value.getStream(), 0);
785 case javax.jcr.PropertyType.BOOLEAN:
786 return factories.getBooleanFactory().create(value.getBoolean());
787 case javax.jcr.PropertyType.DATE:
788 return factories.getDateFactory().create(value.getDate());
789 case javax.jcr.PropertyType.DOUBLE:
790 return factories.getDoubleFactory().create(value.getDouble());
791 case javax.jcr.PropertyType.LONG:
792 return factories.getLongFactory().create(value.getLong());
793 case javax.jcr.PropertyType.NAME:
794 return factories.getNameFactory().create(value.getString());
795 case javax.jcr.PropertyType.PATH:
796 return factories.getPathFactory().create(value.getString());
797 case javax.jcr.PropertyType.REFERENCE:
798 return factories.getReferenceFactory().create(value.getString());
799 case javax.jcr.PropertyType.STRING:
800 return factories.getStringFactory().create(value.getString());
801 case javax.jcr.PropertyType.UNDEFINED:
802
803
804 try {
805
806 return factories.getNameFactory().create(value.getString());
807 } catch (ValueFormatException e) {
808
809 try {
810 return factories.getPathFactory().create(value.getString());
811 } catch (ValueFormatException e2) {
812
813 return factories.getStringFactory().create(value.getString());
814 }
815 }
816 }
817 } catch (ValueFormatException e) {
818
819 String typeName = javax.jcr.PropertyType.nameFromValue(value.getType());
820 throw new RepositoryException(JcrConnectorI18n.errorConvertingJcrValueOfType.text(value.getString(), typeName));
821 }
822 return null;
823 }
824
825
826
827
828
829
830
831
832 public Location locationFor( Node node ) throws RepositoryException {
833
834 String pathStr = node.getPath();
835 Path path = factories.getPathFactory().create(pathStr);
836
837
838 if (node.isNodeType("mix:referenceable")) {
839 String uuidStr = node.getUUID();
840 if (uuidStr != null) {
841 UUID uuid = UUID.fromString(uuidStr);
842 return Location.create(path, uuid);
843 }
844 }
845 return Location.create(path);
846 }
847
848 public Location locationForRootNode() throws RepositoryException {
849 return locationFor(session.getRootNode());
850 }
851
852
853
854
855
856
857
858
859
860
861 public Node node( Location location ) throws RepositoryException {
862 Node root = session.getRootNode();
863 UUID uuid = location.getUuid();
864 if (uuid != null) {
865 try {
866 return session.getNodeByUUID(uuid.toString());
867 } catch (ItemNotFoundException e) {
868 if (!location.hasPath()) {
869 String msg = JcrConnectorI18n.unableToFindNodeWithUuid.text(getSourceName(), uuid);
870 throw new PathNotFoundException(location, factories.getPathFactory().createRootPath(), msg);
871 }
872
873 }
874 }
875 if (location.hasPath()) {
876 Path relativePath = location.getPath().relativeToRoot();
877 ValueFactory<String> stringFactory = factories.getStringFactory();
878 String relativePathStr = stringFactory.create(relativePath);
879 try {
880 return root.getNode(relativePathStr);
881 } catch (javax.jcr.PathNotFoundException e) {
882
883 Node node = root;
884 for (Path.Segment segment : relativePath) {
885 try {
886 node = node.getNode(stringFactory.create(segment));
887 } catch (javax.jcr.PathNotFoundException e2) {
888 String pathStr = stringFactory.create(location.getPath());
889 Path lowestPath = factories.getPathFactory().create(node.getPath());
890 throw new PathNotFoundException(location, lowestPath,
891 JcrConnectorI18n.nodeDoesNotExist.text(getSourceName(),
892 session.getWorkspace()
893 .getName(),
894 pathStr));
895 }
896 }
897 }
898 }
899
900 String msg = JcrConnectorI18n.unableToFindNodeWithoutPathOrUuid.text(getSourceName(), location);
901 throw new IllegalArgumentException(msg);
902 }
903
904 public void setProperties( Node node,
905 Iterable<Property> properties ) throws RepositoryException {
906
907 Set<Name> multiValued = null;
908 for (Property property : properties) {
909 if (property.getName().equals(ModeShapeIntLexicon.MULTI_VALUED_PROPERTIES)) {
910
911 multiValued = getMultiValuedProperties(property);
912 break;
913 }
914 }
915 if (multiValued == null) multiValued = Collections.emptySet();
916
917
918 for (Property property : properties) {
919 setProperty(node, property, multiValued.contains(property.getName()));
920 }
921 }
922
923 protected Set<Name> getMultiValuedProperties( Property multiValuedProperty ) {
924
925 Set<Name> multiValued = new HashSet<Name>();
926 for (Object value : multiValuedProperty) {
927 Name multiValuedPropertyName = nameFactory.create(value);
928 if (multiValuedPropertyName != null) {
929 multiValued.add(multiValuedPropertyName);
930 }
931 }
932 return multiValued;
933 }
934
935 protected void setProperty( Node node,
936 Property property,
937 boolean isMultiValued ) throws RepositoryException {
938 Name name = property.getName();
939 if (name.equals(JcrLexicon.PRIMARY_TYPE)) return;
940 if (name.equals(ModeShapeIntLexicon.NODE_DEFINITON)) return;
941 if (name.equals(ModeShapeIntLexicon.MULTI_VALUED_PROPERTIES)) return;
942 if (name.equals(JcrLexicon.MIXIN_TYPES)) {
943 for (Object mixinVvalue : property.getValuesAsArray()) {
944 String mixinTypeName = stringFor(mixinVvalue);
945 node.addMixin(mixinTypeName);
946 }
947 return;
948 }
949
950
951 String propertyName = stringFor(name);
952 if (isMultiValued) {
953 Value[] values = new Value[property.size()];
954 int index = 0;
955 PropertyType propertyType = null;
956 for (Object value : property) {
957 if (value == null) continue;
958 if (propertyType == null) propertyType = PropertyType.discoverType(value);
959 values[index] = convertToJcrValue(propertyType, value);
960 ++index;
961 }
962 node.setProperty(propertyName, values);
963 } else {
964 Object firstValue = property.getFirstValue();
965 PropertyType propertyType = PropertyType.discoverType(firstValue);
966 Value value = convertToJcrValue(propertyType, firstValue);
967 node.setProperty(propertyName, value);
968 }
969 }
970
971 protected Value convertToJcrValue( PropertyType graphType,
972 Object graphValue ) {
973 if (graphValue == null) return null;
974 switch (graphType) {
975 case DECIMAL:
976 case NAME:
977 case PATH:
978 case REFERENCE:
979 case UUID:
980 case URI:
981 case STRING:
982 case OBJECT:
983 String stringValue = factories.getStringFactory().create(graphValue);
984 return jcrValueFactory.createValue(stringValue);
985 case BOOLEAN:
986 Boolean booleanValue = factories.getBooleanFactory().create(graphValue);
987 return jcrValueFactory.createValue(booleanValue.booleanValue());
988 case DOUBLE:
989 Double doubleValue = factories.getDoubleFactory().create(graphValue);
990 return jcrValueFactory.createValue(doubleValue);
991 case LONG:
992 Long longValue = factories.getLongFactory().create(graphValue);
993 return jcrValueFactory.createValue(longValue);
994 case DATE:
995 Calendar calValue = factories.getDateFactory().create(graphValue).toCalendar();
996 return jcrValueFactory.createValue(calValue);
997 case BINARY:
998 Binary binary = factories.getBinaryFactory().create(graphValue);
999 try {
1000 binary.acquire();
1001 return jcrValueFactory.createValue(binary.getStream());
1002 } finally {
1003 binary.release();
1004 }
1005 }
1006 assert false;
1007 return null;
1008 }
1009 }
1010 }