private void handleAuthorizable()

in vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java [744:843]


    private void handleAuthorizable(Node node, DocViewNode2 docViewNode) throws RepositoryException, IOException {
        String id = userManagement.getAuthorizableId(docViewNode);
        String newPath = node.getPath() + "/" + npResolver.getJCRName(docViewNode.getName());
        boolean isIncluded = wspFilter.contains(newPath);
        String oldPath = userManagement.getAuthorizablePath(this.session, id);
        // what to do with policies inside the authorizable node subtree?
        boolean keepAcPolicies = aclHandling == AccessControlHandling.IGNORE || 
                aclHandling == AccessControlHandling.MERGE || 
                aclHandling == AccessControlHandling.MERGE_PRESERVE;
        if (oldPath == null) {
            if (!isIncluded) {
                log.trace("auto-creating authorizable node not in filter {}", newPath);
            }

            // just import the authorizable node
            log.trace("Authorizable element detected. Starting sysview transformation {}", newPath);
            stack = stack.push();
            stack.adapter = new JcrSysViewTransformer(node, wspFilter.getImportMode(newPath), keepAcPolicies);
            stack.adapter.startNode(docViewNode);
            importInfo.onAuthorizableCreated(id);
            return;
        }

        Node authNode = session.getNode(oldPath);
        ImportMode mode = wspFilter.getImportMode(newPath);

        // if existing path is not the same as this, we need to register this so that further
        // nodes down the line (i.e. profiles, policies) are imported at the correct location
        // we only follow existing authorizables for non-REPLACE mode and if ignoring this authorizable node
        // todo: check if this also works cross-aggregates
        if (mode != ImportMode.REPLACE || !isIncluded) {
            importInfo.onRemapped(oldPath, newPath);
        }

        if (!isIncluded) {
            // skip authorizable handling - always follow existing authorizable - regardless of mode
            // todo: we also need to check any rep:Memberlist subnodes. see JCRVLT-69
            stack = stack.push(new StackElement(authNode, false));
            importInfo.onNop(oldPath);
            return;
        }

        switch (mode) {
            case MERGE:
            case MERGE_PROPERTIES:
                // remember desired memberships.
                // todo: how to deal with multi-node memberships? see JCRVLT-69
                Optional<DocViewProperty2> prop = docViewNode.getProperty(NAME_REP_MEMBERS);
                if (prop.isPresent()) {
                    importInfo.registerMemberships(id, prop.get().getStringValues().toArray(new String[0]));
                }

                log.debug("Skipping import of existing authorizable '{}' due to MERGE import mode.", id);
                stack = stack.push(new StackElement(authNode, false));
                importInfo.onNop(newPath);
                break;

            case REPLACE:
                // just replace the entire subtree for now.
                log.trace("Authorizable element detected. starting sysview transformation {}", newPath);
                stack = stack.push();
                // the principal ACLs are automatically restored by the JcrSysViewTransformer (depending on aclHandling)
                stack.adapter = new JcrSysViewTransformer(node, mode, keepAcPolicies);
                stack.adapter.startNode(docViewNode);
                importInfo.onReplaced(oldPath);
                importInfo.onAuthorizableCreated(id);
                break;

            case UPDATE:
            case UPDATE_PROPERTIES:
                log.trace("Authorizable element detected. starting sysview transformation {}", newPath);
                stack = stack.push();
                // the principal ACLs are automatically restored by the JcrSysViewTransformer (depending on aclHandling)
                stack.adapter = new JcrSysViewTransformer(node, oldPath, mode, keepAcPolicies);
                // we need to tweak the ni.name so that the sysview import does not
                // rename the authorizable node name
                String newName = Text.getName(oldPath);
                Collection<DocViewProperty2> properties = new LinkedList<>(docViewNode.getProperties());
                // but we need to augment with a potential rep:authorizableId
                if (authNode.hasProperty("rep:authorizableId")) {
                    DocViewProperty2 authId = new DocViewProperty2(
                            JackrabbitUserManagement.NAME_REP_AUTHORIZABLE_ID,
                            authNode.getProperty("rep:authorizableId").getString(),
                            PropertyType.STRING
                    );
                    properties.removeIf((p) -> p.getName().equals(JackrabbitUserManagement.NAME_REP_AUTHORIZABLE_ID));
                    properties.add(authId);
                }
                
                DocViewNode2 mapped = new DocViewNode2(
                        npResolver.getQName(newName),
                        properties
                );
                
                stack.adapter.startNode(mapped);
                importInfo.onReplaced(oldPath);
                importInfo.onAuthorizableCreated(id);
                break;
        }
    }