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 final String user = getCurrentUserName();
472 NodeUtil.visit(getSession().getNode(destAbsPath), node -> updateActivationStatus(node, user));
473 getSession().save();
474 }
475
476 @Override
477 public void copy(String srcWorkspace, String srcAbsPath, String destAbsPath) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException {
478 super.copy(srcWorkspace, srcAbsPath, destAbsPath);
479 final String workspaceName = super.getWrappedWorkspace().getName();
480 setCreatedDate(workspaceName, destAbsPath, true);
481 final String user = getCurrentUserName();
482 NodeUtil.visit(getSession().getNode(destAbsPath), node -> updateActivationStatus(node, user));
483 getSession().save();
484 }
485
486 @Override
487 public void clone(String srcWorkspace, String srcAbsPath, String destAbsPath, boolean removeExisting) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException {
488 super.clone(srcWorkspace, srcAbsPath, destAbsPath, removeExisting);
489
490 }
491
492 }
493
494
495
496
497
498
499 @Deprecated
500 public class LastUpdateSessionWrapper extends MgnlPropertySettingSessionWrapper {
501 public LastUpdateSessionWrapper(final Session session, final MgnlPropertySettingContentDecorator contentDecorator) {
502 super(session, contentDecorator);
503 }
504 }
505
506
507
508
509 public class MgnlPropertySettingSessionWrapper extends ContentDecoratorSessionWrapper<MgnlPropertySettingContentDecorator> implements Session {
510
511 public MgnlPropertySettingSessionWrapper(Session session, MgnlPropertySettingContentDecorator contentDecorator) {
512 super(session, contentDecorator);
513 }
514
515 @Override
516 public void move(final String srcAbsPath, final String destAbsPath) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException {
517 super.move(srcAbsPath, destAbsPath);
518
519 boolean onSourcePath = MgnlContext.doInSystemContext(new JCRSessionOp<Boolean>(super.getWrappedSession().getWorkspace().getName()) {
520 @Override
521 public Boolean exec(Session session) throws RepositoryException {
522 return session.itemExists(srcAbsPath);
523 }
524 });
525 String aPath = onSourcePath ? srcAbsPath : destAbsPath;
526 updateLastModified(super.getWrappedSession(), aPath, true);
527 if (onSourcePath) {
528 for (DirtyOp op : dirtyOps) {
529 if (op.getPath().equals(srcAbsPath) || op.getPath().startsWith(srcAbsPath + "/")) {
530 op.setPath(destAbsPath + StringUtils.substringAfter(op.getPath(), srcAbsPath));
531 }
532 }
533 }
534 }
535
536 @Override
537 public void save() throws AccessDeniedException, ItemExistsException, ReferentialIntegrityException, ConstraintViolationException, InvalidItemStateException, VersionException, LockException, NoSuchNodeTypeException, RepositoryException {
538 String workspaceName = wrapped.getWorkspace().getName();
539 try {
540 log.debug("saving session: {}::{}::sys:{}::{}", wrapped.toString(), workspaceName, MgnlContext.isSystemInstance(), Thread.currentThread().getName());
541 super.save();
542 } catch (InvalidItemStateException e) {
543 log.error("Failed to update LUD for session: {}::{}", wrapped.toString(), workspaceName, e);
544 throw e;
545 }
546 if (!dirtyOps.isEmpty()) {
547 Session sysSession = MgnlContext.getSystemContext().getJCRSession(workspaceName);
548 if (sysSession instanceof DelegateSessionWrapper) {
549 sysSession = ((DelegateSessionWrapper) sysSession).deepUnwrap(MgnlPropertySettingSessionWrapper.class);
550 }
551 applyPendingChanges(sysSession);
552 sysSession.save();
553 }
554 }
555
556 protected void applyPendingChanges(Session session) throws RepositoryException, PathNotFoundException {
557 while (!dirtyOps.isEmpty()) {
558 DirtyOp dirty = dirtyOps.remove(0);
559 if (session.nodeExists(dirty.getPath())) {
560 log.debug("Updating {} with {}", dirty.getPath(), dirty.getUpdateDate());
561 LastModified.update(session.getNode(dirty.getPath()), dirty.getUserName(), dirty.getUpdateDate());
562 } else {
563
564 if (log.isDebugEnabled()) {
565 log.warn("wanted to update {}:{} modified by:{} at {} but it's gone now.", session.getWorkspace().getName(), dirty.getPath(), dirty.getUserName(), dirty.getUpdateDate());
566 }
567 }
568 }
569 }
570
571 }
572
573 @Override
574 public Session wrapSession(Session session) {
575 return new MgnlPropertySettingSessionWrapper(session, this);
576 }
577
578 @Override
579 public Workspace wrapWorkspace(Workspace workspace) {
580 return new MgnlPropertySettingWorkspaceWrapper(workspace, this);
581 }
582
583 @Override
584 public Node wrapNode(Node node) {
585 return new MgnlPropertySettingNodeWrapper(node, this);
586 }
587
588 @Override
589 public Property wrapProperty(Property property) {
590 return new LastUpdatePropertyWrapper(property, this);
591 }
592
593 void updateLastModified(final Session session, final String destAbsPath, final boolean recursiveDown) throws RepositoryException, PathNotFoundException {
594 this.updateLastModified(session.getWorkspace().getName(), destAbsPath, recursiveDown);
595 }
596
597 void updateLastModified(final String workspaceName, final String destAbsPath, final boolean recursiveDown) throws RepositoryException, PathNotFoundException {
598
599 if ("/".equals(destAbsPath) && !recursiveDown) {
600
601 return;
602 }
603
604 final Calendar updateDate = Calendar.getInstance();
605
606
607 MgnlContext.doInSystemContext(new ChangeLastUpdateDateOp(workspaceName, getCurrentUserName(), destAbsPath, updateDate, recursiveDown));
608
609 }
610
611 void updateLastModified(String workspaceName, String destAbsPath) throws RepositoryException, PathNotFoundException {
612 updateLastModified(workspaceName, destAbsPath, false);
613 }
614
615 void updateLastModified(Session session, String destAbsPath) throws RepositoryException, PathNotFoundException {
616 updateLastModified(session, destAbsPath, false);
617 }
618
619 void updateLastModifiedProperty(String workspaceName, String propertyName, String parentPath) throws RepositoryException {
620 if (shouldIgnoreUpdate(propertyName)) {
621 return;
622 }
623 updateLastModified(workspaceName, parentPath);
624 }
625
626 void setCreatedDate(final String workspaceName, final String absPath) throws RepositoryException {
627 setCreatedDate(workspaceName, absPath, false);
628 }
629
630 void setCreatedDate(final String workspaceName, final String absPath, final boolean recursiveDown) throws RepositoryException {
631 final Session session = MgnlContext.getJCRSession(workspaceName);
632
633
634 if (!session.itemExists(absPath)) {
635
636 if (log.isDebugEnabled()) {
637 log.warn("Can't update {}. Path {}:{} does not exist.", NodeTypes.Created.NAME, workspaceName, absPath);
638 }
639 return;
640 }
641 Node node = session.getNode(absPath);
642
643
644 if (node == null) {
645 return;
646 }
647
648
649 if (node.getDepth() == 0) {
650 return;
651 }
652
653
654 if (node instanceof DelegateNodeWrapper) {
655 node = ((DelegateNodeWrapper) node).deepUnwrap(MgnlPropertySettingNodeWrapper.class);
656 }
657
658 final String user = getCurrentUserName();
659
660
661 final Calendar now = Calendar.getInstance();
662
663 if (node.isNodeType(NodeTypes.Created.NAME)) {
664 log.debug("Setting {} on {} from {}:{}", NodeTypes.Created.NAME, node.getPath(), node.getSession().toString(), Thread.currentThread().getName());
665 NodeTypes.Created.set(node, user, now);
666 }
667
668 if (recursiveDown) {
669
670 List<NodeIterator> iters = new ArrayList<>();
671 iters.add(node.getNodes());
672 while (!iters.isEmpty()) {
673 List<NodeIterator> tmp = updateChildren(iters, user, now);
674 iters.clear();
675 iters.addAll(tmp);
676 }
677 }
678 }
679
680 private void updateActivationStatus(Node node, String userName) throws RepositoryException {
681 if (NodeUtil.isNodeType(node, NodeTypes.Activatable.NAME)) {
682 NodeTypes.Activatable.update(node, userName, false);
683 }
684 }
685
686 private List<NodeIterator> updateChildren(final List<NodeIterator> iters, final String user, final Calendar updateDate) {
687 List<NodeIterator> tmp = new ArrayList<>();
688 for (NodeIterator iterator : iters) {
689 while (iterator.hasNext()) {
690 Node node = iterator.nextNode();
691 try {
692 if (node.isNodeType(NodeTypes.Created.NAME)) {
693 NodeTypes.Created.set(node, user, updateDate);
694 }
695 tmp.add(node.getNodes());
696 } catch (RepositoryException e) {
697 log.error("Failed to set created date of {} with {}", node, e.getMessage(), e);
698 }
699 }
700 }
701 return tmp;
702 }
703
704
705
706
707 protected boolean shouldIgnoreUpdate(final String propertyName) {
708
709 return propertyName.startsWith(NodeTypes.JCR_PREFIX) || (propertyName.startsWith(NodeTypes.MGNL_PREFIX) && !SPECIAL_PROPERTY_NAMES.contains(propertyName));
710 }
711
712 protected String getCurrentUserName() {
713 String userName = MgnlContext.getUser().getName();
714 if (MgnlContext.isSystemInstance()) {
715
716 Context ctx = ((SystemContext) MgnlContext.getInstance()).getOriginalContext();
717 if (ctx != null && ctx.getUser() != null && !userName.equals(ctx.getUser().getName())) {
718
719 return "System [" + ctx.getUser().getName() + "]";
720 }
721 }
722 return userName;
723 }
724 }