4
4
import { Jdtls } from "../java/jdtls" ;
5
5
import { INodeData , NodeKind } from "../java/nodeData" ;
6
6
import { IPackageRootNodeData , PackageRootKind } from "../java/packageRootNodeData" ;
7
+ import { Settings } from "../settings" ;
8
+ import { Utility } from "../utility" ;
7
9
import { DataNode } from "./dataNode" ;
8
10
import { ExplorerNode } from "./explorerNode" ;
9
11
import { FileNode } from "./fileNode" ;
@@ -14,15 +16,45 @@ import { TypeRootNode } from "./typeRootNode";
14
16
15
17
export class PackageRootNode extends DataNode {
16
18
17
- constructor ( nodeData : INodeData , parent : DataNode , private _project : ProjectNode ) {
19
+ private packageTree : PackageTreeNode ;
20
+
21
+ constructor ( nodeData : INodeData , parent : DataNode , private _project : ProjectNode , packageTree : PackageTreeNode = null ) {
18
22
super ( nodeData , parent ) ;
23
+ this . packageTree = packageTree ;
24
+ }
25
+
26
+ // Get correspond packageRootNode when revealPath
27
+ public getPackageNodeFromNodeData ( classPackage : INodeData ) : PackageRootNode {
28
+ // tslint:disable-next-line:no-this-assignment
29
+ let packageRootNode : PackageRootNode = this ;
30
+ while ( packageRootNode . packageTree === null || packageRootNode . packageTree . fullName !== classPackage . name ) {
31
+ let noMatchPackage : boolean = true ;
32
+ packageRootNode . createChildNodeList ( ) . forEach ( ( child ) => {
33
+ if ( child instanceof PackageRootNode && classPackage . name . startsWith ( child . packageTree . fullName ) ) {
34
+ packageRootNode = child ;
35
+ noMatchPackage = false ;
36
+ }
37
+ } ) ;
38
+ if ( noMatchPackage ) {
39
+ return null ;
40
+ }
41
+ }
42
+ return packageRootNode ;
19
43
}
20
44
21
45
protected loadData ( ) : Thenable < INodeData [ ] > {
22
- return Jdtls . getPackageData ( { kind : NodeKind . PackageRoot , projectUri : this . _project . nodeData . uri , rootPath : this . nodeData . path } ) ;
46
+ if ( this . packageTree && this . packageTree . isPackage ) {
47
+ // load package data
48
+ return Jdtls . getPackageData ( {
49
+ kind : NodeKind . Package , projectUri : this . _project . nodeData . uri , path : this . packageTree . fullName , rootPath : this . nodeData . path ,
50
+ } ) ;
51
+ } else {
52
+ return Jdtls . getPackageData ( { kind : NodeKind . PackageRoot , projectUri : this . _project . nodeData . uri , rootPath : this . nodeData . path } ) ;
53
+ }
54
+
23
55
}
24
56
25
- protected createChildNodeList ( ) : ExplorerNode [ ] {
57
+ protected createFlatChildNodeList ( ) : ExplorerNode [ ] {
26
58
const result = [ ] ;
27
59
if ( this . nodeData . children && this . nodeData . children . length ) {
28
60
this . sort ( ) ;
@@ -41,7 +73,67 @@ export class PackageRootNode extends DataNode {
41
73
return result ;
42
74
}
43
75
76
+ protected createHierarchicalChildNodeList ( ) : ExplorerNode [ ] {
77
+ const result = [ ] ;
78
+ if ( this . nodeData . children && this . nodeData . children . length ) {
79
+ this . nodeData . children . forEach ( ( data ) => {
80
+ if ( data . kind === NodeKind . File ) {
81
+ result . push ( new FileNode ( data , this ) ) ;
82
+ } else if ( data . kind === NodeKind . Folder ) {
83
+ result . push ( new FolderNode ( data , this , this . _project , this ) ) ;
84
+ } else if ( data . kind === NodeKind . TypeRoot ) {
85
+ result . push ( new TypeRootNode ( data , this ) ) ;
86
+ }
87
+ } ) ;
88
+ }
89
+ this . getHierarchicalPackageNodes ( ) . forEach ( ( node ) => result . push ( node ) ) ;
90
+ result . sort ( ) ;
91
+ return result ;
92
+ }
93
+
94
+ protected createChildNodeList ( ) : ExplorerNode [ ] {
95
+ if ( Settings . isHierarchicalView ( ) ) {
96
+ return this . createHierarchicalChildNodeList ( ) ;
97
+ } else {
98
+ return this . createFlatChildNodeList ( ) ;
99
+ }
100
+ }
101
+
102
+ protected getHierarchicalPackageNodes ( ) : ExplorerNode [ ] {
103
+ const result = [ ] ;
104
+ const packageTree = this . packageTree ? this . packageTree : this . getPackageTree ( ) ;
105
+ packageTree . childs . forEach ( ( childNode ) => {
106
+ const childNodeData : INodeData = {
107
+ name : childNode . name ,
108
+ moduleName : this . nodeData . moduleName ,
109
+ path : this . nodeData . path ,
110
+ uri : null ,
111
+ kind : NodeKind . PackageRoot ,
112
+ children : null ,
113
+ } ;
114
+ result . push ( new PackageRootNode ( childNodeData , this , this . _project , childNode ) ) ;
115
+ } ) ;
116
+ return result ;
117
+ }
118
+
119
+ // Generage tree for packages, use for Hierarchical view
120
+ protected getPackageTree ( ) : PackageTreeNode {
121
+ const result : PackageTreeNode = new PackageTreeNode ( "" , "" ) ;
122
+ if ( this . nodeData . children && this . nodeData . children . length ) {
123
+ this . nodeData . children . forEach ( ( child ) => {
124
+ if ( child . kind === NodeKind . Package ) {
125
+ result . addPackage ( child . name ) ;
126
+ }
127
+ } ) ;
128
+ }
129
+ result . compressTree ( ) ;
130
+ return result ;
131
+ }
132
+
44
133
protected get iconPath ( ) : { light : string ; dark : string } {
134
+ if ( this . packageTree !== null ) {
135
+ return ExplorerNode . resolveIconPath ( "package" ) ;
136
+ }
45
137
const data = < IPackageRootNodeData > this . nodeData ;
46
138
if ( data . entryKind === PackageRootKind . K_BINARY ) {
47
139
return ExplorerNode . resolveIconPath ( "jar" ) ;
@@ -50,3 +142,54 @@ export class PackageRootNode extends DataNode {
50
142
}
51
143
}
52
144
}
145
+
146
+ class PackageTreeNode {
147
+ public name : string ;
148
+ public fullName : string ;
149
+ public childs : PackageTreeNode [ ] = [ ] ;
150
+ public isPackage : boolean = false ;
151
+
152
+ constructor ( packageName : string , parentName : string ) {
153
+ const splitPackageName = packageName . split ( "." ) ;
154
+ this . name = splitPackageName [ 0 ] ;
155
+ this . fullName = parentName === "" ? this . name : parentName + "." + this . name ;
156
+ if ( splitPackageName . length > 1 ) {
157
+ this . childs . push ( new PackageTreeNode ( packageName . substring ( this . name . length + 1 ) , this . fullName ) ) ;
158
+ } else {
159
+ this . isPackage = true ;
160
+ }
161
+ }
162
+
163
+ public addPackage ( packageName : string ) : void {
164
+ const splitPackageName = packageName . split ( "." ) ;
165
+ const firstSubName = splitPackageName [ 0 ] ;
166
+ const restname = packageName . substring ( firstSubName . length + 1 ) ;
167
+
168
+ let contains : boolean = false ;
169
+ this . childs . forEach ( ( child ) => {
170
+ if ( child . name === firstSubName ) {
171
+ if ( restname === "" ) {
172
+ child . isPackage = true ;
173
+ } else {
174
+ child . addPackage ( restname ) ;
175
+ }
176
+ contains = true ;
177
+ }
178
+ } ) ;
179
+ if ( ! contains ) {
180
+ this . childs . push ( new PackageTreeNode ( packageName , this . fullName ) ) ;
181
+ }
182
+ }
183
+
184
+ public compressTree ( ) : void {
185
+ // Don't compress the root node
186
+ while ( this . name !== "" && this . childs . length === 1 && ! this . isPackage ) {
187
+ const child = this . childs [ 0 ] ;
188
+ this . fullName = this . fullName + "." + child . name ;
189
+ this . name = this . name + "." + child . name ;
190
+ this . childs = child . childs ;
191
+ this . isPackage = child . isPackage ;
192
+ }
193
+ this . childs . forEach ( ( child ) => child . compressTree ( ) ) ;
194
+ }
195
+ }
0 commit comments