-
Notifications
You must be signed in to change notification settings - Fork 308
/
cds-project-mutator.ts
105 lines (93 loc) · 4.83 KB
/
cds-project-mutator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import * as path from 'path';
import { DOMParser } from '@xmldom/xmldom';
/*
* Logic extracted from bolt.module.solution.dll
* Version: 0.4.3
* Class: bolt.module.solution.CdsProjectMutator
*/
export default class CdsProjectMutator {
private _cdsProjectDocument: Document;
private _cdsProject: HTMLElement;
private _cdsNamespace: string;
public get cdsProjectDocument(): Document {
return this._cdsProjectDocument;
}
public constructor(document: string) {
this._cdsProjectDocument = new DOMParser().parseFromString(document, 'text/xml');
this._cdsProject = this._cdsProjectDocument.documentElement;
this._cdsNamespace = this._cdsProject.lookupNamespaceURI('') || '';
}
public addProjectReference(referencedProjectPath: string): void {
if (!this.doesProjectReferenceExists(referencedProjectPath)) {
const projectReferenceElement = this.createProjectReferenceElement(referencedProjectPath);
let projectReferenceItemGroup = this.getProjectReferenceItemGroup();
if (projectReferenceItemGroup) {
this.addProjectReferenceElement(projectReferenceItemGroup, projectReferenceElement);
}
else {
projectReferenceItemGroup = this.createProjectReferenceItemGroup(projectReferenceElement);
this.addProjectReferenceItemGroupElement(projectReferenceItemGroup);
}
}
}
private doesProjectReferenceExists(referencedProjectPath: string): boolean {
return this.getNamedGroups('ItemGroup').some(itemGroup => {
return this.getProjectReferencesFromItemGroup(itemGroup).some(projectReference => {
const projectReferencePath = projectReference.getAttributeNode('Include');
return (projectReferencePath && path.normalize(projectReferencePath.value).toLowerCase() === referencedProjectPath.toLowerCase());
});
});
}
private getNamedGroups(name: string): Element[] {
return Array.from(this._cdsProject.getElementsByTagNameNS(this._cdsNamespace, name));
}
private getProjectReferencesFromItemGroup(itemGroup: Element): Element[] {
return Array.from(itemGroup.getElementsByTagNameNS(this._cdsNamespace, 'ProjectReference'));
}
private getProjectReferenceItemGroup(): Element | null {
const itemGroups = this.getNamedGroups('ItemGroup').filter(itemGroup => this.getProjectReferencesFromItemGroup(itemGroup).length > 0);
return itemGroups.length > 0 ? itemGroups[0] : null;
}
private createProjectReferenceElement(referencedProjectPath: string): Node {
const projectReferenceElement = this._cdsProjectDocument.createElementNS(this._cdsNamespace, 'ProjectReference');
projectReferenceElement.setAttributeNS(this._cdsNamespace, 'Include', referencedProjectPath);
return projectReferenceElement;
}
private createProjectReferenceItemGroup(projectReferenceElement: Node): Element {
const projectReferenceItemGroup = this._cdsProjectDocument.createElementNS(this._cdsNamespace, 'ItemGroup');
projectReferenceItemGroup.appendChild(this._cdsProjectDocument.createTextNode('\n '));
this.addProjectReferenceElement(projectReferenceItemGroup, projectReferenceElement);
return projectReferenceItemGroup;
}
private addProjectReferenceElement(projectReferenceItemGroup: Element, projectReferenceElement: Node): void {
projectReferenceItemGroup.appendChild(this._cdsProjectDocument.createTextNode(' '));
projectReferenceItemGroup.appendChild(projectReferenceElement);
projectReferenceItemGroup.appendChild(this._cdsProjectDocument.createTextNode('\n '));
}
private addProjectReferenceItemGroupElement(projectReferenceItemGroup: Element): void {
const itemGroups = this.getNamedGroups('ItemGroup');
if (itemGroups.length > 0) {
this._cdsProject.insertBefore(projectReferenceItemGroup, itemGroups[itemGroups.length - 1].nextSibling);
this._cdsProject.insertBefore(this._cdsProjectDocument.createTextNode('\n\n '), projectReferenceItemGroup);
}
else {
const propertyGroups = this.getNamedGroups('PropertyGroup');
if (propertyGroups.length > 0) {
this._cdsProject.insertBefore(projectReferenceItemGroup, propertyGroups[propertyGroups.length - 1].nextSibling);
this._cdsProject.insertBefore(this._cdsProjectDocument.createTextNode('\n\n '), projectReferenceItemGroup);
}
else {
const importGroups = this.getNamedGroups('Import');
if (importGroups.length > 0) {
this._cdsProject.insertBefore(projectReferenceItemGroup, importGroups[0].nextSibling);
this._cdsProject.insertBefore(this._cdsProjectDocument.createTextNode('\n\n '), projectReferenceItemGroup);
}
else {
this._cdsProject.appendChild(this._cdsProjectDocument.createTextNode('\n '));
this._cdsProject.appendChild(projectReferenceItemGroup);
this._cdsProject.appendChild(this._cdsProjectDocument.createTextNode('\n'));
}
}
}
}
}