jspurefix
Version:
pure node js fix engine
89 lines (79 loc) • 3.81 kB
text/typescript
import { ContainedGroupField, ContainedSimpleField, ContainedComponentField } from '../../contained'
import { ISaxNode } from '../../dict-primitive'
import { FixDefinitions, GroupFieldDefinition, SimpleFieldDefinition, ComponentFieldDefinition } from '../../definition'
import { ParseContext } from './parse-context'
import { QuickFixXmlFileParser } from './quick-fix-xml-file-parser'
export abstract class NodeParser {
protected readonly parseContexts: ParseContext[] = []
protected readonly definitions: FixDefinitions
protected constructor (public readonly parser: QuickFixXmlFileParser) {
this.definitions = parser.definitions
}
public abstract open (line: number, node: ISaxNode): void
public abstract close (line: number, node: string): void
protected addSimple (node: ISaxNode): void {
if (node.isSelfClosing) {
const parent: ParseContext = this.peek()
if (parent == null) {
throw new Error(`simple field ${node.name} has no parent on which to add.`)
}
const fieldName: string = node.attributes.name
const fieldDefinition: SimpleFieldDefinition = this.definitions.simple.get(fieldName)
if (fieldDefinition == null) {
throw new Error(`simple field ${fieldName} has no declaration in dictionary.`)
}
const containedField: ContainedSimpleField = new ContainedSimpleField(fieldDefinition,
parent.set.fields.length, node.attributes.required === 'Y', false)
parent.set.add(containedField)
}
}
protected addComponentField (componentName: string, node: ISaxNode): void {
const parent: ParseContext = this.peek()
if (parent == null) {
throw new Error(`component ${node.name} has no parent on which to add.`)
}
const fieldDef: ComponentFieldDefinition = this.definitions.component.get(componentName)
if (fieldDef != null) {
const containedField: ContainedComponentField =
new ContainedComponentField(fieldDef, parent.set.fields.length, parent.required)
parent.set.add(containedField)
} else {
if (this.parser.numberPasses >= 4) {
throw new Error(`field ${node.name} includes unknown component ${componentName}.`)
}
}
}
protected addGroupField (name: string): void {
const group: ParseContext = this.parseContexts.pop()
if (group == null) {
throw new Error(`group field ${name} closes yet does not exist.`)
}
const parent: ParseContext = this.peek()
if (parent != null) {
const asGroup: GroupFieldDefinition = group.asGroup()
const containedField: ContainedGroupField =
new ContainedGroupField(asGroup, parent.set.fields.length, group.required)
parent.set.add(containedField)
} else {
throw new Error(`group field ${group.name} has no parent on which to add.`)
}
}
protected beginGroupDefinition (node: ISaxNode): void {
if (!node.isSelfClosing) {
// a group should have a field that matches its name
const groupName: string = node.attributes.name
const noOfField: SimpleFieldDefinition = this.definitions.simple.get(groupName)
if (noOfField == null) {
const msg: string = `group ${groupName} has no field defined.`
throw new Error(msg)
}
const set: GroupFieldDefinition = new GroupFieldDefinition(groupName, groupName, null, noOfField,null)
const context: ParseContext = new ParseContext(node.attributes.name, true, set)
context.required = node.attributes.required === 'Y'
this.parseContexts.push(context)
}
}
private peek (): ParseContext {
return this.parseContexts.length > 0 ? this.parseContexts[this.parseContexts.length - 1] : null
}
}