function getTreeTransformer()

in guacamole/src/main/frontend/src/app/import/services/connectionParseService.js [223:369]


    function getTreeTransformer(importConfig) {

        // A map of group path with connection name, to connection object, used
        // for detecting duplicate connections within the import file itself
        const connectionsInFile = {};

        return getTreeLookups().then(treeLookups => connection => {

            const { groupPathsByIdentifier, groupIdentifiersByPath,
                    connectionIdsByGroupAndName } = treeLookups;

            const providedIdentifier = connection.parentIdentifier;

            // The normalized group path for this connection, of the form
            // "ROOT/parent/child"
            let group;
            
            // The identifier for the parent group of this connection
            let parentIdentifier;
            
            // The operator to apply for this connection
            let op = DirectoryPatch.Operation.ADD;

            // If both are specified, the parent group is ambigious
            if (providedIdentifier && connection.group) {
                connection.errors.push(new ParseError({
                    message: 'Only one of group or parentIdentifier can be set',
                    key: 'IMPORT.ERROR_AMBIGUOUS_PARENT_GROUP'
                }));
                return connection;
            }

            // If a parent group identifier is present, but not valid
            else if (providedIdentifier
                    && !groupPathsByIdentifier[providedIdentifier]) {
                connection.errors.push(new ParseError({
                    message: 'No group with identifier: ' + providedIdentifier,
                    key: 'IMPORT.ERROR_INVALID_GROUP_IDENTIFIER',
                    variables: { IDENTIFIER: providedIdentifier }
                }));
                return connection;
            }

            // If the parent identifier is valid, use it to determine the path
            else if (providedIdentifier) {
                parentIdentifier = providedIdentifier;
                group = groupPathsByIdentifier[providedIdentifier];
            }

            // If a user-supplied group path is provided, attempt to normalize
            // and match it to an existing connection group
            else if (connection.group) {

                // The group path extracted from the user-provided connection,
                // to be translated into an absolute path starting at the root
                group = connection.group;

                // If the provided group isn't a string, it can never be valid
                if (typeof group !== 'string') {
                    connection.errors.push(new ParseError({
                        message: 'Invalid group type - must be a string',
                        key: 'IMPORT.ERROR_INVALID_GROUP_TYPE'
                    }));
                    return connection;
                }

                // Allow the group to start with a leading slash instead instead
                // of explicitly requiring the root connection group
                if (group.startsWith('/'))
                    group = ROOT_GROUP_IDENTIFIER + group;

                // Allow groups to begin directly with the path under the root
                else if (!group.startsWith(ROOT_GROUP_IDENTIFIER))
                    group = ROOT_GROUP_IDENTIFIER + '/' + group;

                // Allow groups to end with a trailing slash
                if (group.endsWith('/'))
                    group = group.slice(0, -1);

                // Look up the parent identifier for the specified group path
                parentIdentifier = groupPathsByIdentifier[group];

                // If the group doesn't match anything in the tree
                if (!parentIdentifier) {
                    connection.errors.push(new ParseError({
                        message: 'No group found named: ' + connection.group,
                        key: 'IMPORT.ERROR_INVALID_GROUP',
                        variables: { GROUP: connection.group }
                    }));
                    return connection;
                }

            }

            // If no group is specified at all, default to the root group
            else {
                parentIdentifier = ROOT_GROUP_IDENTIFIER;
                group = ROOT_GROUP_IDENTIFIER;
            }

            // The full path, of the form "ROOT/Child Group/Connection Name"
            const path = group + '/' + connection.name;

            // Error out if this is a duplicate of a connection already in the
            // file
            if (!!_.get(connectionsInFile, path)) 
                connection.errors.push(new ParseError({
                    message: 'Duplicate connection in file: ' + path,
                    key: 'IMPORT.ERROR_DUPLICATE_CONNECTION_IN_FILE',
                    variables: { NAME: connection.name, PATH: group }
                }));

            // Mark the current path as already seen in the file
            _.setWith(connectionsInFile, path, connection, Object);

            // Check if this would be an update to an existing connection
            const existingIdentifier = _.get(connectionIdsByGroupAndName,
                    [parentIdentifier, connection.name]);

            // The default behavior is to create connections if no conflict
            let importMode = ImportConnection.ImportMode.CREATE;
            let identifier;

            // If updates to existing connections are disallowed
            if (existingIdentifier && importConfig.existingConnectionMode ===
                    ConnectionImportConfig.ExistingConnectionMode.REJECT)
                connection.errors.push(new ParseError({
                    message: 'Rejecting update to existing connection: ' + path,
                    key: 'IMPORT.ERROR_REJECT_UPDATE_CONNECTION',
                    variables: { NAME: connection.name, PATH: group }
                }));

            // If the connection is being replaced, set the existing identifer
            else if (existingIdentifier) {
                identifier = existingIdentifier;
                importMode = ImportConnection.ImportMode.REPLACE;
            }

            else
                importMode = ImportConnection.ImportMode.CREATE;

            // Set the import mode, normalized path, and validated identifier
            return new ImportConnection({ ...connection, 
                    importMode, group, identifier, parentIdentifier });

        });
    }