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.jcr.wrapper;
35
36 import info.magnolia.cms.security.JCRSessionOp;
37 import info.magnolia.context.Context;
38 import info.magnolia.context.MgnlContext;
39 import info.magnolia.context.SystemContext;
40 import info.magnolia.jcr.decoration.ContentDecorator;
41 import info.magnolia.jcr.decoration.ContentDecoratorPropertyWrapper;
42 import info.magnolia.jcr.decoration.ContentDecoratorSessionWrapper;
43 import info.magnolia.jcr.decoration.ContentDecoratorWorkspaceWrapper;
44 import info.magnolia.jcr.util.NodeTypes;
45 import info.magnolia.jcr.util.NodeTypes.LastModified;
46 import info.magnolia.jcr.util.NodeUtil;
47 import info.magnolia.repository.RepositoryConstants;
48
49 import java.io.InputStream;
50 import java.math.BigDecimal;
51 import java.util.ArrayList;
52 import java.util.Calendar;
53 import java.util.LinkedList;
54 import java.util.List;
55 import java.util.Map;
56 import java.util.Stack;
57
58 import javax.jcr.AccessDeniedException;
59 import javax.jcr.Binary;
60 import javax.jcr.InvalidItemStateException;
61 import javax.jcr.ItemExistsException;
62 import javax.jcr.NoSuchWorkspaceException;
63 import javax.jcr.Node;
64 import javax.jcr.NodeIterator;
65 import javax.jcr.PathNotFoundException;
66 import javax.jcr.Property;
67 import javax.jcr.ReferentialIntegrityException;
68 import javax.jcr.RepositoryException;
69 import javax.jcr.Session;
70 import javax.jcr.Value;
71 import javax.jcr.ValueFormatException;
72 import javax.jcr.Workspace;
73 import javax.jcr.lock.LockException;
74 import javax.jcr.nodetype.ConstraintViolationException;
75 import javax.jcr.nodetype.NoSuchNodeTypeException;
76 import javax.jcr.version.VersionException;
77
78 import org.apache.commons.lang3.StringUtils;
79 import org.slf4j.Logger;
80 import org.slf4j.LoggerFactory;
81
82 import com.google.common.collect.ImmutableList;
83 import com.google.common.collect.ImmutableMap;
84
85
86
87
88
89
90 public class MgnlPropertySettingContentDecorator extends PropertyAndChildWrappingContentDecorator implements ContentDecorator {
91
92
93
94
95
96 private class DirtyOp {
97
98 private String path;
99 private String userName;
100 private Calendar updateDate;
101
102 public DirtyOp(String path, String userName, Calendar updateDate) {
103 this.path = path;
104 this.userName = userName;
105 this.updateDate = updateDate;
106 }
107
108 public String getPath() {
109 return path;
110 }
111
112 public void setPath(String path) {
113 this.path = path;
114 }
115
116 public String getUserName() {
117 return userName;
118 }
119
120 public Calendar getUpdateDate() {
121 return updateDate;
122 }
123
124 }
125
126 private static final Logger log = LoggerFactory.getLogger(MgnlPropertySettingContentDecorator.class);
127
128
129
130
131 private static final ImmutableList<String> SPECIAL_PROPERTY_NAMES = ImmutableList.of(
132 NodeTypes.MGNL_PREFIX + "variantTitle",
133 NodeTypes.MGNL_PREFIX + "variationOf",
134 NodeTypes.MGNL_PREFIX + "assignedSegments",
135 NodeTypes.Renderable.TEMPLATE
136 );
137
138
139
140
141
142 private static Map<String, String> PARENT_NODE_MAPPINGS = ImmutableMap.of(
143 RepositoryConstants.WEBSITE, NodeTypes.Page.NAME,
144 RepositoryConstants.USERS, NodeTypes.User.NAME,
145
146
147
148
149 "dam", "mgnl:asset");
150
151 protected List<DirtyOp> dirtyOps = new LinkedList<>();
152
153
154
155
156
157 final class ChangeLastUpdateDateOp extends MgnlContext.RepositoryOp {
158 private final String workspaceName;
159 private final String userName;
160 private final String destAbsPath;
161 private final Calendar updateDate;
162 private final boolean recursiveDown;
163
164 ChangeLastUpdateDateOp(String workspaceName, String userName, String destAbsPath, Calendar updateDate, boolean recursiveDown) {
165 this.workspaceName = workspaceName;
166 this.userName = userName;
167 this.destAbsPath = destAbsPath;
168 this.updateDate = updateDate;
169 this.recursiveDown = recursiveDown;
170 }
171
172 @Override
173 public void doExec() throws RepositoryException {
174 Session sysSession = MgnlContext.getJCRSession(workspaceName);
175
176
177 if (!sysSession.itemExists(destAbsPath)) {
178
179 if (log.isDebugEnabled()) {
180 log.warn("Can't update mgnl:lastModified. Path {}:{} doesn't exist anymore.", workspaceName, destAbsPath);
181 }
182 return;
183 }
184 String srcAbsPath = sysSession.getNode(destAbsPath).getPath();
185
186 Stack<Node> nodes = resolveNodesToModify(destAbsPath, sysSession);
187 Node node;
188 if (!nodes.isEmpty()) {
189 node = nodes.pop();
190 } else {
191
192 node = sysSession.getNode(destAbsPath);
193 }
194
195 if (node.isNodeType(NodeTypes.MetaData.NAME)) {
196
197 return;
198 }
199
200
201 if (node.getDepth() == 0) {
202 return;
203 }
204
205
206 if (node instanceof DelegateNodeWrapper) {
207 node = ((DelegateNodeWrapper) node).deepUnwrap(MgnlPropertySettingNodeWrapper.class);
208 }
209
210 log.debug("LUD on {} from {}:{}", node.getPath(), node.getSession().toString(), Thread.currentThread().getName());
211 if (node.isNodeType(LastModified.NAME)) {
212 String resolvedPath = node.getPath();
213 if (!destAbsPath.equals(srcAbsPath)) {
214
215 if (!resolvedPath.equals(srcAbsPath) && !resolvedPath.equals(destAbsPath)) {
216
217 if (srcAbsPath.startsWith(resolvedPath)) {
218 String hunk = StringUtils.substringAfter(srcAbsPath, resolvedPath);
219 if (destAbsPath.endsWith(hunk)) {
220 resolvedPath = StringUtils.substringBefore(destAbsPath, hunk);
221 }
222 } else {
223 resolvedPath = destAbsPath;
224 }
225 }
226 }
227
228 dirtyOps.add(new DirtyOp(resolvedPath, userName, updateDate));
229 }
230
231
232 while (!nodes.isEmpty()) {
233 Node child = nodes.pop();
234 if (child.isNodeType(LastModified.NAME)) {
235 dirtyOps.add(new DirtyOp(child.getPath(), userName, updateDate));
236 }
237 }
238
239 if (recursiveDown) {
240
241 List<NodeIterator> iters = new ArrayList<>();
242 iters.add(node.getNodes());
243 while (!iters.isEmpty()) {
244 List<NodeIterator> tmp = updateChildren(node.getPath(), destAbsPath, iters, updateDate);
245 iters.clear();
246 iters.addAll(tmp);
247 }
248 }
249
250
251 }
252
253
254
255
256
257
258
259
260
261
262
263
264
265 private Stack<Node> resolveNodesToModify(String destAbsPath, Session sysSession) throws RepositoryException {
266 Stack<Node> nodeStack = new Stack<>();
267
268 String parentNodeType = PARENT_NODE_MAPPINGS.get(workspaceName);
269 Node node = sysSession.getNode(destAbsPath);
270 if (parentNodeType == null) {
271 return nodeStack;
272 }
273 while (node != null && !parentNodeType.equals(node.getPrimaryNodeType().getName()) && node.getDepth() > 0) {
274 nodeStack.add(node);
275 node = node.getParent();
276 }
277 nodeStack.add(node);
278 return nodeStack;
279 }
280
281 private List<NodeIterator> updateChildren(String srcAbsPath, String destAbsPath, List<NodeIterator> iters, Calendar updateDate) {
282 List<NodeIterator> tmp = new ArrayList<>();
283 for (NodeIterator iter : iters) {
284 while (iter.hasNext()) {
285 Node node = iter.nextNode();
286 try {
287 if (skipTypeInWorkspace(workspaceName, node.getPrimaryNodeType().getName())) {
288
289 continue;
290 }
291 if (node.isNodeType(NodeTypes.MetaData.NAME)) {
292
293 continue;
294 }
295 if (node.isNodeType(LastModified.NAME)) {
296 dirtyOps.add(new DirtyOp(destAbsPath + StringUtils.removeStart(node.getPath(), srcAbsPath), userName, updateDate));
297 }
298 tmp.add(node.getNodes());
299 } catch (RepositoryException e) {
300 log.error("Failed to update last modified date of {} with {}", node, e.getMessage(), e);
301 }
302 }
303 }
304 return tmp;
305 }
306
307 private boolean skipTypeInWorkspace(String workspaceName, String name) {
308 if (RepositoryConstants.USER_ROLES.equals(workspaceName)) {
309 return !(NodeTypes.Role.NAME.equals(name) || NodeTypes.Folder.NAME.equals(name));
310 }
311 if (RepositoryConstants.WEBSITE.equals(workspaceName)) {
312 return !NodeTypes.Page.NAME.equals(name);
313 }
314 return false;
315 }
316
317 }
318
319
320
321
322 public class LastUpdatePropertyWrapper extends ContentDecoratorPropertyWrapper<MgnlPropertySettingContentDecorator> implements Property {
323
324 public LastUpdatePropertyWrapper(Property property, MgnlPropertySettingContentDecorator contentDecorator) {
325 super(property, contentDecorator);
326 }
327
328 @Override
329 public void setValue(BigDecimal value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
330 String parentPath = this.getParent().getPath();
331 String propertyName = this.getName();
332 super.setValue(value);
333 updateLastModifiedProperty(propertyName, parentPath);
334 }
335
336 @Override
337 public void setValue(Binary value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
338 String parentPath = this.getParent().getPath();
339 String propertyName = this.getName();
340 super.setValue(value);
341 updateLastModifiedProperty(propertyName, parentPath);
342 }
343
344 @Override
345 public void setValue(boolean value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
346 String parentPath = this.getParent().getPath();
347 String propertyName = this.getName();
348 super.setValue(value);
349 updateLastModifiedProperty(propertyName, parentPath);
350 }
351
352 @Override
353 public void setValue(Calendar value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
354 String parentPath = this.getParent().getPath();
355 String propertyName = this.getName();
356 super.setValue(value);
357 updateLastModifiedProperty(propertyName, parentPath);
358 }
359
360 @Override
361 public void setValue(double value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
362 String parentPath = this.getParent().getPath();
363 String propertyName = this.getName();
364 super.setValue(value);
365 updateLastModifiedProperty(propertyName, parentPath);
366 }
367
368 @Override
369 public void setValue(InputStream value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
370 String parentPath = this.getParent().getPath();
371 String propertyName = this.getName();
372 super.setValue(value);
373 updateLastModifiedProperty(propertyName, parentPath);
374 }
375
376 @Override
377 public void setValue(long value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
378 String parentPath = this.getParent().getPath();
379 String propertyName = this.getName();
380 super.setValue(value);
381 updateLastModifiedProperty(propertyName, parentPath);
382 }
383
384 @Override
385 public void setValue(Node value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
386 String parentPath = this.getParent().getPath();
387 String propertyName = this.getName();
388 super.setValue(value);
389 updateLastModifiedProperty(propertyName, parentPath);
390 }
391
392 @Override
393 public void setValue(String value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
394 String parentPath = this.getParent().getPath();
395 String propertyName = this.getName();
396 super.setValue(value);
397 updateLastModifiedProperty(propertyName, parentPath);
398 }
399
400 @Override
401 public void setValue(String[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
402 String parentPath = this.getParent().getPath();
403 String propertyName = this.getName();
404 super.setValue(values);
405 updateLastModifiedProperty(propertyName, parentPath);
406 }
407
408 @Override
409 public void setValue(Value value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
410 String parentPath = this.getParent().getPath();
411 String propertyName = this.getName();
412 super.setValue(value);
413 updateLastModifiedProperty(propertyName, parentPath);
414 }
415
416 @Override
417 public void setValue(Value[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
418 String parentPath = this.getParent().getPath();
419 String propertyName = this.getName();
420 super.setValue(values);
421 updateLastModifiedProperty(propertyName, parentPath);
422 }
423
424 @Override
425 public void remove() throws VersionException, LockException, ConstraintViolationException, AccessDeniedException, RepositoryException {
426 String parentPath = this.getParent().getPath();
427 String propertyName = this.getName();
428 super.remove();
429
430 updateLastModifiedProperty(propertyName, parentPath);
431 }
432
433 private void updateLastModifiedProperty(String propertyName, String parentPath) throws RepositoryException {
434 getContentDecorator().updateLastModifiedProperty(getSession().getWorkspace().getName(), propertyName, parentPath);
435 }
436 }
437
438
439
440
441
442
443 @Deprecated
444 public class LastUpdateWorkspaceWrapper extends MgnlPropertySettingWorkspaceWrapper {
445
446 protected LastUpdateWorkspaceWrapper(final Workspace workspace, final ContentDecorator contentDecorator) {
447 super(workspace, contentDecorator);
448 }
449 }
450
451
452
453
454 public class MgnlPropertySettingWorkspaceWrapper extends ContentDecoratorWorkspaceWrapper implements Workspace {
455
456 protected MgnlPropertySettingWorkspaceWrapper(final Workspace workspace, final ContentDecorator contentDecorator) {
457 super(workspace, contentDecorator);
458 }
459
460 @Override
461 public void move(String srcAbsPath, String destAbsPath) throws ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException {
462 super.move(srcAbsPath, destAbsPath);
463 updateLastModified(super.getWrappedWorkspace().getSession(), destAbsPath, true);
464 }
465
466 @Override
467 public void copy(String srcAbsPath, String destAbsPath) throws ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException {
468 super.copy(srcAbsPath, destAbsPath);
469 final String workspaceName = super.getWrappedWorkspace().getName();
470 setCreatedDate(workspaceName, destAbsPath, true);
471
472 NodeUtil.visit(getSession().getNode(destAbsPath), this::removeActivationAndModificationMetadata);
473 getSession().save();
474 }
475
476 private void removeActivationAndModificationMetadata(Node node) throws RepositoryException {
477 if (NodeUtil.hasMixin(node, NodeTypes.HasVersion.NAME)) {
478 node.removeMixin(NodeTypes.HasVersion.NAME);
479 }
480 NodeTypes.LastModified.remove(node);
481 NodeTypes.Activatable.remove(node);
482 log.debug("Stripped activation and modification metadata successfully.");
483 }
484
485 @Override
486 public void copy(String srcWorkspace, String srcAbsPath, String destAbsPath) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException {
487 super.copy(srcWorkspace, srcAbsPath, destAbsPath);
488 final String workspaceName = super.getWrappedWorkspace().getName();
489 setCreatedDate(workspaceName, destAbsPath, true);
490
491 NodeUtil.visit(getSession().getNode(destAbsPath), this::removeActivationAndModificationMetadata);
492 getSession().save();
493 }
494
495 @Override
496 public void clone(String srcWorkspace, String srcAbsPath, String destAbsPath, boolean removeExisting) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException {
497 super.clone(srcWorkspace, srcAbsPath, destAbsPath, removeExisting);
498
499 }
500
501 }
502
503
504
505
506
507
508 @Deprecated
509 public class LastUpdateSessionWrapper extends MgnlPropertySettingSessionWrapper {
510 public LastUpdateSessionWrapper(final Session session, final MgnlPropertySettingContentDecorator contentDecorator) {
511 super(session, contentDecorator);
512 }
513 }
514
515
516
517
518 public class MgnlPropertySettingSessionWrapper extends ContentDecoratorSessionWrapper<MgnlPropertySettingContentDecorator> implements Session {
519
520 public MgnlPropertySettingSessionWrapper(Session session, MgnlPropertySettingContentDecorator contentDecorator) {
521 super(session, contentDecorator);
522 }
523
524 @Override
525 public void move(final String srcAbsPath, final String destAbsPath) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException {
526 super.move(srcAbsPath, destAbsPath);
527
528 boolean onSourcePath = MgnlContext.doInSystemContext(new JCRSessionOp<Boolean>(super.getWrappedSession().getWorkspace().getName()) {
529 @Override
530 public Boolean exec(Session session) throws RepositoryException {
531 return session.itemExists(srcAbsPath);
532 }
533 });
534 String aPath = onSourcePath ? srcAbsPath : destAbsPath;
535 updateLastModified(super.getWrappedSession(), aPath, true);
536 if (onSourcePath) {
537 for (DirtyOp op : dirtyOps) {
538 if (op.getPath().equals(srcAbsPath) || op.getPath().startsWith(srcAbsPath + "/")) {
539 op.setPath(destAbsPath + StringUtils.substringAfter(op.getPath(), srcAbsPath));
540 }
541 }
542 }
543 }
544
545 @Override
546 public void save() throws AccessDeniedException, ItemExistsException, ReferentialIntegrityException, ConstraintViolationException, InvalidItemStateException, VersionException, LockException, NoSuchNodeTypeException, RepositoryException {
547 String workspaceName = wrapped.getWorkspace().getName();
548 try {
549 log.debug("saving session: {}::{}::sys:{}::{}", wrapped.toString(), workspaceName, MgnlContext.isSystemInstance(), Thread.currentThread().getName());
550 super.save();
551 } catch (InvalidItemStateException e) {
552 log.error("Failed to update LUD for session: {}::{}", wrapped.toString(), workspaceName, e);
553 throw e;
554 }
555 if (!dirtyOps.isEmpty()) {
556 Session sysSession = MgnlContext.getSystemContext().getJCRSession(workspaceName);
557 if (sysSession instanceof DelegateSessionWrapper) {
558 sysSession = ((DelegateSessionWrapper) sysSession).deepUnwrap(MgnlPropertySettingSessionWrapper.class);
559 }
560 applyPendingChanges(sysSession);
561 sysSession.save();
562 }
563 }
564
565 protected void applyPendingChanges(Session session) throws RepositoryException, PathNotFoundException {
566 while (!dirtyOps.isEmpty()) {
567 DirtyOp dirty = dirtyOps.remove(0);
568 if (session.nodeExists(dirty.getPath())) {
569 log.debug("Updating {} with {}", dirty.getPath(), dirty.getUpdateDate());
570 LastModified.update(session.getNode(dirty.getPath()), dirty.getUserName(), dirty.getUpdateDate());
571 } else {
572
573 if (log.isDebugEnabled()) {
574 log.warn("wanted to update {}:{} modified by:{} at {} but it's gone now.", session.getWorkspace().getName(), dirty.getPath(), dirty.getUserName(), dirty.getUpdateDate());
575 }
576 }
577 }
578 }
579
580 }
581
582 @Override
583 public Session wrapSession(Session session) {
584 return new MgnlPropertySettingSessionWrapper(session, this);
585 }
586
587 @Override
588 public Workspace wrapWorkspace(Workspace workspace) {
589 return new MgnlPropertySettingWorkspaceWrapper(workspace, this);
590 }
591
592 @Override
593 public Node wrapNode(Node node) {
594 return new MgnlPropertySettingNodeWrapper(node, this);
595 }
596
597 @Override
598 public Property wrapProperty(Property property) {
599 return new LastUpdatePropertyWrapper(property, this);
600 }
601
602 void updateLastModified(final Session session, final String destAbsPath, final boolean recursiveDown) throws RepositoryException, PathNotFoundException {
603 this.updateLastModified(session.getWorkspace().getName(), destAbsPath, recursiveDown);
604 }
605
606 void updateLastModified(final String workspaceName, final String destAbsPath, final boolean recursiveDown) throws RepositoryException, PathNotFoundException {
607
608 if ("/".equals(destAbsPath) && !recursiveDown) {
609
610 return;
611 }
612
613 final Calendar updateDate = Calendar.getInstance();
614
615
616 MgnlContext.doInSystemContext(new ChangeLastUpdateDateOp(workspaceName, getCurrentUserName(), destAbsPath, updateDate, recursiveDown));
617
618 }
619
620 void updateLastModified(String workspaceName, String destAbsPath) throws RepositoryException, PathNotFoundException {
621 updateLastModified(workspaceName, destAbsPath, false);
622 }
623
624 void updateLastModified(Session session, String destAbsPath) throws RepositoryException, PathNotFoundException {
625 updateLastModified(session, destAbsPath, false);
626 }
627
628 void updateLastModifiedProperty(String workspaceName, String propertyName, String parentPath) throws RepositoryException {
629 if (shouldIgnoreUpdate(propertyName)) {
630 return;
631 }
632 updateLastModified(workspaceName, parentPath);
633 }
634
635 void setCreatedDate(final String workspaceName, final String absPath) throws RepositoryException {
636 setCreatedDate(workspaceName, absPath, false);
637 }
638
639 void setCreatedDate(final String workspaceName, final String absPath, final boolean recursiveDown) throws RepositoryException {
640 final Session session = MgnlContext.getJCRSession(workspaceName);
641
642
643 if (!session.itemExists(absPath)) {
644
645 if (log.isDebugEnabled()) {
646 log.warn("Can't update {}. Path {}:{} does not exist.", NodeTypes.Created.NAME, workspaceName, absPath);
647 }
648 return;
649 }
650 Node node = session.getNode(absPath);
651
652
653 if (node == null) {
654 return;
655 }
656
657
658 if (node.getDepth() == 0) {
659 return;
660 }
661
662
663 if (node instanceof DelegateNodeWrapper) {
664 node = ((DelegateNodeWrapper) node).deepUnwrap(MgnlPropertySettingNodeWrapper.class);
665 }
666
667 final String user = getCurrentUserName();
668
669
670 final Calendar now = Calendar.getInstance();
671
672 if (node.isNodeType(NodeTypes.Created.NAME)) {
673 log.debug("Setting {} on {} from {}:{}", NodeTypes.Created.NAME, node.getPath(), node.getSession().toString(), Thread.currentThread().getName());
674 NodeTypes.Created.set(node, user, now);
675 }
676
677 if (recursiveDown) {
678
679 List<NodeIterator> iters = new ArrayList<>();
680 iters.add(node.getNodes());
681 while (!iters.isEmpty()) {
682 List<NodeIterator> tmp = updateChildren(iters, user, now);
683 iters.clear();
684 iters.addAll(tmp);
685 }
686 }
687 }
688
689 private void updateActivationStatus(Node node, String userName) throws RepositoryException {
690 if (NodeUtil.isNodeType(node, NodeTypes.Activatable.NAME)) {
691 NodeTypes.Activatable.update(node, userName, false);
692 }
693 }
694
695 private List<NodeIterator> updateChildren(final List<NodeIterator> iters, final String user, final Calendar updateDate) {
696 List<NodeIterator> tmp = new ArrayList<>();
697 for (NodeIterator iterator : iters) {
698 while (iterator.hasNext()) {
699 Node node = iterator.nextNode();
700 try {
701 if (node.isNodeType(NodeTypes.Created.NAME)) {
702 NodeTypes.Created.set(node, user, updateDate);
703 }
704 tmp.add(node.getNodes());
705 } catch (RepositoryException e) {
706 log.error("Failed to set created date of {} with {}", node, e.getMessage(), e);
707 }
708 }
709 }
710 return tmp;
711 }
712
713
714
715
716 protected boolean shouldIgnoreUpdate(final String propertyName) {
717
718 return propertyName.startsWith(NodeTypes.JCR_PREFIX) || (propertyName.startsWith(NodeTypes.MGNL_PREFIX) && !SPECIAL_PROPERTY_NAMES.contains(propertyName));
719 }
720
721 protected String getCurrentUserName() {
722 String userName = MgnlContext.getUser().getName();
723 if (MgnlContext.isSystemInstance()) {
724
725 Context ctx = ((SystemContext) MgnlContext.getInstance()).getOriginalContext();
726 if (ctx != null && ctx.getUser() != null && !userName.equals(ctx.getUser().getName())) {
727
728 return "System [" + ctx.getUser().getName() + "]";
729 }
730 }
731 return userName;
732 }
733 }