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.graph.connector.federation;
25
26 import java.util.List;
27 import java.util.Set;
28 import net.jcip.annotations.Immutable;
29 import org.modeshape.graph.ExecutionContext;
30 import org.modeshape.graph.Location;
31 import org.modeshape.graph.property.Path;
32 import org.modeshape.graph.property.PathFactory;
33
34
35
36
37
38
39 @Immutable
40 final class GeneralProjector extends ProjectorWithPlaceholders {
41
42
43
44
45
46
47
48
49 static GeneralProjector with( ExecutionContext context,
50 List<Projection> projections ) {
51 assert projections != null;
52 assert context != null;
53 return new GeneralProjector(context, projections);
54 }
55
56 private final List<Projection> projections;
57
58 private GeneralProjector( ExecutionContext context,
59 List<Projection> projections ) {
60 super(context, projections);
61 this.projections = projections;
62 }
63
64
65
66
67
68
69 public ProjectedNode project( ExecutionContext context,
70 Location location,
71 boolean requiresUpdate ) {
72 PlaceholderNode placeholder = isPlaceholder(location);
73 if (placeholder != null) return placeholder;
74
75
76 Path path = location.getPath();
77 if (path == null) {
78
79 ProjectedNode result = null;
80 for (Projection projection : projections) {
81 if (requiresUpdate && projection.isReadOnly()) continue;
82 ProxyNode proxy = new ProxyNode(projection, location, location, false);
83 if (result == null) {
84 result = proxy;
85 } else {
86 result.add(proxy);
87 }
88 }
89 return result;
90 }
91
92 ProjectedNode result = isPlaceholder(location);
93 if (result != null) return result;
94
95
96 final PathFactory pathFactory = context.getValueFactories().getPathFactory();
97 for (Projection projection : projections) {
98 if (requiresUpdate && projection.isReadOnly()) continue;
99
100 Set<Path> pathsInSource = projection.getPathsInSource(path, pathFactory);
101 for (Path pathInSource : pathsInSource) {
102
103 Location locationInSource = Location.create(pathInSource);
104 boolean samePath = pathInSource.equals(path);
105 ProxyNode proxy = new ProxyNode(projection, locationInSource, location, samePath);
106 if (result == null) {
107 result = proxy;
108 } else {
109 result.add(proxy);
110 }
111 }
112 }
113
114
115 if (result != null && !result.hasNext() && result.isProxy()) {
116
117 ProxyNode proxy = result.asProxy();
118 result = new ProxyNode(proxy.projection(), location.with(result.location().getPath()), location,
119 proxy.isSameLocationAsOriginal());
120 }
121 return result;
122 }
123
124 }