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