1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.cms.core.version;
35
36 import info.magnolia.context.SystemContext;
37 import info.magnolia.jcr.decoration.AbstractContentDecorator;
38 import info.magnolia.jcr.decoration.ContentDecoratorNodeWrapper;
39 import info.magnolia.jcr.decoration.ContentDecoratorSessionWrapper;
40 import info.magnolia.jcr.decoration.ContentDecoratorWorkspaceWrapper;
41 import info.magnolia.jcr.iterator.FilteringRangeIterator;
42 import info.magnolia.jcr.util.NodeTypes;
43 import info.magnolia.jcr.util.NodeUtil;
44 import info.magnolia.objectfactory.Components;
45
46 import java.util.ArrayList;
47 import java.util.Iterator;
48 import java.util.List;
49
50 import javax.jcr.AccessDeniedException;
51 import javax.jcr.ItemNotFoundException;
52 import javax.jcr.Node;
53 import javax.jcr.Property;
54 import javax.jcr.RepositoryException;
55 import javax.jcr.Session;
56 import javax.jcr.Workspace;
57 import javax.jcr.lock.LockException;
58 import javax.jcr.nodetype.ConstraintViolationException;
59 import javax.jcr.version.Version;
60 import javax.jcr.version.VersionException;
61 import javax.jcr.version.VersionIterator;
62
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
65
66
67
68
69 public class MgnlVersionSessionDecorator extends AbstractContentDecorator {
70
71 private static final Logger log = LoggerFactory.getLogger(MgnlVersionSessionDecorator.class);
72
73 private String sourceWorkspace;
74
75 public MgnlVersionSessionDecorator(String sourceWorkspace) {
76 this.sourceWorkspace = sourceWorkspace;
77 }
78
79 @Override
80 public Session wrapSession(Session session) {
81 return new MgnlVersionSessionWrapper(session, this);
82 }
83
84 @Override
85 public Workspace wrapWorkspace(Workspace workspace) {
86 return new MgnlVersionSessionWorkspaceWrapper(workspace, this);
87 }
88
89 @Override
90 public Node wrapNode(Node node) {
91 return new MgnlVersionSessionNodeWrapper(node, this);
92 }
93
94 @Override
95 public VersionIterator wrapVersionIterator(VersionIterator versionIterator) {
96 return new MgnlVersionSessionVersionIteratorWrapper(sourceWorkspace, versionIterator);
97 }
98
99 @Override
100 public boolean isMultipleWrapEnabled() {
101 return false;
102 }
103
104 private void removeHasVersionMixin(Node versionedNode) throws RepositoryException {
105 Node node = versionedNode;
106 while (node.getDepth() != 1) {
107 node = node.getParent();
108 }
109 String uuid = versionedNode.getIdentifier();
110 try {
111 Node original = Components.getComponent(SystemContext.class).getJCRSession(sourceWorkspace).getNodeByIdentifier(uuid);
112 if (NodeUtil.hasMixin(original, NodeTypes.HasVersion.NAME)) {
113 original.removeMixin(NodeTypes.HasVersion.NAME);
114 original.getSession().save();
115 }
116 } catch (ItemNotFoundException e) {
117
118 log.warn("Original node for version {} not found.", e.getMessage());
119 }
120 }
121
122
123
124
125 public class MgnlVersionSessionVersionIteratorWrapper extends FilteringRangeIterator<Version> implements VersionIterator {
126
127 private final String sourceWorkspace;
128 private final VersionIterator versionIterator;
129 private final List<Version> allVersions = new ArrayList<>();
130
131 public MgnlVersionSessionVersionIteratorWrapper(String sourceWorkspace, VersionIterator versionIterator) {
132 super(versionIterator);
133 this.sourceWorkspace = sourceWorkspace;
134 this.versionIterator = versionIterator;
135 }
136
137 @Override
138 protected boolean evaluate(Version version) {
139 allVersions.add(version);
140 try {
141 if (version.getFrozenNode().hasNode(BaseVersionManager.SYSTEM_NODE) && version.getFrozenNode().getNode(BaseVersionManager.SYSTEM_NODE).hasProperty(BaseVersionManager.SOURCE_WORKSPACE)) {
142 String workspace = version.getFrozenNode().getNode(BaseVersionManager.SYSTEM_NODE).getProperty(BaseVersionManager.SOURCE_WORKSPACE).getString();
143 return sourceWorkspace.equals(workspace);
144 }
145 } catch (RepositoryException e) {
146 log.warn("Unable to determine source workspace for version {}", version, e);
147 return false;
148 }
149 return true;
150 }
151
152 @Override
153 public Version nextVersion() {
154 return wrapVersion(next());
155 }
156
157
158
159
160 public long getUnfilteredSize() {
161 return versionIterator.getSize();
162 }
163
164
165
166
167 public Iterator<Version> getAllVersionsUnfiltered() {
168 return allVersions.iterator();
169 }
170 }
171
172
173
174
175 public class MgnlVersionSessionWrapper extends ContentDecoratorSessionWrapper<MgnlVersionSessionDecorator> {
176
177 public MgnlVersionSessionWrapper(Session session, MgnlVersionSessionDecorator contentDecorator) {
178 super(session, contentDecorator);
179 }
180
181 @Override
182 public void removeItem(String absPath) throws LockException, ConstraintViolationException, AccessDeniedException, VersionException, RepositoryException {
183 if (getItem(absPath) instanceof Property) {
184 super.removeItem(absPath);
185 } else {
186 removeHasVersionMixin(getNode(absPath));
187 super.removeItem(absPath);
188 }
189 }
190 }
191
192
193
194
195 public class MgnlVersionSessionNodeWrapper extends ContentDecoratorNodeWrapper<MgnlVersionSessionDecorator> {
196
197 public MgnlVersionSessionNodeWrapper(Node node, MgnlVersionSessionDecorator contentDecorator) {
198 super(node, contentDecorator);
199 }
200
201 @Override
202 public void remove() throws LockException, ConstraintViolationException, AccessDeniedException, VersionException, RepositoryException {
203 removeHasVersionMixin(this);
204 super.remove();
205 }
206 }
207
208
209
210
211 public class MgnlVersionSessionWorkspaceWrapper extends ContentDecoratorWorkspaceWrapper {
212
213 public MgnlVersionSessionWorkspaceWrapper(Workspace workspace, MgnlVersionSessionDecorator contentDecorator) {
214 super(workspace, contentDecorator);
215 }
216 }
217 }