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 net.jcip.annotations.Immutable;
28 import org.modeshape.graph.ExecutionContext;
29 import org.modeshape.graph.Location;
30 import org.modeshape.graph.property.Path;
31 import org.modeshape.graph.property.PathFactory;
32
33
34
35
36
37
38
39 @Immutable
40 final class OffsetMirrorProjector extends ProjectorWithPlaceholders {
41
42
43
44
45
46
47
48
49
50 static OffsetMirrorProjector with( ExecutionContext context,
51 List<Projection> projections ) {
52 assert projections != null;
53 assert context != null;
54
55 if (projections.size() != 1) return null;
56 Projection projection = projections.get(0);
57 assert projection != null;
58
59 if (projection.getRules().size() != 1) return null;
60 PathFactory pathFactory = context.getValueFactories().getPathFactory();
61
62
63 List<Path> topLevelPaths = projection.getRules().get(0).getTopLevelPathsInRepository(pathFactory);
64 if (topLevelPaths.size() != 1) return null;
65 Path topLevelPath = topLevelPaths.get(0);
66 assert topLevelPath != null;
67
68 if (topLevelPath.isRoot()) return null;
69
70
71 Path sourcePath = projection.getRules().get(0).getPathInSource(topLevelPath, pathFactory);
72
73 return new OffsetMirrorProjector(context, projections, topLevelPath, sourcePath);
74 }
75
76 private final Projection projection;
77 private final Path offset;
78 private final int offsetSize;
79 private final Path sourcePath;
80
81 private OffsetMirrorProjector( ExecutionContext context,
82 List<Projection> projections,
83 Path offset,
84 Path sourcePath ) {
85 super(context, projections);
86 this.projection = projections.get(0);
87 this.offset = offset;
88 this.offsetSize = offset.size();
89 this.sourcePath = sourcePath;
90 }
91
92
93
94
95
96
97 public ProjectedNode project( ExecutionContext context,
98 Location location,
99 boolean requiresUpdate ) {
100 if (requiresUpdate && projection.isReadOnly()) return null;
101 PlaceholderNode placeholder = isPlaceholder(location);
102 if (placeholder != null) return placeholder;
103
104 Path path = location.getPath();
105 Location locationInSource = location;
106 if (path != null) {
107 if (path.size() == offsetSize) {
108
109 if (path.equals(offset)) {
110 locationInSource = location.with(sourcePath);
111 } else {
112 return null;
113 }
114 } else {
115
116 if (path.isDecendantOf(offset)) {
117 Path pathBelowOffset = path.relativeTo(offset);
118 PathFactory pathFactory = context.getValueFactories().getPathFactory();
119 Path pathInSource = pathFactory.create(sourcePath, pathBelowOffset);
120 locationInSource = location.with(pathInSource);
121 } else {
122
123 return null;
124 }
125 }
126 }
127 return new ProxyNode(projection, locationInSource, location);
128 }
129
130 }