diff --git a/magnolia-core/src/main/java/info/magnolia/audit/MgnlAuditLoggingContentDecoratorNodeWrapper.java b/magnolia-core/src/main/java/info/magnolia/audit/MgnlAuditLoggingContentDecoratorNodeWrapper.java index b6b33c3..b08e1f5 100644 --- a/magnolia-core/src/main/java/info/magnolia/audit/MgnlAuditLoggingContentDecoratorNodeWrapper.java +++ b/magnolia-core/src/main/java/info/magnolia/audit/MgnlAuditLoggingContentDecoratorNodeWrapper.java @@ -34,6 +34,7 @@ package info.magnolia.audit; import info.magnolia.jcr.decoration.ContentDecoratorNodeWrapper; +import info.magnolia.jcr.util.NodeTypes; import java.io.InputStream; import java.math.BigDecimal; @@ -116,112 +117,112 @@ public class MgnlAuditLoggingContentDecoratorNodeWrapper extends ContentDecorato @Override public Property setProperty(String name, Value value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, value); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @Override public Property setProperty(String name, Value[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, values); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @Override public Property setProperty(String name, String[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, values); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @Override public Property setProperty(String name, String value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, value); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @Override public Property setProperty(String name, InputStream value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, value); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @Override public Property setProperty(String name, Binary value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, value); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @Override public Property setProperty(String name, boolean value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, value); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @Override public Property setProperty(String name, double value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, value); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @Override public Property setProperty(String name, BigDecimal value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, value); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @Override public Property setProperty(String name, long value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, value); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @Override public Property setProperty(String name, Calendar value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, value); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @Override public Property setProperty(String name, Node value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, value); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @Override public Property setProperty(String name, Value value, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, value); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @Override public Property setProperty(String name, Value[] values, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, values); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @Override public Property setProperty(String name, String[] values, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, values); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @Override public Property setProperty(String name, String value, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { Property property = super.setProperty(name, value); - getContentDecorator().logActionModify(this); + logActionModify(property); return property; } @@ -246,4 +247,13 @@ public class MgnlAuditLoggingContentDecoratorNodeWrapper extends ContentDecorato } } + private void logActionModify(Property property) throws RepositoryException { + final String name = property.getName(); + if (name.startsWith(NodeTypes.JCR_PREFIX) || name.startsWith(NodeTypes.MGNL_PREFIX)) { + // do not audit system or our prop updates (same as for metadata updates in old API + return; + } + getContentDecorator().logActionModify(this); + } + } diff --git a/magnolia-core/src/main/java/info/magnolia/audit/MgnlAuditLoggingContentDecoratorPropertyWrapper.java b/magnolia-core/src/main/java/info/magnolia/audit/MgnlAuditLoggingContentDecoratorPropertyWrapper.java index 6199131..767852b 100644 --- a/magnolia-core/src/main/java/info/magnolia/audit/MgnlAuditLoggingContentDecoratorPropertyWrapper.java +++ b/magnolia-core/src/main/java/info/magnolia/audit/MgnlAuditLoggingContentDecoratorPropertyWrapper.java @@ -34,12 +34,15 @@ package info.magnolia.audit; import info.magnolia.jcr.decoration.ContentDecoratorPropertyWrapper; +import info.magnolia.jcr.util.NodeTypes; import java.io.InputStream; import java.math.BigDecimal; import java.util.Calendar; +import javax.jcr.AccessDeniedException; import javax.jcr.Binary; +import javax.jcr.ItemNotFoundException; import javax.jcr.Node; import javax.jcr.Property; import javax.jcr.RepositoryException; @@ -62,73 +65,82 @@ public class MgnlAuditLoggingContentDecoratorPropertyWrapper extends ContentDeco @Override public void setValue(Value value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { super.setValue(value); - getContentDecorator().logActionModify(getParent()); + logActionModify(); } @Override public void setValue(Value[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { super.setValue(values); - getContentDecorator().logActionModify(getParent()); + logActionModify(); } @Override public void setValue(String value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { super.setValue(value); - getContentDecorator().logActionModify(getParent()); + logActionModify(); } @Override public void setValue(String[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { super.setValue(values); - getContentDecorator().logActionModify(getParent()); + logActionModify(); } @Override public void setValue(InputStream value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { super.setValue(value); - getContentDecorator().logActionModify(getParent()); + logActionModify(); } @Override public void setValue(Binary value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { super.setValue(value); - getContentDecorator().logActionModify(getParent()); + logActionModify(); } @Override public void setValue(long value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { super.setValue(value); - getContentDecorator().logActionModify(getParent()); + logActionModify(); } @Override public void setValue(double value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { super.setValue(value); - getContentDecorator().logActionModify(getParent()); + logActionModify(); } @Override public void setValue(BigDecimal value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { super.setValue(value); - getContentDecorator().logActionModify(getParent()); + logActionModify(); } @Override public void setValue(Calendar value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { super.setValue(value); - getContentDecorator().logActionModify(getParent()); + logActionModify(); } @Override public void setValue(boolean value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { super.setValue(value); - getContentDecorator().logActionModify(getParent()); + logActionModify(); } @Override public void setValue(Node value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException { super.setValue(value); + logActionModify(); + } + + private void logActionModify() throws RepositoryException, ItemNotFoundException, AccessDeniedException { + final String name = this.getName(); + if (name.startsWith(NodeTypes.JCR_PREFIX) || name.startsWith(NodeTypes.MGNL_PREFIX)) { + // do not audit system or our prop updates (same as for metadata updates in old API) + return; + } getContentDecorator().logActionModify(getParent()); } diff --git a/magnolia-core/src/main/java/info/magnolia/importexport/postprocessors/MetaDataImportPostProcessor.java b/magnolia-core/src/main/java/info/magnolia/importexport/postprocessors/MetaDataImportPostProcessor.java index f240471..9163c32 100644 --- a/magnolia-core/src/main/java/info/magnolia/importexport/postprocessors/MetaDataImportPostProcessor.java +++ b/magnolia-core/src/main/java/info/magnolia/importexport/postprocessors/MetaDataImportPostProcessor.java @@ -33,6 +33,9 @@ */ package info.magnolia.importexport.postprocessors; +import info.magnolia.jcr.wrapper.DelegateNodeWrapper; +import info.magnolia.jcr.wrapper.LastUpdateNodeWrapper; + import javax.jcr.Node; import javax.jcr.RepositoryException; @@ -54,6 +57,10 @@ public class MetaDataImportPostProcessor implements ImportPostProcessor { // do period saves to reduce memory consumption here. conversionHelper.setPeriodicSaves(false); + // we update LUD ourselves so unwrap to prevent interference from LUNW + if (node instanceof DelegateNodeWrapper) { + node = ((DelegateNodeWrapper) node).deepUnwrap(LastUpdateNodeWrapper.class); + } conversionHelper.convertNodeAndChildren(node); } } diff --git a/magnolia-core/src/main/java/info/magnolia/jcr/util/NodeTypes.java b/magnolia-core/src/main/java/info/magnolia/jcr/util/NodeTypes.java index d861ec5..094e9bb 100644 --- a/magnolia-core/src/main/java/info/magnolia/jcr/util/NodeTypes.java +++ b/magnolia-core/src/main/java/info/magnolia/jcr/util/NodeTypes.java @@ -400,7 +400,7 @@ public class NodeTypes { } protected static String getCurrentUserName() { - return MgnlContext.getUser().getName(); + return MgnlContext.getUser() == null ? "not available" : MgnlContext.getUser().getName(); } protected static Calendar getCurrentCalendar() { diff --git a/magnolia-core/src/main/java/info/magnolia/jcr/wrapper/DelegateSessionWrapper.java b/magnolia-core/src/main/java/info/magnolia/jcr/wrapper/DelegateSessionWrapper.java index 54eb978..7fffcfd 100644 --- a/magnolia-core/src/main/java/info/magnolia/jcr/wrapper/DelegateSessionWrapper.java +++ b/magnolia-core/src/main/java/info/magnolia/jcr/wrapper/DelegateSessionWrapper.java @@ -72,7 +72,7 @@ import org.xml.sax.SAXException; * * @version $Id$ */ -public abstract class DelegateSessionWrapper implements Session { +public abstract class DelegateSessionWrapper implements Session, Cloneable { protected Session wrapped; @@ -314,4 +314,48 @@ public abstract class DelegateSessionWrapper implements Session { } return session; } + + /** + * Removes a wrapper by type. The wrapper can be deep in a chain of wrappers in which case wrappers before it will + * be cloned creating a new chain that leads to the same real node. + */ + public Session deepUnwrap(Class wrapper) { + + if (this.getClass().equals(wrapper)) { + return getWrappedSession(); + } + + Session next = getWrappedSession(); + + // If the next session is the real node then we can skip cloning ourselves. + // This happens when the wrapper to remove isn't present + if (!(next instanceof DelegateSessionWrapper)) { + return this; + } + + // We let the next wrapper do deepUnwrap first, if it returns itself then the wrapper isn't in the chain and cloning is not necessary + Session deepUnwrappedNext = ((DelegateSessionWrapper) next).deepUnwrap(wrapper); + if (deepUnwrappedNext == next) { + return this; + } + + try { + DelegateSessionWrapper clone = ((DelegateSessionWrapper) this.clone()); + clone.initClone(deepUnwrappedNext); + return clone; + } catch (CloneNotSupportedException e) { + throw new RuntimeException("Failed to unwrap " + this.getClass().getName() + " due to " + e.getMessage(), e); + } + } + + protected void initClone(Session newSession) { + setWrappedSession(newSession); + } + + @Override + protected Object clone() throws CloneNotSupportedException { + // just shallow clone ... keep it that way at least for wrappedSession otherwise deepUnwrap generates zillions of objects unnecessarily + return super.clone(); + } + } diff --git a/magnolia-core/src/main/java/info/magnolia/repository/DefaultRepositoryManager.java b/magnolia-core/src/main/java/info/magnolia/repository/DefaultRepositoryManager.java index 4ddd72f..c52bdfb 100644 --- a/magnolia-core/src/main/java/info/magnolia/repository/DefaultRepositoryManager.java +++ b/magnolia-core/src/main/java/info/magnolia/repository/DefaultRepositoryManager.java @@ -33,21 +33,6 @@ */ package info.magnolia.repository; -import java.io.InputStream; -import java.util.Collection; -import javax.inject.Singleton; -import javax.jcr.Credentials; -import javax.jcr.NoSuchWorkspaceException; -import javax.jcr.Node; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; - -import info.magnolia.jcr.RuntimeRepositoryException; -import org.apache.commons.io.IOUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import info.magnolia.audit.MgnlAuditLoggingContentDecorator; import info.magnolia.audit.MgnlAuditLoggingContentDecoratorSessionWrapper; import info.magnolia.cms.core.SystemProperty; @@ -55,9 +40,11 @@ import info.magnolia.cms.core.version.MgnlVersioningSession; import info.magnolia.cms.security.AccessDeniedException; import info.magnolia.cms.util.ConfigUtil; import info.magnolia.context.MgnlContext; +import info.magnolia.jcr.RuntimeRepositoryException; import info.magnolia.jcr.predicate.AbstractPredicate; import info.magnolia.jcr.util.NodeTypes; import info.magnolia.jcr.util.NodeUtil; +import info.magnolia.jcr.wrapper.LastUpdateContentDecorator; import info.magnolia.objectfactory.Classes; import info.magnolia.objectfactory.Components; import info.magnolia.repository.definition.RepositoryDefinition; @@ -67,6 +54,21 @@ import info.magnolia.repository.definition.WorkspaceMappingDefinition; import info.magnolia.repository.mbean.TrackingSessionWrapper; import info.magnolia.stats.JCRStats; +import java.io.InputStream; +import java.util.Collection; + +import javax.inject.Singleton; +import javax.jcr.Credentials; +import javax.jcr.NoSuchWorkspaceException; +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Manages all used Repositories. */ @@ -251,6 +253,7 @@ public final class DefaultRepositoryManager implements RepositoryManager { // it's only temporary solution. It will be removed when MAGNOLIA-5012 is resolved. return new MgnlVersioningSession(session); } + session = new LastUpdateContentDecorator().wrapSession(session); return new MgnlAuditLoggingContentDecoratorSessionWrapper(new MgnlVersioningSession(session), new MgnlAuditLoggingContentDecorator()); } diff --git a/magnolia-core/src/test/java/info/magnolia/audit/MgnlAuditLoggingContentDecoratorTest.java b/magnolia-core/src/test/java/info/magnolia/audit/MgnlAuditLoggingContentDecoratorTest.java index abf2d7f..318013d 100644 --- a/magnolia-core/src/test/java/info/magnolia/audit/MgnlAuditLoggingContentDecoratorTest.java +++ b/magnolia-core/src/test/java/info/magnolia/audit/MgnlAuditLoggingContentDecoratorTest.java @@ -33,9 +33,7 @@ */ package info.magnolia.audit; -import static org.junit.Assert.assertEquals; - -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import info.magnolia.context.MgnlContext; import info.magnolia.importexport.DataTransporter; diff --git a/magnolia-core/src/test/java/info/magnolia/importexport/postprocessors/MetaDataImportPostProcessorTest.java b/magnolia-core/src/test/java/info/magnolia/importexport/postprocessors/MetaDataImportPostProcessorTest.java index 0b465e8..6f85cc6 100644 --- a/magnolia-core/src/test/java/info/magnolia/importexport/postprocessors/MetaDataImportPostProcessorTest.java +++ b/magnolia-core/src/test/java/info/magnolia/importexport/postprocessors/MetaDataImportPostProcessorTest.java @@ -33,18 +33,19 @@ */ package info.magnolia.importexport.postprocessors; +import static org.junit.Assert.*; + +import info.magnolia.context.MgnlContext; +import info.magnolia.jcr.util.NodeTypes; +import info.magnolia.test.RepositoryTestCase; + import java.util.Calendar; + import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; -import info.magnolia.jcr.util.NodeTypes; import org.junit.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import info.magnolia.context.MgnlContext; -import info.magnolia.test.RepositoryTestCase; /** * Test case for {@link MetaDataImportPostProcessor}. @@ -84,11 +85,11 @@ public class MetaDataImportPostProcessorTest extends RepositoryTestCase { private void assertPropertyEquals(Node node, String relPath, String expectedValue) throws RepositoryException { assertTrue(node.hasProperty(relPath)); - assertEquals(node.getProperty(relPath).getValue().getString(), expectedValue); + assertEquals(expectedValue, node.getProperty(relPath).getValue().getString()); } private void assertPropertyEquals(Node node, String relPath, Calendar expectedValue) throws RepositoryException { assertTrue(node.hasProperty(relPath)); - assertEquals(node.getProperty(relPath).getValue().getDate().getTimeInMillis(), expectedValue.getTimeInMillis()); + assertEquals(expectedValue.getTimeInMillis(), node.getProperty(relPath).getValue().getDate().getTimeInMillis()); } } diff --git a/magnolia-rendering/src/test/java/info/magnolia/rendering/renderer/I18nNodeWrapperRendererTest.java b/magnolia-rendering/src/test/java/info/magnolia/rendering/renderer/I18nNodeWrapperRendererTest.java index a71a9d5..66c9c35 100644 --- a/magnolia-rendering/src/test/java/info/magnolia/rendering/renderer/I18nNodeWrapperRendererTest.java +++ b/magnolia-rendering/src/test/java/info/magnolia/rendering/renderer/I18nNodeWrapperRendererTest.java @@ -50,7 +50,6 @@ import info.magnolia.rendering.template.variation.RenderableVariationResolver; import info.magnolia.repository.RepositoryConstants; import info.magnolia.test.ComponentsTestUtil; import info.magnolia.test.RepositoryTestCase; -import info.magnolia.test.mock.MockWebContext; import java.io.IOException; @@ -77,7 +76,7 @@ public class I18nNodeWrapperRendererTest extends RepositoryTestCase { ComponentsTestUtil.setImplementation(RenderingEngine.class, DefaultRenderingEngine.class); ComponentsTestUtil.setImplementation(TemplateDefinitionAssignment.class, MetaDataBasedTemplateDefinitionAssignment.class); ComponentsTestUtil.setImplementation(RenderableVariationResolver.class, NoopVariationResolver.class); - ComponentsTestUtil.setInstance(SystemContext.class, new MockWebContext()); + ComponentsTestUtil.setInstance(SystemContext.class, MgnlContext.getSystemContext()); ComponentsTestUtil.setInstance(Provider.class, mock(Provider.class)); }