You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by re...@apache.org on 2021/11/03 19:55:07 UTC

[jackrabbit-filevault] branch master updated: JCRVLT-557 - make default for overwriting node types configurable (OSGi) (#175)

This is an automated email from the ASF dual-hosted git repository.

reschke 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 13e60fb  JCRVLT-557 - make default for overwriting node types configurable (OSGi) (#175)
13e60fb is described below

commit 13e60fb99d7643dbe76900952850a072bcb2b6ef
Author: Julian Reschke <re...@apache.org>
AuthorDate: Wed Nov 3 20:55:00 2021 +0100

    JCRVLT-557 - make default for overwriting node types configurable (OSGi) (#175)
    
    * JCRVLT-577: add sysprop based config for implicite nodetype calculation
    
    * JCRVLT-577: move flag into ImportOptions
    
    * JCRVLT-557: adjust variable/method/prop name as suggested by kwin
    
    * JCRVLT-557: move default into OSGi config
    
    * JCRVLT-557: Javadoc fixes
    
    * JCRVLT-557: remove trailing whitespace
    
    * JCRVLT-557: support new option in PackageTaskOptionsSerializer
---
 .../vault/fs/impl/io/FolderArtifactHandler.java    | 19 ++++++++++++-
 .../jackrabbit/vault/fs/io/ImportOptions.java      | 31 ++++++++++++++++++++--
 .../apache/jackrabbit/vault/fs/io/Importer.java    | 11 ++++++--
 .../jackrabbit/vault/fs/io/package-info.java       |  2 +-
 .../vault/packaging/impl/JcrPackageImpl.java       |  3 ++-
 .../packaging/impl/JcrPackageManagerImpl.java      |  9 ++++---
 .../vault/packaging/impl/PackagingImpl.java        | 13 +++++----
 .../vault/packaging/impl/ZipVaultPackage.java      | 15 ++++++-----
 .../registry/impl/AbstractPackageRegistry.java     |  9 ++++++-
 .../packaging/registry/impl/FSPackageRegistry.java | 16 +++++------
 .../registry/impl/JcrPackageRegistry.java          |  7 ++---
 .../impl/PackageTaskOptionsSerializer.java         |  5 +++-
 .../packaging/integration/PackageInstallIT.java    |  2 +-
 .../impl/ExecutionPlanBuilderImplTest.java         |  3 ++-
 14 files changed, 109 insertions(+), 36 deletions(-)

diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/FolderArtifactHandler.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/FolderArtifactHandler.java
index f64cc0c..7b42180 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/FolderArtifactHandler.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/FolderArtifactHandler.java
@@ -48,6 +48,11 @@ import org.jetbrains.annotations.NotNull;
 public class FolderArtifactHandler extends AbstractArtifactHandler {
 
     /**
+     * whether primary type of folders should be overwritten
+     */
+    private boolean overwritePrimaryTypesOfFolders = true;
+
+    /**
      * qualified names of those default node types which should not be used for intermediate nodes (as they come with too many restrictions)
      */
     private static final List<String> DISALLOWED_PRIMARY_NODE_TYPE_NAMES = Arrays.asList(JcrConstants.NT_BASE, JcrConstants.NT_HIERARCHYNODE);
@@ -73,6 +78,17 @@ public class FolderArtifactHandler extends AbstractArtifactHandler {
         this.nodeType = nodeType;
     }
 
+    /**
+     * Sets whether primary node type of folders should be overwritten
+     *
+     * @param overwritePrimaryTypesOfFolders
+     *            set to "false" to disable the default behavior of overwriting
+     *            the primary node type of folders
+     */
+    public void setOverwritePrimaryTypesOfFolders(boolean overwritePrimaryTypesOfFolders) {
+        this.overwritePrimaryTypesOfFolders = overwritePrimaryTypesOfFolders;
+    }
+
     private Node createIntermediateNode(Node parent, String intermediateNodeName) throws RepositoryException {
         // preferably use default (=primary) node type for intermediate nodes
         Optional<String> defaultPrimaryChildNodeType = EffectiveNodeType.ofNode(parent).getDefaultPrimaryChildNodeTypeName(parent, intermediateNodeName);
@@ -123,7 +139,8 @@ public class FolderArtifactHandler extends AbstractArtifactHandler {
             }
 
             Node node = parent.getNode(dir.getRelativePath());
-            if (wspFilter.contains(node.getPath()) && wspFilter.getImportMode(node.getPath())==ImportMode.REPLACE && !nodeType.equals(node.getPrimaryNodeType().getName())) {
+            if (overwritePrimaryTypesOfFolders
+                    && wspFilter.contains(node.getPath()) && wspFilter.getImportMode(node.getPath()) == ImportMode.REPLACE && !nodeType.equals(node.getPrimaryNodeType().getName())) {
                 modifyPrimaryType(node, info);
             }
             NodeIterator iter = node.getNodes();
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/ImportOptions.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/ImportOptions.java
index 82a6f64..2fa7f53 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/ImportOptions.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/ImportOptions.java
@@ -69,6 +69,8 @@ public class ImportOptions {
 
     private @NotNull IdConflictPolicy idConflictPolicy = IdConflictPolicy.FAIL;
 
+    private Boolean overwritePrimaryTypesOfFolders = null;
+
     /**
      * Default constructor.
      */
@@ -100,6 +102,7 @@ public class ImportOptions {
             pathMapping = base.pathMapping;
             dependencyHandling = base.dependencyHandling;
             idConflictPolicy = base.idConflictPolicy;
+            overwritePrimaryTypesOfFolders = base.overwritePrimaryTypesOfFolders;
         }
     }
 
@@ -126,9 +129,30 @@ public class ImportOptions {
         ret.pathMapping = pathMapping;
         ret.dependencyHandling = dependencyHandling;
         ret.idConflictPolicy = idConflictPolicy;
+        ret.overwritePrimaryTypesOfFolders = overwritePrimaryTypesOfFolders;
         return ret;
     }
 
+    public void setOverwritePrimaryTypesOfFolders(boolean overwritePrimaryTypesOfFolders) {
+        this.overwritePrimaryTypesOfFolders = overwritePrimaryTypesOfFolders;
+    }
+
+    public boolean overwritePrimaryTypesOfFolders() {
+        if (overwritePrimaryTypesOfFolders == null) {
+            return true;
+        } else {
+            return overwritePrimaryTypesOfFolders;
+        }
+    }
+
+    public boolean overwritePrimaryTypesOfFolders(boolean overwritePrimaryTypesOfFoldersByDefault) {
+        if (overwritePrimaryTypesOfFolders == null) {
+            return overwritePrimaryTypesOfFoldersByDefault;
+        } else {
+            return overwritePrimaryTypesOfFolders;
+        }
+    }
+
     public boolean isStrict(boolean isStrictByDefault) {
         if (strict == null) {
             return isStrictByDefault;
@@ -465,6 +489,8 @@ public class ImportOptions {
         result = prime * result + ((pathMapping == null) ? 0 : pathMapping.hashCode());
         result = prime * result + ((idConflictPolicy == null) ? 0 : idConflictPolicy.hashCode());
         result = prime * result + (strict ? 1231 : 1237);
+        result = prime * result + (overwritePrimaryTypesOfFolders ? 1231 : 1237);
+
         return result;
     }
 
@@ -530,6 +556,8 @@ public class ImportOptions {
             return false;
         if (strict != other.strict)
             return false;
+        if (overwritePrimaryTypesOfFolders != other.overwritePrimaryTypesOfFolders)
+            return false;
         if (!idConflictPolicy.equals(other.idConflictPolicy))
             return false;
         return true;
@@ -548,8 +576,7 @@ public class ImportOptions {
                 + (hookClassLoader != null ? "hookClassLoader=" + hookClassLoader + ", " : "")
                 + (pathMapping != null ? "pathMapping=" + pathMapping + ", " : "")
                 + (dependencyHandling != null ? "dependencyHandling=" + dependencyHandling + ", " : "")
+                + "overwritePrimaryTypesOfFolders=" + overwritePrimaryTypesOfFolders + ", "
                 + "idConflictPolicy=" + idConflictPolicy + "]";
     }
-    
-    
 }
\ No newline at end of file
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/Importer.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/Importer.java
index 4777004..776bbee 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/Importer.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/Importer.java
@@ -273,11 +273,12 @@ public class Importer {
      * list of intermediate infos that were removed since the last auto save
      */
     private Map<String, TxInfo> removedIntermediates = new LinkedHashMap<String, TxInfo>();
-    
+
     private final boolean isStrictByDefault;
+    private final boolean overwritePrimaryTypesOfFoldersByDefault;
 
     public Importer() {
-         this(new ImportOptions(), false);
+         this(new ImportOptions(), false, true);
     }
 
     public Importer(ImportOptions opts) {
@@ -285,8 +286,13 @@ public class Importer {
     }
 
     public Importer(ImportOptions opts, boolean isStrictByDefault) {
+        this(opts, isStrictByDefault, true);
+    }
+
+    public Importer(ImportOptions opts, boolean isStrictByDefault, boolean overwritePrimaryTypesOfFoldersByDefault) {
         this.opts = opts;
         this.isStrictByDefault = isStrictByDefault;
+        this.overwritePrimaryTypesOfFoldersByDefault = overwritePrimaryTypesOfFoldersByDefault;
     }
 
     public ImportOptions getOptions() {
@@ -400,6 +406,7 @@ public class Importer {
         genericHandler.setCugHandling(opts.getCugHandling());
         folderHandler.setAcHandling(opts.getAccessControlHandling());
         folderHandler.setCugHandling(opts.getCugHandling());
+        folderHandler.setOverwritePrimaryTypesOfFolders(opts.overwritePrimaryTypesOfFolders(overwritePrimaryTypesOfFoldersByDefault));
 
         filter = opts.getFilter();
         if (filter == null) {
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/package-info.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/package-info.java
index 06a5dbd..2be7b2f 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/package-info.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/package-info.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-@Version("2.11.0")
+@Version("2.12.0")
 package org.apache.jackrabbit.vault.fs.io;
 
 import org.osgi.annotation.versioning.Version;
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageImpl.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageImpl.java
index 3dd99dc..4d5a8b0 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageImpl.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageImpl.java
@@ -386,7 +386,8 @@ public class JcrPackageImpl implements JcrPackage {
             // MAX_VALUE disables saving completely, therefore we have to use a lower value!
             opts.setAutoSaveThreshold(Integer.MAX_VALUE - 1);
         }
-        InstallContextImpl ctx = pack.prepareExtract(node.getSession(), opts, mgr.getSecurityConfig(), mgr.isStrictByDefault());
+        InstallContextImpl ctx = pack.prepareExtract(node.getSession(), opts, mgr.getSecurityConfig(), mgr.isStrictByDefault(),
+                mgr.overwritePrimaryTypesOfFoldersByDefault());
         JcrPackage snap = null;
         if (!opts.isDryRun() && createSnapshot) {
             ExportOptions eOpts = new ExportOptions();
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageManagerImpl.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageManagerImpl.java
index 0096d2b..30e137a 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageManagerImpl.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageManagerImpl.java
@@ -88,15 +88,18 @@ public class JcrPackageManagerImpl extends PackageManagerImpl implements JcrPack
      *
      * @param session repository session
      * @param roots the root paths to store the packages.
-     * @deprecated Use {@link #JcrPackageManagerImpl(Session, String[], String[], String[], boolean)} instead.
+     * @deprecated Use {@link #JcrPackageManagerImpl(Session, String[], String[], String[], boolean, boolean)} instead.
      */
     @Deprecated
     public JcrPackageManagerImpl(@NotNull Session session, @Nullable String[] roots) {
         this(new JcrPackageRegistry(session, roots));
     }
 
-    public JcrPackageManagerImpl(@NotNull Session session, @Nullable String[] roots, @Nullable String[] authIdsForHookExecution, @Nullable String[] authIdsForRootInstallation, boolean isStrict) {
-        this(new JcrPackageRegistry(session, new AbstractPackageRegistry.SecurityConfig(authIdsForHookExecution, authIdsForRootInstallation), isStrict, roots));
+    public JcrPackageManagerImpl(@NotNull Session session, @Nullable String[] roots, @Nullable String[] authIdsForHookExecution,
+            @Nullable String[] authIdsForRootInstallation, boolean isStrict, boolean overwritePrimaryTypesOfFoldersByDefault) {
+        this(new JcrPackageRegistry(session,
+                new AbstractPackageRegistry.SecurityConfig(authIdsForHookExecution, authIdsForRootInstallation), isStrict,
+                overwritePrimaryTypesOfFoldersByDefault, roots));
     }
 
     protected JcrPackageManagerImpl(JcrPackageRegistry registry) {
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackagingImpl.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackagingImpl.java
index 6b1347b..cc1d50e 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackagingImpl.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackagingImpl.java
@@ -94,15 +94,18 @@ public class PackagingImpl implements Packaging {
          */
         @AttributeDefinition(description = "The locations in the repository which are used by the package manager")
         String[] packageRoots() default {"/etc/packages"};
-        
+
         @AttributeDefinition(description = "The authorizable ids or principal names which are allowed to execute hooks (in addition to 'admin', 'administrators' and 'system'")
         String[] authIdsForHookExecution();
-        
+
         @AttributeDefinition(description = "The authorizable ids or principal names which are allowed to install packages with the 'requireRoot' flag (in addition to 'admin', 'administrators' and 'system'")
         String[] authIdsForRootInstallation();
-        
+
         @AttributeDefinition(description = "The default value for strict imports (i.e. whether it just logs certain errors or always throws exceptions")
         boolean isStrict() default true;
+
+        @AttributeDefinition(description = "Whether to overwrite the primary type of folders")
+        boolean overwritePrimaryTypesOfFolders() default true;
     }
 
     @Activate
@@ -123,7 +126,7 @@ public class PackagingImpl implements Packaging {
      * {@inheritDoc}
      */
     public JcrPackageManager getPackageManager(Session session) {
-        JcrPackageManagerImpl mgr = new JcrPackageManagerImpl(session, config.packageRoots(), config.authIdsForHookExecution(), config.authIdsForRootInstallation(), config.isStrict());
+        JcrPackageManagerImpl mgr = new JcrPackageManagerImpl(session, config.packageRoots(), config.authIdsForHookExecution(), config.authIdsForRootInstallation(), config.isStrict(), config.overwritePrimaryTypesOfFolders());
         mgr.setDispatcher(eventDispatcher);
         setBaseRegistry(mgr.getInternalRegistry(), registries);
         return mgr;
@@ -177,7 +180,7 @@ public class PackagingImpl implements Packaging {
     }
 
     private JcrPackageRegistry getJcrPackageRegistry(Session session, boolean useBaseRegistry) {
-        JcrPackageRegistry registry = new JcrPackageRegistry(session, new AbstractPackageRegistry.SecurityConfig(config.authIdsForHookExecution(), config.authIdsForRootInstallation()), config.isStrict(), config.packageRoots());
+        JcrPackageRegistry registry = new JcrPackageRegistry(session, new AbstractPackageRegistry.SecurityConfig(config.authIdsForHookExecution(), config.authIdsForRootInstallation()), config.isStrict(), config.overwritePrimaryTypesOfFolders(), config.packageRoots());
         registry.setDispatcher(eventDispatcher);
         if (useBaseRegistry) {
             setBaseRegistry(registry, registries);
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/ZipVaultPackage.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/ZipVaultPackage.java
index 1d44cab..67fd9c7 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/ZipVaultPackage.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/ZipVaultPackage.java
@@ -162,15 +162,16 @@ public class ZipVaultPackage extends PackagePropertiesImpl implements VaultPacka
      * @throws PackageException if an error during packaging occurs
      * @throws RepositoryException if a repository error during installation occurs.
      */
-    public void extract(Session session, ImportOptions opts, @NotNull AbstractPackageRegistry.SecurityConfig securityConfig, boolean isStrict) throws PackageException, RepositoryException {
-        extract(prepareExtract(session, opts, securityConfig, isStrict), null);
+    public void extract(Session session, ImportOptions opts, @NotNull AbstractPackageRegistry.SecurityConfig securityConfig,
+            boolean isStrict, boolean isOverwritePrimaryTypesOfFolders) throws PackageException, RepositoryException {
+        extract(prepareExtract(session, opts, securityConfig, isStrict, isOverwritePrimaryTypesOfFolders), null);
     }
-    
+
     /**
      * {@inheritDoc}
      */
     public void extract(Session session, ImportOptions opts) throws RepositoryException, PackageException {
-        extract(session, opts, new AbstractPackageRegistry.SecurityConfig(null, null), false);
+        extract(session, opts, new AbstractPackageRegistry.SecurityConfig(null, null), false, true);
     }
 
     /**
@@ -191,7 +192,9 @@ public class ZipVaultPackage extends PackagePropertiesImpl implements VaultPacka
      * @throws IllegalStateException if the package is not valid.
      * @return installation context
      */
-    protected InstallContextImpl prepareExtract(Session session, ImportOptions opts, @NotNull AbstractPackageRegistry.SecurityConfig securityConfig, boolean isStrictByDefault) throws PackageException, RepositoryException {
+    protected InstallContextImpl prepareExtract(Session session, ImportOptions opts,
+            @NotNull AbstractPackageRegistry.SecurityConfig securityConfig, boolean isStrictByDefault,
+            boolean overwritePrimaryTypesOfFoldersByDefault) throws PackageException, RepositoryException {
         if (!isValid()) {
             throw new IllegalStateException("Package not valid.");
         }
@@ -211,7 +214,7 @@ public class ZipVaultPackage extends PackagePropertiesImpl implements VaultPacka
                 opts.setAutoSaveThreshold(Integer.MAX_VALUE - 1);
             }
     
-            Importer importer = new Importer(opts, isStrictByDefault);
+            Importer importer = new Importer(opts, isStrictByDefault, overwritePrimaryTypesOfFoldersByDefault);
             AccessControlHandling ac = getACHandling();
             if (opts.getAccessControlHandling() == null) {
                 opts.setAccessControlHandling(ac);
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/AbstractPackageRegistry.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/AbstractPackageRegistry.java
index 858a9ad..fcc2492 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/AbstractPackageRegistry.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/AbstractPackageRegistry.java
@@ -83,19 +83,26 @@ public abstract class AbstractPackageRegistry implements PackageRegistry, Intern
      */
     private final boolean isStrictByDefault;
 
-    public AbstractPackageRegistry(SecurityConfig securityConfig, boolean isStrictByDefault) {
+    private final boolean overwritePrimaryTypesOfFoldersByDefault;
+
+    public AbstractPackageRegistry(SecurityConfig securityConfig, boolean isStrictByDefault, boolean overwritePrimaryTypesOfFoldersByDefault) {
         if (securityConfig != null) {
             this.securityConfig = securityConfig;
         } else {
             this.securityConfig = new SecurityConfig(null, null);
         }
         this.isStrictByDefault = isStrictByDefault;
+        this.overwritePrimaryTypesOfFoldersByDefault = overwritePrimaryTypesOfFoldersByDefault;
     }
 
     public boolean isStrictByDefault() {
         return isStrictByDefault;
     }
 
+    public boolean overwritePrimaryTypesOfFoldersByDefault() {
+        return overwritePrimaryTypesOfFoldersByDefault;
+    }
+
     /**
      * {@inheritDoc}
      */
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistry.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistry.java
index b78ee6c..27f1e34 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistry.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistry.java
@@ -107,7 +107,7 @@ public class FSPackageRegistry extends AbstractPackageRegistry {
      *
      * @param homeDir the directory in which packages and their metadata is stored
      * @throws IOException If an I/O error occurs.
-     * @deprecated Use {@link #FSPackageRegistry(File, InstallationScope, SecurityConfig, boolean)} instead
+     * @deprecated Use {@link #FSPackageRegistry(File, InstallationScope, SecurityConfig, boolean, boolean)} instead
      */
     @Deprecated
     public FSPackageRegistry(@NotNull File homeDir) throws IOException {
@@ -120,7 +120,7 @@ public class FSPackageRegistry extends AbstractPackageRegistry {
      * @param homeDir the directory in which packages and their metadata is stored
      * @param scope to set a corresponding workspacefilter
      * @throws IOException If an I/O error occurs.
-     * @deprecated Use {@link #FSPackageRegistry(File, InstallationScope, SecurityConfig, boolean)} instead
+     * @deprecated Use {@link #FSPackageRegistry(File, InstallationScope, SecurityConfig, boolean, boolean)} instead
      */
     @Deprecated
     public FSPackageRegistry(@NotNull File homeDir, InstallationScope scope) throws IOException {
@@ -133,15 +133,15 @@ public class FSPackageRegistry extends AbstractPackageRegistry {
      * @param scope
      * @param securityConfig
      * @throws IOException
-     * @deprecated Use {@link #FSPackageRegistry(File, InstallationScope, SecurityConfig, boolean)} instead
+     * @deprecated Use {@link #FSPackageRegistry(File, InstallationScope, SecurityConfig, boolean, boolean)} instead
      */
     @Deprecated
     public FSPackageRegistry(@NotNull File homeDir, InstallationScope scope, @Nullable AbstractPackageRegistry.SecurityConfig securityConfig) throws IOException {
-        this(homeDir, scope, securityConfig, false);
+        this(homeDir, scope, securityConfig, false, true);
     }
 
-    public FSPackageRegistry(@NotNull File homeDir, InstallationScope scope, @Nullable AbstractPackageRegistry.SecurityConfig securityConfig, boolean isStrict) throws IOException {
-        super(securityConfig, isStrict);
+    public FSPackageRegistry(@NotNull File homeDir, InstallationScope scope, @Nullable AbstractPackageRegistry.SecurityConfig securityConfig, boolean isStrict, boolean overwritePrimaryTypesOfFolders) throws IOException {
+        super(securityConfig, isStrict, overwritePrimaryTypesOfFolders);
         log.info("Jackrabbit Filevault FS Package Registry initialized with home location {}", homeDir.getPath());
         this.scope = scope;
         this.stateCache = new FSInstallStateCache(homeDir.toPath());
@@ -152,7 +152,7 @@ public class FSPackageRegistry extends AbstractPackageRegistry {
      * @throws IOException 
      */
     public FSPackageRegistry() throws IOException {
-        super(null, false); // set security config delayed (i.e. only after activate())
+        super(null, false, true); // set security config delayed (i.e. only after activate())
     }
 
     @Activate
@@ -628,7 +628,7 @@ public class FSPackageRegistry extends AbstractPackageRegistry {
                 
             }
             if (vltPkg instanceof ZipVaultPackage) {
-                ((ZipVaultPackage)vltPkg).extract(session, opts, getSecurityConfig(), isStrictByDefault());
+                ((ZipVaultPackage)vltPkg).extract(session, opts, getSecurityConfig(), isStrictByDefault(), overwritePrimaryTypesOfFoldersByDefault());
                 dispatch(PackageEvent.Type.EXTRACT, pkg.getId(), null);
                 stateCache.updatePackageStatus(vltPkg.getId(), FSPackageStatus.EXTRACTED);
             } else {
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/JcrPackageRegistry.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/JcrPackageRegistry.java
index 4100659..897348e 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/JcrPackageRegistry.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/JcrPackageRegistry.java
@@ -117,11 +117,12 @@ public class JcrPackageRegistry extends AbstractPackageRegistry {
      * @param roots the root paths to store the packages.
      */
     public JcrPackageRegistry(@NotNull Session session, @Nullable String ... roots) {
-        this(session, null, false, roots);
+        this(session, null, false, true, roots);
     }
 
-    public JcrPackageRegistry(@NotNull Session session, @Nullable AbstractPackageRegistry.SecurityConfig securityConfig,  boolean isStrict, @Nullable String... roots) {
-        super(securityConfig, isStrict);
+    public JcrPackageRegistry(@NotNull Session session, @Nullable AbstractPackageRegistry.SecurityConfig securityConfig,
+            boolean isStrict, boolean overwritePrimaryTypesOfFoldersByDefault, @Nullable String... roots) {
+        super(securityConfig, isStrict, overwritePrimaryTypesOfFoldersByDefault);
         this.session = session;
         if (roots == null || roots.length == 0) {
             packRootPaths = new String[]{DEFAULT_PACKAGE_ROOT_PATH};
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/PackageTaskOptionsSerializer.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/PackageTaskOptionsSerializer.java
index e6bbe80..d403305 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/PackageTaskOptionsSerializer.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/PackageTaskOptionsSerializer.java
@@ -42,7 +42,8 @@ public class PackageTaskOptionsSerializer {
     private static final String TAG_NON_RECURSIVE = "nonRecursive";
     private static final String TAG_DRY_RUN = "dryRun";
     private static final String TAG_IMPORT_MODE = "importMode";
-    
+    private static final String TAG_OVERWRITE_PRIMARY_TYPES_OF_FOLDERS = "overwritePrimaryTypesOfFolders";
+
     enum Type {
         ImportOptions;
 
@@ -96,6 +97,7 @@ public class PackageTaskOptionsSerializer {
         writeOption(writer, TAG_NON_RECURSIVE, Boolean.class, importOptions.isNonRecursive());
         writeOption(writer, TAG_DRY_RUN, Boolean.class, importOptions.isDryRun());
         writeOption(writer, TAG_IMPORT_MODE, ImportMode.class, importOptions.getImportMode());
+        writeOption(writer, TAG_OVERWRITE_PRIMARY_TYPES_OF_FOLDERS, Boolean.class, importOptions.overwritePrimaryTypesOfFolders());
     }
 
     public ImportOptionsPackageTaskOption loadImportOptions(Element element) {
@@ -108,6 +110,7 @@ public class PackageTaskOptionsSerializer {
         readOption(element, TAG_NON_RECURSIVE, Boolean.class, options::setNonRecursive);
         readOption(element, TAG_DRY_RUN, Boolean.class,  options::setDryRun);
         readOption(element, TAG_IMPORT_MODE, ImportMode.class,  options::setImportMode);
+        readOption(element, TAG_OVERWRITE_PRIMARY_TYPES_OF_FOLDERS, Boolean.class,  options::setOverwritePrimaryTypesOfFolders);
         return new ImportOptionsPackageTaskOption(options);
     }
 
diff --git a/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/PackageInstallIT.java b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/PackageInstallIT.java
index 1f1e6d0..4ae429c 100644
--- a/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/PackageInstallIT.java
+++ b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/PackageInstallIT.java
@@ -291,7 +291,7 @@ public class PackageInstallIT extends IntegrationTestBase {
         
         Session userSession = repository.login(new SimpleCredentials(userId, userPwd.toCharArray()));
         try {
-            packMgr = new JcrPackageManagerImpl(userSession, new String[0], new String[] {"user1"}, null, false);
+            packMgr = new JcrPackageManagerImpl(userSession, new String[0], new String[] {"user1"}, null, false, true);
     
             PackageEventDispatcherImpl dispatcher = new PackageEventDispatcherImpl();
             dispatcher.bindPackageEventListener(new ActivityLog(), Collections.singletonMap("component.id", (Object) "1234"));
diff --git a/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/registry/impl/ExecutionPlanBuilderImplTest.java b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/registry/impl/ExecutionPlanBuilderImplTest.java
index e5a19c1..ea63d14 100644
--- a/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/registry/impl/ExecutionPlanBuilderImplTest.java
+++ b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/registry/impl/ExecutionPlanBuilderImplTest.java
@@ -62,9 +62,10 @@ public class ExecutionPlanBuilderImplTest {
         importOptions.setImportMode(ImportMode.UPDATE);
         importOptions.setDryRun(true);
         importOptions.setNonRecursive(true);
+        importOptions.setOverwritePrimaryTypesOfFolders(true);
         PackageTaskOptions options = new ImportOptionsPackageTaskOption(importOptions);
         builder.addTask().with(MockPackageRegistry.NEW_PACKAGE_ID).withOptions(options).with(PackageTask.Type.INSTALL);
-        
+
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         builder.save(out);
         builder = new ExecutionPlanBuilderImpl(new MockPackageRegistry(MockPackageRegistry.NEW_PACKAGE_ID));