This repository has been archived by the owner on May 8, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
AbstractProcessor.ts
126 lines (114 loc) · 4.8 KB
/
AbstractProcessor.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { ProcessorInterface } from './ProcessorInterface'
import { SockoNodeInterface } from '../nodes/SockoNodeInterface'
import { NeedRootNodeError } from '../errors/NeedRootNodeError'
import { getLogger, Logger } from 'loglevel'
import { SockoNodeType } from '../nodes/SockoNodeType'
import { RootNodeBuilder } from '../builders/RootNodeBuilder'
import { SkippedNodeBuilder } from '../builders/SkippedNodeBuilder'
import { ProcessorOptionsInterface } from '../options/ProcessorOptionsInterface'
import Bluebird = require('bluebird')
import { BranchNodeBuilder } from '../builders/BranchNodeBuilder'
/**
* An abstract implementation of [[ProcessorInterface]].
*/
export abstract class AbstractProcessor<C extends SockoNodeInterface> implements ProcessorInterface {
public process (inputNode: SockoNodeInterface,
hierarchyNode: SockoNodeInterface,
options: ProcessorOptionsInterface): Bluebird<SockoNodeInterface> {
if (!inputNode.isRoot()) {
return Bluebird.reject(new NeedRootNodeError(inputNode))
}
return this._processInternal(inputNode, hierarchyNode, options)
}
/**
* Return the name of this processor (for logging purposes)
* @return {string} the name of this processor
* @private
*/
protected abstract _getProcessorName (): string
/**
* Return the types, that this processor processes
* @return {Array<SockoNodeType>}
* @private
*/
protected abstract _getNeededTypes (): Array<SockoNodeType>
/**
* Return an instance of the logger
* @return {log.Logger} the logger to use
* @private
*/
protected _getLog (): Logger {
return getLogger(`socko-api:${this._getProcessorName()}`)
}
/**
* An abstract method, that is overridden by the processor to process its specific node type and return the
* resulting nodes
* @param {C} inputNode the input tree to process
* @param {SockoNodeInterface} hierarchyNode the hierarchy tree to process
* @param {ProcessorOptionsInterface} options processor options
* @return {Bluebird<SockoNodeInterface>} the assembled nodes
* @private
*/
protected abstract _process (inputNode: C,
hierarchyNode: SockoNodeInterface,
options: ProcessorOptionsInterface): Bluebird<SockoNodeInterface>
/**
* A recursive call to walk through the complete input node, look for node types, that are handled by processors
* and run the processors on it
* @param {SockoNodeInterface} inputNode the input tree
* @param {SockoNodeInterface} hierarchyNode the hierarchy tree
* @param {ProcessorOptionsInterface} options processor options
* @return {Bluebird<SockoNodeInterface>} the assembled nodes
* @private
*/
private _processInternal (inputNode: SockoNodeInterface,
hierarchyNode: SockoNodeInterface,
options: ProcessorOptionsInterface): Bluebird<SockoNodeInterface> {
let processCall: Bluebird<SockoNodeInterface>
this._getLog().debug(`Got node named ${inputNode.name}. Checking...`)
if (this._getNeededTypes().indexOf(inputNode.type) !== -1) {
this._getLog().debug(`Processing...`)
processCall = this._process(inputNode as C, hierarchyNode, options)
} else if (inputNode.type === SockoNodeType.Root) {
this._getLog().debug('Creating root node')
processCall = Bluebird.resolve(new RootNodeBuilder().build())
} else if (inputNode.type === SockoNodeType.Branch) {
this._getLog().debug('Creating branch node')
processCall = Bluebird.resolve(new BranchNodeBuilder().withName(inputNode.name).build())
} else {
this._getLog().debug('Skipping...')
processCall = Bluebird.resolve(new SkippedNodeBuilder().withName(inputNode.name).build())
}
let outputNode: SockoNodeInterface
return processCall
.then(
processedNode => {
outputNode = processedNode
this._getLog().debug('Processing child nodes...')
return Bluebird.reduce<SockoNodeInterface, Array<SockoNodeInterface>>(
inputNode.getChildren() as Array<SockoNodeInterface>,
(total, current) => {
return this._processInternal(current as C, hierarchyNode, options)
.then(
processedChildNode => {
total.push(processedChildNode)
return Bluebird.resolve(total)
}
)
},
[]
)
}
)
.then(
outputNodes => {
this._getLog().debug(`Completed processing child nodes of ${inputNode.name}.`)
for (let childNode of outputNodes) {
outputNode.addChild(childNode)
}
this._getLog().debug(`Completed node ${inputNode.name}`)
return Bluebird.resolve(outputNode)
}
)
}
}