async function insertDependencyManagement()

in src/handlers/setDependencyVersionHandler.ts [89:156]


async function insertDependencyManagement(pomPath: string, targetNode: ElementNode, deleteNode: ElementNode | undefined, gid: string, aid: string, version: string): Promise<void> {
    if (targetNode.contentStart === undefined || targetNode.contentEnd === undefined) {
        throw new UserError("Invalid target XML node to insert dependency management.");
    }
    const currentDocument: vscode.TextDocument = await vscode.workspace.openTextDocument(pomPath);
    const textEditor: vscode.TextEditor = await vscode.window.showTextDocument(currentDocument);
    const baseIndent: string = getIndentation(currentDocument, targetNode.contentEnd);
    const options: vscode.TextEditorOptions = textEditor.options;
    const indent: string = options.insertSpaces && typeof options.tabSize === "number" ? " ".repeat(options.tabSize) : "\t";
    const eol: string = currentDocument.eol === vscode.EndOfLine.LF ? "\n" : "\r\n";

    let insertPosition: vscode.Position | undefined;
    let targetText: string;
    let dependencyNodeInManagement: ElementNode | undefined;
    const dependenciesNode: ElementNode | undefined = targetNode?.children?.find(node => node.tag === XmlTagName.Dependencies);

    if (targetNode.tag === XmlTagName.DependencyManagement && dependenciesNode !== undefined) {
        if (dependenciesNode.contentStart === undefined || dependenciesNode.contentEnd === undefined) {
            throw new UserError("Invalid target XML node to insert dependency management.");
        }
        insertPosition = currentDocument.positionAt(dependenciesNode.contentStart);
        // find ${gid:aid} dependency node that already in dependency management to delete
        dependencyNodeInManagement = dependenciesNode.children?.find(node =>
            node.children?.find(id => id.tag === XmlTagName.GroupId && id.text === gid) &&
            node.children?.find(id => id.tag === XmlTagName.ArtifactId && id.text === aid)
        );
        const newIndent: string = `${baseIndent}${indent}`;
        targetText = constructDependencyNode({ gid, aid, version, baseIndent: newIndent, indent, eol });
    } else if (targetNode.tag === XmlTagName.DependencyManagement && dependenciesNode === undefined) {
        insertPosition = currentDocument.positionAt(targetNode.contentStart);
        targetText = constructDependenciesNode({ gid, aid, version, baseIndent, indent, eol });
    } else if (targetNode.tag === XmlTagName.Project) {
        insertPosition = currentDocument.positionAt(targetNode.contentEnd);
        targetText = constructDependencyManagementNode({ gid, aid, version, baseIndent, indent, eol });
    } else {
        return;
    }

    const edit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit();
    if (deleteNode) { // the version of ${gid:aid} dependency node already imported should be deleted
        const versionItem: ElementNode | undefined = deleteNode.children?.find(node => node.tag === XmlTagName.Version);
        if (versionItem) {
            if (versionItem.contentStart === undefined || versionItem.contentEnd === undefined) {
                throw new UserError("Invalid target XML node to delete.");
            }
            const versionString: string = "<version>";
            const start: number = versionItem.contentStart - versionString.length;
            const end: number = versionItem.contentEnd + versionString.length + 1;
            const range = new vscode.Range(currentDocument.positionAt(start), currentDocument.positionAt(end));
            edit.delete(currentDocument.uri, range);
        }
    }
    if (dependencyNodeInManagement) { // ${gid:aid} dependency node that already exists in <dependencyManagement> shoule be deleted
        if (dependencyNodeInManagement.contentStart === undefined || dependencyNodeInManagement.contentEnd === undefined) {
            throw new UserError("Invalid target XML node to delete.");
        }
        const dependencyString: string = "<dependency>";
        const start = dependencyNodeInManagement.contentStart - dependencyString.length;
        const end = dependencyNodeInManagement.contentEnd + dependencyString.length + 1;
        const range = new vscode.Range(currentDocument.positionAt(start), currentDocument.positionAt(end));
        edit.delete(currentDocument.uri, range);
    }

    edit.insert(currentDocument.uri, insertPosition, targetText);
    await vscode.workspace.applyEdit(edit);
    const endingPosition: vscode.Position = currentDocument.positionAt(currentDocument.offsetAt(insertPosition) + targetText.length);
    textEditor.revealRange(new vscode.Range(insertPosition, endingPosition));
}