1+ // Copyright (c) Microsoft Corporation. All rights reserved.
2+ // Licensed under the MIT license.
3+
4+ import { Range , type TextDocument , Uri , workspace } from "vscode" ;
5+ import type { Element } from "domhandler" ;
6+ import { getChildrenByTags , getExactlyOneChildByTag , getTextFromNode , parseDocument , XmlTagName } from "./lexerUtils" ;
7+ import { buildPackageId , normalizePath } from "./utility" ;
8+ import { Dependency } from "./type" ;
9+ import { Upgrade } from "../constants" ;
10+
11+ function getRangeOfNode ( node : Element , vscodeDocument : TextDocument ) : Range | undefined {
12+ if ( ! node . startIndex || ! node . endIndex ) {
13+ return ;
14+ }
15+ return new Range (
16+ vscodeDocument . positionAt ( node . startIndex ) ,
17+ vscodeDocument . positionAt ( node . endIndex + 1 ) ,
18+ )
19+ }
20+
21+ function readDependencyNode ( node : Element , vscodeDocument : TextDocument ) : Dependency | undefined {
22+ const range = getRangeOfNode ( node , vscodeDocument ) ;
23+ if ( ! range ) {
24+ return undefined ;
25+ }
26+ const groupId = getExactlyOneChildByTag ( node , XmlTagName . GroupId ) ;
27+ const artifactId = getExactlyOneChildByTag ( node , XmlTagName . ArtifactId ) ;
28+ const version = getExactlyOneChildByTag ( node , XmlTagName . Version ) ;
29+ if ( ! groupId || ! artifactId ) {
30+ return undefined ;
31+ }
32+ const groupIdText = getTextFromNode ( groupId . children [ 0 ] ) ;
33+ const artifactIdText = getTextFromNode ( artifactId . children [ 0 ] ) ;
34+ const versionText = version ? getTextFromNode ( version . children [ 0 ] ) : undefined ;
35+ return {
36+ packageId : buildPackageId ( groupIdText , artifactIdText ) ,
37+ version : versionText ,
38+ location : range ,
39+ }
40+ }
41+
42+
43+
44+ class PomDataManager {
45+ private pomMap : Record < /* pomPath */ string , Record < string /* packageId */ , Range > > = { } ;
46+
47+ public async parsePom ( pomPath : string ) {
48+ const normalizedPath = normalizePath ( pomPath ) ;
49+ const pomDocument = await workspace . openTextDocument ( Uri . parse ( normalizedPath ) ) ;
50+ const documentText = pomDocument . getText ( ) ;
51+ const xmlDocument = await parseDocument ( documentText ) ;
52+ this . pomMap [ normalizedPath ] = { } ;
53+
54+ const projectNode = getExactlyOneChildByTag ( xmlDocument , XmlTagName . Project ) ;
55+ if ( ! projectNode ) {
56+ return ;
57+ }
58+
59+ const dependenciesNode = getExactlyOneChildByTag ( projectNode , XmlTagName . Dependencies ) ;
60+ const dependencyManagementNode = getExactlyOneChildByTag ( projectNode , XmlTagName . DependencyManagement ) ;
61+ const pomMap : Record < string /* packageId */ , Range > = { } ;
62+
63+ if ( dependencyManagementNode ) {
64+ const deps = getChildrenByTags ( dependencyManagementNode , [ XmlTagName . Dependency ] ) ;
65+ deps . forEach ( ( item ) => {
66+ const dep = readDependencyNode ( item , pomDocument ) ;
67+ if ( dep && ( ! pomMap [ dep . packageId ] || dep . version ) ) {
68+ pomMap [ dep . packageId ] = dep . location ;
69+ }
70+ } )
71+ }
72+ if ( dependenciesNode ) {
73+ const deps = getChildrenByTags ( dependenciesNode , [ XmlTagName . Dependency ] ) ;
74+ deps . forEach ( ( item ) => {
75+ const dep = readDependencyNode ( item , pomDocument ) ;
76+ if ( dep && ( ! pomMap [ dep . packageId ] || dep . version ) ) {
77+ pomMap [ dep . packageId ] = dep . location ;
78+ }
79+ } )
80+ }
81+
82+ const propertiesNode = getExactlyOneChildByTag ( projectNode , XmlTagName . Properties ) ;
83+ if ( propertiesNode ) {
84+ const javaVersionNode = getExactlyOneChildByTag ( propertiesNode , "java.version" ) ;
85+ if ( javaVersionNode ) {
86+ const range = getRangeOfNode ( javaVersionNode , pomDocument ) ;
87+ if ( range ) {
88+ pomMap [ buildPackageId ( Upgrade . DIAGNOSTICS_GROUP_ID_FOR_JAVA_ENGINE , "*" ) ] = range ;
89+ }
90+ }
91+ }
92+
93+ this . pomMap [ normalizedPath ] = pomMap ;
94+ }
95+
96+ public getPomRange ( pomPath : string , packageId : string ) : Range | undefined {
97+ return this . pomMap [ pomPath ] ?. [ packageId ] ;
98+ }
99+
100+
101+ }
102+
103+ const pomDataManager = new PomDataManager ( ) ;
104+ export default pomDataManager ;
0 commit comments