You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by kw...@apache.org on 2022/02/15 09:32:37 UTC
[jackrabbit-filevault] branch master updated: JCRVLT-605 don't overwrite filtered protected properties during import (#206)
This is an automated email from the ASF dual-hosted git repository.
kwin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git
The following commit(s) were added to refs/heads/master by this push:
new 14dcce9 JCRVLT-605 don't overwrite filtered protected properties during import (#206)
14dcce9 is described below
commit 14dcce932be027d79274e82d11ddeec1ac0bb0d6
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Tue Feb 15 10:32:33 2022 +0100
JCRVLT-605 don't overwrite filtered protected properties during import (#206)
---
.../vault/fs/impl/io/DocViewImporter.java | 108 ++++++++++++++-------
.../vault/fs/impl/io/DocViewSAXFormatter.java | 27 +++---
.../apache/jackrabbit/vault/fs/io/FileArchive.java | 11 ++-
.../jackrabbit/vault/fs/io/ZipNioArchive.java | 6 +-
.../jackrabbit/vault/packaging/PackageManager.java | 4 +-
.../vault/packaging/impl/PackageManagerImpl.java | 14 ++-
.../apache/jackrabbit/vault/fs/io/ArchiveTest.java | 1 +
.../integration/FilteredPropertiesIT.java | 68 +++++++++++--
.../META-INF/vault/nodetypes.cnd | 1 +
.../jcr_root/testroot3/.content.xml | 11 +++
10 files changed, 188 insertions(+), 63 deletions(-)
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java
index 88ab639..b401928 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java
@@ -84,6 +84,7 @@ import org.apache.jackrabbit.vault.util.DocViewProperty2;
import org.apache.jackrabbit.vault.util.EffectiveNodeType;
import org.apache.jackrabbit.vault.util.JcrConstants;
import org.apache.jackrabbit.vault.util.MimeTypes;
+import org.apache.jackrabbit.vault.util.PathUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
@@ -110,23 +111,30 @@ public class DocViewImporter implements DocViewParserHandler {
static final Logger log = LoggerFactory.getLogger(DocViewImporter.class);
/**
- * these properties are protected but can be set nevertheless via system view xml import
+ * these properties are protected but are set for new nodes nevertheless via system view xml import
*/
- static final Set<Name> PROTECTED_PROPERTIES;
+ static final Set<Name> PROTECTED_PROPERTIES_CONSIDERED_FOR_NEW_NODES;
+
+ /**
+ * these properties are protected but are set for updated nodes via special JCR methods
+ */
+ static final Set<Name> PROTECTED_PROPERTIES_CONSIDERED_FOR_UPDATED_NODES;
static {
Set<Name> props = new HashSet<>();
props.add(NameConstants.JCR_PRIMARYTYPE);
props.add(NameConstants.JCR_MIXINTYPES);
props.add(NameConstants.JCR_UUID);
+ PROTECTED_PROPERTIES_CONSIDERED_FOR_UPDATED_NODES = Collections.unmodifiableSet(props);
props.add(NameConstants.JCR_ISCHECKEDOUT);
props.add(NameConstants.JCR_BASEVERSION);
props.add(NameConstants.JCR_PREDECESSORS);
props.add(NameConstants.JCR_SUCCESSORS);
props.add(NameConstants.JCR_VERSIONHISTORY);
- PROTECTED_PROPERTIES = Collections.unmodifiableSet(props);
+ PROTECTED_PROPERTIES_CONSIDERED_FOR_NEW_NODES = Collections.unmodifiableSet(props);
}
+
/**
* the importing session
*/
@@ -934,7 +942,7 @@ public class DocViewImporter implements DocViewParserHandler {
// TODO: is this faster than using sysview import?
// set new primary type (but never set rep:root)
String primaryType = ni.getPrimaryType().orElseThrow(() -> new IllegalStateException("Mandatory property 'jcr:primaryType' missing from " + ni));
- if (importMode == ImportMode.REPLACE && !"rep:root".equals(primaryType)) {
+ if (importMode == ImportMode.REPLACE && !"rep:root".equals(primaryType) && wspFilter.includesProperty(PathUtil.append(node.getPath(), JcrConstants.JCR_PRIMARYTYPE))) {
if (!node.getPrimaryNodeType().getName().equals(primaryType)) {
vs.ensureCheckedOut();
node.setPrimaryType(primaryType);
@@ -943,37 +951,38 @@ public class DocViewImporter implements DocViewParserHandler {
}
// calculate mixins to be added
Set<String> newMixins = new HashSet<>();
- AccessControlHandling acHandling = getAcHandling(ni.getName());
- for (String mixin : ni.getMixinTypes()) {
- // omit name if mix:AccessControllable and CLEAR
- if (!aclManagement.isAccessControllableMixin(mixin)
- || acHandling != AccessControlHandling.CLEAR) {
- newMixins.add(mixin);
+ if (wspFilter.includesProperty(PathUtil.append(node.getPath(), JcrConstants.JCR_MIXINTYPES))) {
+ AccessControlHandling acHandling = getAcHandling(ni.getName());
+ for (String mixin : ni.getMixinTypes()) {
+ // omit if mix:AccessControllable and CLEAR
+ if (!aclManagement.isAccessControllableMixin(mixin)
+ || acHandling != AccessControlHandling.CLEAR) {
+ newMixins.add(mixin);
+ }
}
- }
- // remove mixins not in package (only for mode = replace)
- if (importMode == ImportMode.REPLACE) {
- for (NodeType mix : node.getMixinNodeTypes()) {
- String name = mix.getName();
- if (!newMixins.remove(name)) {
- // special check for mix:AccessControllable
- if (!aclManagement.isAccessControllableMixin(name)
- || acHandling == AccessControlHandling.CLEAR
- || acHandling == AccessControlHandling.OVERWRITE) {
- vs.ensureCheckedOut();
- node.removeMixin(name);
- updatedNode = node;
+ // remove mixins not in package (only for mode = replace)
+ if (importMode == ImportMode.REPLACE) {
+ for (NodeType mix : node.getMixinNodeTypes()) {
+ String name = mix.getName();
+ if (!newMixins.remove(name)) {
+ // special check for mix:AccessControllable
+ if (!aclManagement.isAccessControllableMixin(name)
+ || acHandling == AccessControlHandling.CLEAR
+ || acHandling == AccessControlHandling.OVERWRITE) {
+ vs.ensureCheckedOut();
+ node.removeMixin(name);
+ updatedNode = node;
+ }
}
}
}
+ // add remaining mixins (for all import modes)
+ for (String mixin : newMixins) {
+ vs.ensureCheckedOut();
+ node.addMixin(mixin);
+ updatedNode = node;
+ }
}
- // add remaining mixins (for all import modes)
- for (String mixin : newMixins) {
- vs.ensureCheckedOut();
- node.addMixin(mixin);
- updatedNode = node;
- }
-
// remove unprotected properties not in package (only for mode = replace)
if (importMode == ImportMode.REPLACE) {
PropertyIterator pIter = node.getProperties();
@@ -990,9 +999,12 @@ public class DocViewImporter implements DocViewParserHandler {
}
}
}
+ EffectiveNodeType effectiveNodeType = EffectiveNodeType.ofNode(node);
+ // logging for uncovered protected properties
+ logIgnoredProtectedProperties(effectiveNodeType, node.getPath(), ni.getProperties(), PROTECTED_PROPERTIES_CONSIDERED_FOR_UPDATED_NODES);
// add/modify properties contained in package
- if (setUnprotectedProperties(node, ni, importMode == ImportMode.REPLACE|| importMode == ImportMode.UPDATE || importMode == ImportMode.UPDATE_PROPERTIES, vs)) {
+ if (setUnprotectedProperties(effectiveNodeType, node, ni, importMode == ImportMode.REPLACE|| importMode == ImportMode.UPDATE || importMode == ImportMode.UPDATE_PROPERTIES, vs)) {
updatedNode = node;
}
}
@@ -1041,7 +1053,7 @@ public class DocViewImporter implements DocViewParserHandler {
boolean addMixRef = false;
if (ni.getIndex() > 0 && !ni.getIdentifier().isPresent()) {
- Collection<DocViewProperty2> preprocessedProperties = new LinkedList<>(ni.getProperties());
+ Collection<DocViewProperty2> preprocessedProperties = new LinkedList<>(ni.getProperties());
preprocessedProperties.add(new DocViewProperty2( NameConstants.JCR_UUID, UUID.randomUUID().toString(), PropertyType.STRING));
// check mixins
DocViewProperty2 mix = ni.getProperty(NameConstants.JCR_MIXINTYPES).orElse(null);
@@ -1066,11 +1078,14 @@ public class DocViewImporter implements DocViewParserHandler {
}
ni = ni.cloneWithDifferentProperties(preprocessedProperties);
}
+
+ String nodePath = PathUtil.append(parentPath, npResolver.getJCRName(ni.getName()));
// add the protected properties
for (DocViewProperty2 p : ni.getProperties()) {
- if (p.getStringValue().isPresent() && PROTECTED_PROPERTIES.contains(p.getName())) {
+ String qualifiedPropertyName = npResolver.getJCRName(p.getName());
+ if (p.getStringValue().isPresent() && PROTECTED_PROPERTIES_CONSIDERED_FOR_NEW_NODES.contains(p.getName()) && wspFilter.includesProperty(nodePath + "/" + qualifiedPropertyName)) {
attrs = new AttributesImpl();
- attrs.addAttribute(Name.NS_SV_URI, "name", "sv:name", ATTRIBUTE_TYPE_CDATA, npResolver.getJCRName(p.getName()));
+ attrs.addAttribute(Name.NS_SV_URI, "name", "sv:name", ATTRIBUTE_TYPE_CDATA, qualifiedPropertyName);
attrs.addAttribute(Name.NS_SV_URI, "type", "sv:type", ATTRIBUTE_TYPE_CDATA, PropertyType.nameFromValue(p.getType()));
handler.startElement(Name.NS_SV_URI, "property", "sv:property", attrs);
for (String v : p.getStringValues()) {
@@ -1086,7 +1101,11 @@ public class DocViewImporter implements DocViewParserHandler {
// retrieve newly created node either by uuid, label or name
Node node = getNodeByIdOrName(parentNode, ni, importUuidBehavior == ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
- setUnprotectedProperties(node, ni, true, null);
+ EffectiveNodeType effectiveNodeType = EffectiveNodeType.ofNode(node);
+
+ // logging for uncovered protected properties
+ logIgnoredProtectedProperties(effectiveNodeType, node.getPath(), ni.getProperties(), PROTECTED_PROPERTIES_CONSIDERED_FOR_NEW_NODES);
+ setUnprotectedProperties(effectiveNodeType, node, ni, true, null);
// remove mix referenceable if it was temporarily added
if (addMixRef) {
node.removeMixin(JcrConstants.MIX_REFERENCEABLE);
@@ -1114,6 +1133,22 @@ public class DocViewImporter implements DocViewParserHandler {
}
}
+ private void logIgnoredProtectedProperties(EffectiveNodeType effectiveNodeType, String nodePath, Collection<DocViewProperty2> properties, Set<Name> importedProtectedProperties) {
+ // logging for protected properties which are not considered during import
+ properties.stream()
+ .filter(p -> p.getStringValue().isPresent()
+ && !importedProtectedProperties.contains(p.getName()))
+ .forEach(p -> {
+ try {
+ if (isPropertyProtected(effectiveNodeType, p)) {
+ log.warn("Ignore protected property '{}' on node '{}'", npResolver.getJCRName(p.getName()), nodePath);
+ }
+ } catch (RepositoryException e) {
+ throw new IllegalStateException("Error retrieving protected status of properties", e);
+ }
+ });
+ }
+
/**
* Determines if a given property is protected according to the node type.
*
@@ -1153,7 +1188,7 @@ public class DocViewImporter implements DocViewParserHandler {
return node;
}
- private boolean setUnprotectedProperties(@NotNull Node node, @NotNull DocViewNode2 ni, boolean overwriteExistingProperties, @Nullable VersioningState vs) throws RepositoryException {
+ private boolean setUnprotectedProperties(@NotNull EffectiveNodeType effectiveNodeType, @NotNull Node node, @NotNull DocViewNode2 ni, boolean overwriteExistingProperties, @Nullable VersioningState vs) throws RepositoryException {
boolean isAtomicCounter = false;
for (String mixin : ni.getMixinTypes()) {
if ("mix:atomicCounter".equals(mixin)) {
@@ -1161,7 +1196,6 @@ public class DocViewImporter implements DocViewParserHandler {
}
}
- EffectiveNodeType effectiveNodeType = EffectiveNodeType.ofNode(node);
boolean modified = false;
// add properties
for (DocViewProperty2 prop : ni.getProperties()) {
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXFormatter.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXFormatter.java
index 6470b0f..b5e40a7 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXFormatter.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXFormatter.java
@@ -99,7 +99,7 @@ public class DocViewSAXFormatter implements AggregateWalkListener {
protected final String jcrRoot;
// used to temporarily store properties of a node
- private final List<Property> props = new ArrayList<Property>();
+ private final List<Property> props = new ArrayList<>();
/**
* the export context
@@ -112,9 +112,18 @@ public class DocViewSAXFormatter implements AggregateWalkListener {
private final boolean useBinaryReferences;
/**
- * internally ignored properties
+ * Names of properties which should never be contained in the doc view serialization.
*/
- private final Set<String> ignored = new HashSet<String>();
+ private static final Set<String> IGNORED_PROTECTED_PROPERTIES;
+ static {
+ Set<String> props = new HashSet<>();
+ props.add(JcrConstants.JCR_CREATED);
+ props.add(JcrConstants.JCR_CREATED_BY);
+ props.add(JcrConstants.JCR_BASEVERSION);
+ props.add(JcrConstants.JCR_VERSIONHISTORY);
+ props.add(JcrConstants.JCR_PREDECESSORS);
+ IGNORED_PROTECTED_PROPERTIES = Collections.unmodifiableSet(props);
+ }
private ItemNameComparator2 itemNameComparator;
@@ -184,14 +193,6 @@ public class DocViewSAXFormatter implements AggregateWalkListener {
*/
@Override
public void onWalkBegin(Node root) throws RepositoryException {
- // init ignored protected properties
- ignored.clear();
- ignored.add(JcrConstants.JCR_CREATED);
- ignored.add(JcrConstants.JCR_CREATED_BY);
- ignored.add(JcrConstants.JCR_BASEVERSION);
- ignored.add(JcrConstants.JCR_VERSIONHISTORY);
- ignored.add(JcrConstants.JCR_PREDECESSORS);
-
try {
writer.writeStartDocument();
} catch (XMLStreamException e) {
@@ -230,7 +231,7 @@ public class DocViewSAXFormatter implements AggregateWalkListener {
String label = Text.getName(node.getPath());
final String elemName;
if (level == 0) {
- // root node needs a name
+ // root node needs a special name
elemName = jcrRoot;
} else {
// encode node name to make sure it's a valid xml name
@@ -289,7 +290,7 @@ public class DocViewSAXFormatter implements AggregateWalkListener {
*/
@Override
public void onProperty(Property prop, int level) throws RepositoryException {
- if (ignored.contains(prop.getName()) && prop.getDefinition().isProtected()) {
+ if (IGNORED_PROTECTED_PROPERTIES.contains(prop.getName())) {
return;
}
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/FileArchive.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/FileArchive.java
index 821dd84..c41f662 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/FileArchive.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/FileArchive.java
@@ -90,7 +90,7 @@ public class FileArchive extends AbstractArchive {
*/
@Override
public Entry getRoot() throws IOException {
- return new OsEntry(eRoot.getRoot());
+ return new OsEntry(eRoot.getRoot(), true);
}
/**
@@ -128,9 +128,15 @@ public class FileArchive extends AbstractArchive {
private static class OsEntry implements Entry {
private final File file;
+ private final boolean isRoot;
private OsEntry(File file) {
+ this(file, false);
+ }
+
+ private OsEntry(File file, boolean isRoot) {
this.file = file;
+ this.isRoot = isRoot;
}
/**
@@ -138,6 +144,9 @@ public class FileArchive extends AbstractArchive {
*/
@Override
public String getName() {
+ if (isRoot) {
+ return "";
+ }
return file.getName();
}
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/ZipNioArchive.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/ZipNioArchive.java
index cd9d9e9..f136fd6 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/ZipNioArchive.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/ZipNioArchive.java
@@ -266,7 +266,11 @@ public class ZipNioArchive extends AbstractArchive {
@Override
@NotNull
public String getName() {
- String name = path.getName(path.getNameCount()-1).toString();
+ int numNames = path.getNameCount();
+ if (numNames == 0) {
+ return "";
+ }
+ String name = path.getName(numNames-1).toString();
// strip trailing slashes (returned by Zip File System provider for directories)
if (name.endsWith("/")) {
name = name.substring(0, name.length()-1);
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/PackageManager.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/PackageManager.java
index ed87954..10664ab 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/PackageManager.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/PackageManager.java
@@ -141,11 +141,11 @@ public interface PackageManager {
/**
* Re-wraps a package using the given meta information and file to
- * store to. if file is {@code null} a temp file is generated.
+ * store to.
*
* @param opts export options
* @param src source package
- * @param file the file to write to
+ * @param file the file to write to (may be {@code null}) to create a new temp file
* @return the newly created vault package
*
* @throws IOException if an I/O error occurs.
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackageManagerImpl.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackageManagerImpl.java
index 21e8102..2507bd8 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackageManagerImpl.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackageManagerImpl.java
@@ -218,11 +218,11 @@ public class PackageManagerImpl implements PackageManager {
}
final Set<String> metaInfIncludes;
- final Set<String> metaInfExcludes;
+ final Set<String> metaInfExcludes = new HashSet<>();
if (opts.getPostProcessor() == null) {
// no post processor, we keep all metadata files except the properties
metaInfIncludes = Collections.emptySet();
- metaInfExcludes = Collections.singleton(Constants.META_DIR + "/" + Constants.PROPERTIES_XML);
+ metaInfExcludes.add(Constants.META_DIR + "/" + Constants.PROPERTIES_XML);
} else {
metaInfIncludes = new HashSet<>();
@@ -230,9 +230,11 @@ public class PackageManagerImpl implements PackageManager {
metaInfIncludes.add(Constants.META_DIR + "/" + Constants.NODETYPES_CND);
metaInfIncludes.add(Constants.META_DIR + "/" + Constants.CONFIG_XML);
metaInfIncludes.add(Constants.META_DIR + "/" + Constants.FILTER_XML);
- metaInfExcludes = Collections.emptySet();
}
+ if (inf.getFilter() != null) {
+ metaInfExcludes.add(Constants.META_DIR + "/" + Constants.FILTER_XML);
+ }
try (Archive archive = src.getArchive()) {
archive.open(false);
addArchiveEntryToExporter(exporter, archive, "", archive.getRoot(), metaInfIncludes, metaInfExcludes);
@@ -246,6 +248,12 @@ public class PackageManagerImpl implements PackageManager {
tracker.track("A", Constants.META_DIR + "/" + Constants.PROPERTIES_XML);
}
+ if (inf.getFilter() != null) {
+ // write updated filter
+ try (InputStream filterStream = inf.getFilter().getSource()) {
+ exporter.writeFile(filterStream, Constants.META_DIR + "/" + Constants.FILTER_XML);
+ }
+ }
if (opts.getPostProcessor() != null) {
opts.getPostProcessor().process(exporter);
}
diff --git a/vault-core/src/test/java/org/apache/jackrabbit/vault/fs/io/ArchiveTest.java b/vault-core/src/test/java/org/apache/jackrabbit/vault/fs/io/ArchiveTest.java
index 3936ecf..366c807 100644
--- a/vault-core/src/test/java/org/apache/jackrabbit/vault/fs/io/ArchiveTest.java
+++ b/vault-core/src/test/java/org/apache/jackrabbit/vault/fs/io/ArchiveTest.java
@@ -145,6 +145,7 @@ public class ArchiveTest {
archive.open(true);
Entry root = archive.getRoot();
assertNotNull(root);
+ assertEquals("", root.getName());
assertTrue(root.isDirectory());
MatcherAssert.assertThat(root.getChildren().stream().map(Entry::getName).collect(Collectors.toList()), Matchers.containsInAnyOrder("META-INF", "jcr_root"));
diff --git a/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/FilteredPropertiesIT.java b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/FilteredPropertiesIT.java
index 7c9f173..23190b4 100644
--- a/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/FilteredPropertiesIT.java
+++ b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/FilteredPropertiesIT.java
@@ -17,12 +17,16 @@
package org.apache.jackrabbit.vault.packaging.integration;
+import static org.junit.Assert.assertNotNull;
+
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.Properties;
import javax.jcr.Node;
+import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -33,16 +37,24 @@ import org.apache.jackrabbit.vault.fs.config.DefaultMetaInf;
import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter;
import org.apache.jackrabbit.vault.fs.filter.DefaultPathFilter;
import org.apache.jackrabbit.vault.packaging.ExportOptions;
+import org.apache.jackrabbit.vault.packaging.JcrPackage;
import org.apache.jackrabbit.vault.packaging.PackageException;
import org.apache.jackrabbit.vault.packaging.VaultPackage;
+import org.apache.jackrabbit.vault.util.JcrConstants;
+import org.jetbrains.annotations.NotNull;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
/**
* Covers testing the filtering of properties both during export and import
*/
public class FilteredPropertiesIT extends IntegrationTestBase {
+ @Rule
+ public TemporaryFolder folder= new TemporaryFolder();
+
@Before
public void setUp() throws Exception {
super.setUp();
@@ -449,12 +461,54 @@ public class FilteredPropertiesIT extends IntegrationTestBase {
}
@Test
- public void importWithDifferentFilterThanUsedForExport() {
- // the package itself contains more properties than are supposed to be installed during import
-
+ public void importWithExcludedPropertiesContainedInSerializationNew() throws IOException, PackageException, RepositoryException, ConfigurationException {
+ clean("/testroot2");
+ clean("/testroot3");
+ // the package itself contains more properties than are supposed to be installed during import
+ String filterSrc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+ "<workspaceFilter version=\"1.0\">\n" +
+ " <filter root=\"/testroot3\">\n" +
+ " <exclude pattern=\"/testroot3/jcr:mixinTypes\" matchProperties=\"true\"/>\n" +
+ " <exclude pattern=\"/testroot3/jcr:lastModified.*\" matchProperties=\"true\"/>\n" +
+ " <exclude pattern=\"/testroot3/jcr:title\" matchProperties=\"true\"/>\n" +
+ " <exclude pattern=\"/testroot3/someUnprotectedStringProperty\" matchProperties=\"true\"/>\n" +
+ " </filter>\n" +
+ "</workspaceFilter>";
+
+ DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+ filter.load(new ByteArrayInputStream(filterSrc.getBytes(StandardCharsets.UTF_8)));
+ File tmpFile = folder.newFile();
+ try (VaultPackage pkg = loadVaultPackage("/test-packages/protected_properties.zip")) {
+ try (VaultPackage pkgWithAdjustedFilter = packMgr.rewrap(createExportOptions(filter), pkg, tmpFile)) {
+ try (JcrPackage uploadedPackage = packMgr.upload(tmpFile, false, true, null)) {
+ assertNotNull(uploadedPackage);
+ uploadedPackage.install(getDefaultOptions());
+ admin.save();
+ assertProperty("/testroot3/someUnprotectedStringProperty2", "foo");
+ assertPropertyMissing("/testroot3/jcr:mixinTypes");
+ assertPropertyMissing("/testroot3/someUnprotectedStringProperty");
+ assertPropertyMissing("/testroot3/jcr:title");
+ // some protected properties are never imported, independent of their excludes
+ // assertProperty("/testroot3/someProtectedBooleanProperty");
+
+ // now test update on existing node
+ Node node = admin.getNode("/testroot3");
+ // modify some properties
+ node.addMixin(JcrConstants.MIX_LAST_MODIFIED);
+ node.setProperty(JcrConstants.JCR_TITLE, "title");
+ admin.save();
+ // install again
+ uploadedPackage.install(getDefaultOptions());
+ // make sure excluded properties are not extended or overwritten
+ assertProperty("/testroot3/jcr:mixinTypes", new String[] { JcrConstants.MIX_LAST_MODIFIED } );
+ assertProperty("/testroot3/jcr:title", "title");
+ }
+ }
+ }
}
+
/**
* Setup the path /tmp/foo/bar with properties set at each level
*/
@@ -478,7 +532,11 @@ public class FilteredPropertiesIT extends IntegrationTestBase {
throws IOException, RepositoryException {
File tmpFile = File.createTempFile("vaulttest", ".zip");
+ packMgr.assemble(admin, createExportOptions(filter), tmpFile).close();
+ return tmpFile;
+ }
+ private static @NotNull ExportOptions createExportOptions(WorkspaceFilter filter) {
ExportOptions options = new ExportOptions();
DefaultMetaInf meta = new DefaultMetaInf();
meta.setFilter(filter);
@@ -489,9 +547,7 @@ public class FilteredPropertiesIT extends IntegrationTestBase {
meta.setProperties(props);
options.setMetaInf(meta);
-
- packMgr.assemble(admin, options, tmpFile).close();
- return tmpFile;
+ return options;
}
private void assertPropertiesExist(String rootPath, String... propNames)
diff --git a/vault-core/src/test/resources/test-packages/protected_properties.zip/META-INF/vault/nodetypes.cnd b/vault-core/src/test/resources/test-packages/protected_properties.zip/META-INF/vault/nodetypes.cnd
index 9ac3a81..cd948ef 100644
--- a/vault-core/src/test/resources/test-packages/protected_properties.zip/META-INF/vault/nodetypes.cnd
+++ b/vault-core/src/test/resources/test-packages/protected_properties.zip/META-INF/vault/nodetypes.cnd
@@ -3,6 +3,7 @@
<'vlt'='http://www.day.com/jcr/vault/1.0'>
<'my'='http://jackrabbit.apache.org/filevault/testing'>
+// some operations fail due to residual protected property type (https://issues.apache.org/jira/browse/OAK-9695)
[my:Folder] > nt:hierarchyNode
- * (boolean) protected
- * (string)
diff --git a/vault-core/src/test/resources/test-packages/protected_properties.zip/jcr_root/testroot3/.content.xml b/vault-core/src/test/resources/test-packages/protected_properties.zip/jcr_root/testroot3/.content.xml
new file mode 100644
index 0000000..784039e
--- /dev/null
+++ b/vault-core/src/test/resources/test-packages/protected_properties.zip/jcr_root/testroot3/.content.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:rep="internal" xmlns:my="http://jackrabbit.apache.org/filevault/testing"
+ jcr:primaryType="my:Folder"
+ jcr:mixinTypes="mix:title"
+ jcr:title="myTitle"
+ someProtectedBooleanProperty="{Boolean}true"
+ someProtectedBooleanProperty2="{Boolean}true"
+ someUnprotectedStringProperty="{String}foo"
+ someUnprotectedStringProperty2="{String}foo"
+ >
+</jcr:root>