From 3b313e3d3cbfce03bca25da66156226d5b7eef49 Mon Sep 17 00:00:00 2001 From: Patrick Boyd Date: Thu, 28 Feb 2019 16:49:30 -0600 Subject: [PATCH 1/3] Reduce Code Complexity --- lib/Action.js | 23 ++--- lib/ActionImport.js | 20 ++-- lib/AnnotatedObject.js | 13 +++ lib/Annotation.js | 27 +++--- lib/CSDLSearch.js | 93 +++++++++--------- lib/Collection.js | 14 ++- lib/ComplexType.js | 27 +++--- lib/EntityContainer.js | 21 ++-- lib/EntitySet.js | 20 ++-- lib/EntityType.js | 28 +++--- lib/EnumType.js | 27 +++--- lib/Function.js | 24 +---- lib/FunctionImport.js | 22 ++--- lib/Metadata.js | 6 +- lib/NavigationProperty.js | 29 +++--- lib/NavigationPropertyBinding.js | 10 +- lib/Parameter.js | 33 +++---- lib/ParserCommon.js | 162 +++++++++++++++++++------------ lib/Property.js | 27 +----- lib/PropertyValue.js | 28 +++--- lib/Record.js | 17 +--- lib/Reference.js | 22 ++--- lib/ReturnType.js | 12 +-- lib/Schema.js | 37 +++---- lib/Singleton.js | 19 ++-- lib/Term.js | 39 +++----- lib/TypeDefinition.js | 29 +++--- test/corner.js | 2 +- test/negative.js | 6 +- test/search.js | 7 +- 30 files changed, 379 insertions(+), 465 deletions(-) create mode 100644 lib/AnnotatedObject.js diff --git a/lib/Action.js b/lib/Action.js index 05c262f..3571476 100644 --- a/lib/Action.js +++ b/lib/Action.js @@ -1,23 +1,18 @@ -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); -class Action extends ParserCommon { - constructor(element) { +class Action extends AnnotatedObject { + constructor() { super(); - this.Annotations = {}; this.Parameters = {}; this.ReturnType = null; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'Parameter': {parent: this.Parameters, nameProp: 'Name'}, - 'ReturnType': {name: 'ReturnType'} - }; - this.validAttributes = { - 'IsBound': {bool: true}, - 'Name': {alreadyHandeled: true} - }; + this.addElementHandler('Parameter', this.addElementToObj, {parent: this.Parameters, nameProp: 'Name'}); + this.addElementHandler('ReturnType', this.addElementToObj, {name: 'ReturnType'}); - this.init(element, 'Name'); + this.addAttributeHandler('IsBound', this.addBoolAttributeToObj, {}); + this.addAttributeHandler('Name', null, {}); + + this.nameAttr = 'Name'; } } diff --git a/lib/ActionImport.js b/lib/ActionImport.js index e6234e2..ed104d2 100644 --- a/lib/ActionImport.js +++ b/lib/ActionImport.js @@ -1,19 +1,13 @@ -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); -class ActionImport extends ParserCommon { - constructor(element) { +class ActionImport extends AnnotatedObject { + constructor() { super(); - this.Annotations = {}; + this.addAttributeHandler('Action', this.addAttributeToObj, {}); + this.addAttributeHandler('EntitySet', this.addAttributeToObj, {}); + this.addAttributeHandler('Name', null, {}); - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - }; - this.validAttributes = { - 'Action': {}, - 'EntitySet': {}, - 'Name': {alreadyHandeled: true} - }; - this.init(element, 'Name'); + this.nameAttr = 'Name'; } } diff --git a/lib/AnnotatedObject.js b/lib/AnnotatedObject.js new file mode 100644 index 0000000..78ca3e6 --- /dev/null +++ b/lib/AnnotatedObject.js @@ -0,0 +1,13 @@ +const ParserCommon = require('./ParserCommon'); + +class AnnotatedObject extends ParserCommon { + constructor() { + super(); + this.Annotations = {}; + + this.addElementHandler('Annotation', this.addElementToObj, {parent: this.Annotations, nameProp: 'Term'}); + } +} + +module.exports = AnnotatedObject; +/* vim: set tabstop=2 shiftwidth=2 expandtab: */ diff --git a/lib/Annotation.js b/lib/Annotation.js index 36d0a95..ed60816 100644 --- a/lib/Annotation.js +++ b/lib/Annotation.js @@ -1,22 +1,19 @@ const ParserCommon = require('./ParserCommon'); class Annotation extends ParserCommon { - constructor(element) { + constructor() { super(); - this.validElements = { - 'Collection': {parent: this, name: 'Collection'}, - 'Record': {parent: this, name: 'Record'}, - 'String': {parent: this, name: 'String', getText: true} - }; - this.validAttributes = { - 'Term': {alreadyHandeled: true}, - 'Qualifier': {}, - 'String': {}, - 'EnumMember': {}, - 'Bool': {bool: true}, - 'Int': {integer: true} - }; - this.init(element, 'Term'); + this.addElementHandler('Collection', this.addElementToObj, {name: 'Collection'}); + this.addElementHandler('Record', this.addElementToObj, {name: 'Record'}); + this.addElementHandler('String', this.addStringToObj, {name: 'String'}); + + this.addAttributeHandler('Term', null, {}); + this.addAttributeHandler('Qualifier', this.addAttributeToObj, {}); + this.addAttributeHandler('String', this.addAttributeToObj, {}); + this.addAttributeHandler('EnumMember', this.addAttributeToObj, {}); + this.addAttributeHandler('Bool', this.addBoolAttributeToObj, {}); + this.addAttributeHandler('Int', this.addIntAttributeToObj, {}); + this.nameAttr = 'Term'; } } diff --git a/lib/CSDLSearch.js b/lib/CSDLSearch.js index 2629258..31f8060 100644 --- a/lib/CSDLSearch.js +++ b/lib/CSDLSearch.js @@ -43,35 +43,38 @@ function searchCSDL(root, elementType, elementName, includeReferences) { if(key[0] === '_') { continue; } - else if(key === 'Annotations') { + ret = ret.concat(searchElementPart(key, root[key], elementType, elementName, includeReferences)); + } + return ret; +} + +function searchElementPart(key, element, elementType, elementName, includeReferences) { + let ret = []; + switch(key) { + case 'Annotations': if(elementType === 'Annotation') { - ret = ret.concat(searchAnnotation(root.Annotations, elementName)); + return searchAnnotation(element, elementName); } - continue; - } - else if(key === 'References' && includeReferences !== true) { - continue; - } - var element = root[key]; - if(elementInvalid(element)) { - continue; - } - if(elementType !== undefined) { - if(elementType === element.constructor.name) { + return ret; + case 'References': + if(includeReferences !== true) { + return ret; + } + //Deliberate fallthrough... + default: + if(elementInvalid(element)) { + return ret; + } + if(elementType === undefined) { pushIfNotUndefined(ret, getElementIfNameEqual(element, elementName)); + return ret; } - else { - var tmp = searchCSDL(element, elementType, elementName); - if(tmp.length > 0) { - ret = ret.concat(tmp); - } + if(elementType === element.constructor.name) { + pushIfNotUndefined(ret, getElementIfNameEqual(element, elementName)); + return ret; } - } - else { - pushIfNotUndefined(ret, getElementIfNameEqual(element, elementName)); - } + return searchCSDL(element, elementType, elementName); } - return ret; } function remapNamespace(references, namespace) { @@ -95,34 +98,34 @@ function findByType(metadata, typeName) { var justType = typeName.substring(index+1); var schema = metadata[namespace]; if(schema === undefined) { - let schemas = metadata._options.cache.getSchemas(namespace); - if(schemas.length === 0) { - if(metadata.References === undefined) { - return null; - } - namespace = remapNamespace(metadata.References, namespace); - if(namespace !== undefined) { - schema = metadata._options.cache.getSchema(namespace); - } - else { - return null; - } - } - else if(schemas.length === 1) { - schema = schemas[0]; - } - else { - for(let i = 0; i < schemas.length; i++) { - if(schemas[i][justType] !== undefined) { - return schemas[i][justType]; - } - } + schema = findSchema(metadata, namespace, justType); + if(schema === undefined) { return null; } } return schema[justType]; } +function findSchema(metadata, namespace, justType) { + let schemas = metadata._options.cache.getSchemas(namespace); + if(schemas.length === 0) { + if(metadata.References === undefined) { + return undefined; + } + namespace = remapNamespace(metadata.References, namespace); + if(namespace !== undefined) { + return findSchema(metadata, namespace, justType); + } + return undefined; + } + for(let i = 0; i < schemas.length; i++) { + if(schemas[i][justType] !== undefined) { + return schemas[i]; + } + } + return undefined; +} + module.exports.search = searchCSDL; module.exports.findByType = findByType; /* vim: set tabstop=2 shiftwidth=2 expandtab: */ diff --git a/lib/Collection.js b/lib/Collection.js index fff460f..a7971c7 100644 --- a/lib/Collection.js +++ b/lib/Collection.js @@ -1,20 +1,18 @@ const ParserCommon = require('./ParserCommon'); class Collection extends ParserCommon { - constructor(element) { + constructor() { super(); this.PropertyPaths = []; this.Records = []; this.Strings = []; - this.validElements = { - 'PropertyPath': {parent: this.PropertyPaths, getText: true}, - 'Record': {parent: this.Records}, - 'String': {parent: this.Strings, passthru: true} - }; - - this.init(element); + this.addElementHandler('PropertyPath', this.addStringToArray, {parent: this.PropertyPaths}); + this.addElementHandler('String', this.addStringToArray, {parent: this.Strings}); + this.addElementHandler('Record', this.addElementToArray, {parent: this.Records}); + } + postInitCleanup() { if(this.PropertyPaths.length === 0) { delete this.PropertyPaths; } diff --git a/lib/ComplexType.js b/lib/ComplexType.js index 7b00d9e..592aad1 100644 --- a/lib/ComplexType.js +++ b/lib/ComplexType.js @@ -1,25 +1,20 @@ -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); -class ComplexType extends ParserCommon { - constructor(element) { +class ComplexType extends AnnotatedObject { + constructor() { super(); this.Properties = {}; - this.Annotations = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'Property': {parent: this.Properties, nameProp: 'Name'}, - 'NavigationProperty': {parent: this.Properties, nameProp: 'Name'} - }; - this.validAttributes = { - 'Abstract': {bool: true}, - 'OpenType': {bool: true}, - 'BaseType': {}, - 'Name': {alreadyHandeled: true} - }; + this.addElementHandler('Property', this.addElementToObj, {parent: this.Properties, nameProp: 'Name'}); + this.addElementHandler('NavigationProperty', this.addElementToObj, {parent: this.Properties, nameProp: 'Name'}); - this.init(element, 'Name'); + this.addAttributeHandler('Abstract', this.addBoolAttributeToObj, {}); + this.addAttributeHandler('OpenType', this.addBoolAttributeToObj, {}); + this.addAttributeHandler('Name', null, {}); + this.addAttributeHandler('BaseType', this.addAttributeToObj, {}); + + this.nameAttr = 'Name'; } } diff --git a/lib/EntityContainer.js b/lib/EntityContainer.js index 312501f..f0520e1 100644 --- a/lib/EntityContainer.js +++ b/lib/EntityContainer.js @@ -1,21 +1,16 @@ const ParserCommon = require('./ParserCommon'); class EntityContainer extends ParserCommon { - constructor(element) { + constructor() { super(); + this.addElementHandler('EntitySet', this.addElementToObj, {nameProp: 'Name'}); + this.addElementHandler('Singleton', this.addElementToObj, {nameProp: 'Name'}); + this.addElementHandler('ActionImport', this.addElementToObj, {nameProp: 'Name'}); + this.addElementHandler('FunctionImport', this.addElementToObj, {nameProp: 'Name'}); - this.validElements = { - 'EntitySet': {parent: this, nameProp: 'Name'}, - 'Singleton': {parent: this, nameProp: 'Name'}, - 'ActionImport': {parent: this, nameProp: 'Name'}, - 'FunctionImport': {parent: this, nameProp: 'Name'} - }; - this.validAttributes = { - 'Extends': {}, - 'Name': {alreadyHandeled: true} - }; - - this.init(element, 'Name'); + this.addAttributeHandler('Name', null, {}); + this.addAttributeHandler('Extends', this.addAttributeToObj, {}); + this.nameAttr = 'Name'; } } diff --git a/lib/EntitySet.js b/lib/EntitySet.js index f71eb38..ac336b3 100644 --- a/lib/EntitySet.js +++ b/lib/EntitySet.js @@ -1,21 +1,15 @@ -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); -class EntitySet extends ParserCommon { - constructor(element) { +class EntitySet extends AnnotatedObject { + constructor() { super(); - this.Annotations = {}; this.NaviagtionPropertyBindings = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'NavigationPropertyBinding': {parent: this.NaviagtionPropertyBindings, nameProp: 'Path'} - }; - this.validAttributes = { - 'EntityType': {}, - 'Name': {alreadyHandeled: true} - }; + this.addElementHandler('NavigationPropertyBinding', this.addElementToObj, {parent: this.NaviagtionPropertyBindings, nameProp: 'Path'}); - this.init(element, 'Name'); + this.addAttributeHandler('Name', null, {}); + this.addAttributeHandler('EntityType', this.addAttributeToObj, {}); + this.nameAttr = 'Name'; } } diff --git a/lib/EntityType.js b/lib/EntityType.js index b565c8a..229d6be 100644 --- a/lib/EntityType.js +++ b/lib/EntityType.js @@ -1,27 +1,23 @@ -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); -class EntityType extends ParserCommon { - constructor(element) { +class EntityType extends AnnotatedObject { + constructor() { super(); this._key = null; - this.Annotations = {}; this.Properties = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'Property': {parent: this.Properties, nameProp: 'Name'}, - 'NavigationProperty': {parent: this.Properties, nameProp: 'Name'}, - 'Key': {parent: this, name: '_key', passthru: true} - }; - this.validAttributes = { - 'Abstract': {bool: true}, - 'BaseType': {}, - 'Name': {alreadyHandeled: true} - }; + this.addElementHandler('Property', this.addElementToObj, {parent: this.Properties, nameProp: 'Name'}); + this.addElementHandler('NavigationProperty', this.addElementToObj, {parent: this.Properties, nameProp: 'Name'}); + this.addElementHandler('Key', this.addXMLToObj, {name: '_key'}); - this.init(element, 'Name'); + this.addAttributeHandler('Abstract', this.addBoolAttributeToObj, {}); + this.addAttributeHandler('BaseType', this.addAttributeToObj, {}); + this.addAttributeHandler('Name', null, {}); + this.nameAttr = 'Name'; + } + postInitCleanup() { if(this._key !== null) { let propRefs = this._key.childrenNamed('PropertyRef'); for(let i = 0; i < propRefs.length; i++) { diff --git a/lib/EnumType.js b/lib/EnumType.js index 1e460b7..bed1815 100644 --- a/lib/EnumType.js +++ b/lib/EnumType.js @@ -1,27 +1,23 @@ -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); const Annotation = require('./Annotation'); -class EnumType extends ParserCommon { - constructor(element) { +class EnumType extends AnnotatedObject { + constructor() { super(); this._index = 0; this.Members = {}; - this.Annotations = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'Member': {parent: this.Parameters, helperFunc: this.memberHelper.bind(this)} - }; - this.validAttributes = { - 'IsFlags': {bool: true}, - 'Name': {alreadyHandeled: true} - }; + this.addAttributeHandler('Name', null, {}); + this.addAttributeHandler('IsFlags', this.addBoolAttributeToObj, {}); + + this.addElementHandler('Member', this.addMember, {}); + + this.nameAttr = 'Name'; - this.init(element, 'Name'); delete this._index; } - memberHelper(element) { + addMember(element, data) { let name = element.attr['Name']; let value = element.attr['Value']; this.Members[name] = {}; @@ -35,7 +31,8 @@ class EnumType extends ParserCommon { let me = this; element.eachChild(function(child, index, array) { if(child.name === 'Annotation') { - let annotation = new Annotation(child); + let annotation = new Annotation(); + annotation.init(child); if(me.Members[name].Annotations === undefined) { me.Members[name].Annotations = {}; } diff --git a/lib/Function.js b/lib/Function.js index 35766ca..9af2d5e 100644 --- a/lib/Function.js +++ b/lib/Function.js @@ -1,25 +1,11 @@ -const ParserCommon = require('./ParserCommon'); +const Action = require('./Action'); -class Function extends ParserCommon { - constructor(element) { +class Function extends Action { + constructor() { super(); - this.Annotations = {}; - this.Parameters = {}; - this.ReturnType = null; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'Parameter': {parent: this.Parameters, nameProp: 'Name'}, - 'ReturnType': {name: 'ReturnType'} - }; - this.validAttributes = { - 'IsBound': {bool: true}, - 'IsComposable': {bool: true}, - 'EntitySetPath': {}, - 'Name': {alreadyHandeled: true} - }; - - this.init(element, 'Name'); + this.addAttributeHandler('IsComposable', this.addBoolAttributeToObj, {}); + this.addAttributeHandler('EntitySetPath', this.addAttributeToObj, {}); } } diff --git a/lib/FunctionImport.js b/lib/FunctionImport.js index a3491b1..7155654 100644 --- a/lib/FunctionImport.js +++ b/lib/FunctionImport.js @@ -1,20 +1,14 @@ -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); -class FunctionImport extends ParserCommon { - constructor(element) { +class FunctionImport extends AnnotatedObject { + constructor() { super(); - this.Annotations = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - }; - this.validAttributes = { - 'IncludeInServiceDocument': {bool: true}, - 'EntitySet': {}, - 'Function': {}, - 'Name': {alreadyHandeled: true} - }; - this.init(element, 'Name'); + this.addAttributeHandler('Name', null, {}); + this.addAttributeHandler('EntitySet', this.addAttributeToObj, {}); + this.addAttributeHandler('Function', this.addAttributeToObj, {}); + this.addAttributeHandler('IncludeInServiceDocument', this.addBoolAttributeToObj, {}); + this.nameAttr = 'Name'; } } diff --git a/lib/Metadata.js b/lib/Metadata.js index 2de874a..024c846 100644 --- a/lib/Metadata.js +++ b/lib/Metadata.js @@ -43,7 +43,8 @@ class Metadata { switch(elemName) { case 'Reference': case 'edmx:Reference': - let ref = new Reference(child); + let ref = new Reference(); + ref.init(child); arr.push(ref.bind(me._options.cache)); me.References.push(ref); break; @@ -71,7 +72,8 @@ class Metadata { switch(elemName) { case 'Schema': let namespace = child.attr['Namespace']; - me[namespace] = new Schema(child); + me[namespace] = new Schema(); + me[namespace].init(child); break; default: arr.push(Promise.reject(new Error('Unknown element name '+elemName))); diff --git a/lib/NavigationProperty.js b/lib/NavigationProperty.js index 669fa60..2498212 100644 --- a/lib/NavigationProperty.js +++ b/lib/NavigationProperty.js @@ -1,24 +1,17 @@ -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); -class NavigationProperty extends ParserCommon { - constructor(element) { +class NavigationProperty extends AnnotatedObject { + constructor() { super(); - this.Annotations = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - //TODO ReferentialConstraint handling - //TODO OnDelete Handling - }; - this.validAttributes = { - 'Name': {alreadyHandeled: true}, - 'Type': {}, - 'Nullable': {bool: true}, - 'Partner': {}, - 'ContainsTarget': {bool: true} - }; - - this.init(element, 'Name'); + //TODO ReferentialConstraint handling + //TODO OnDelete Handling + this.addAttributeHandler('Name', null, {}); + this.addAttributeHandler('Type', this.addAttributeToObj, {}); + this.addAttributeHandler('Nullable', this.addBoolAttributeToObj, {}); + this.addAttributeHandler('Partner', this.addAttributeToObj, {}); + this.addAttributeHandler('ContainsTarget', this.addBoolAttributeToObj, {}); + this.nameAttr = 'Name'; } } diff --git a/lib/NavigationPropertyBinding.js b/lib/NavigationPropertyBinding.js index 6ab583d..7b751af 100644 --- a/lib/NavigationPropertyBinding.js +++ b/lib/NavigationPropertyBinding.js @@ -1,13 +1,11 @@ const ParserCommon = require('./ParserCommon'); class NavigationPropertyBinding extends ParserCommon { - constructor(element) { + constructor() { super(); - this.validAttributes = { - 'Target': {}, - 'Path': {alreadyHandeled: true} - }; - this.init(element, 'Path'); + this.addAttributeHandler('Target', this.addAttributeToObj, {}); + this.addAttributeHandler('Path', null, {}); + this.nameAttr = 'Path'; } } diff --git a/lib/Parameter.js b/lib/Parameter.js index 823693c..edbb4a6 100644 --- a/lib/Parameter.js +++ b/lib/Parameter.js @@ -1,26 +1,17 @@ -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); - -class Parameter extends ParserCommon { - constructor(element) { +class Parameter extends AnnotatedObject { + constructor() { super(); - this.Annotations = {}; - - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - }; - this.validAttributes = { - 'Name': {alreadyHandeled: true}, - 'Type': {}, - 'Nullable': {bool: true}, - 'MaxLength': {integer: true}, - 'Precision': {integer: true}, - 'Scale': {}, - 'Unicode': {bool: true}, - 'SRID': {} - }; - - this.init(element, 'Name'); + this.addAttributeHandler('Name', null, {}); + this.addAttributeHandler('Type', this.addAttributeToObj, {}); + this.addAttributeHandler('Nullable', this.addBoolAttributeToObj, {}); + this.addAttributeHandler('MaxLength', this.addIntAttributeToObj, {}); + this.addAttributeHandler('Precision', this.addIntAttributeToObj, {}); + this.addAttributeHandler('Scale', this.addAttributeToObj, {}); + this.addAttributeHandler('Unicode', this.addBoolAttributeToObj, {}); + this.addAttributeHandler('SRID', this.addAttributeToObj, {}); + this.nameAttr = 'Name'; } } diff --git a/lib/ParserCommon.js b/lib/ParserCommon.js index bfb0ce3..8065719 100644 --- a/lib/ParserCommon.js +++ b/lib/ParserCommon.js @@ -1,19 +1,27 @@ 'use strict' class ParserCommon { - init(element, nameAttr, nameAttrLocation) { + init(element) { let entityTypeName = this.constructor.name; - if(nameAttr !== undefined) { - if(nameAttrLocation === undefined) { - nameAttrLocation = 'Name'; + if(this.nameAttr !== undefined) { + if(this.nameAttrLocation === undefined) { + this.nameAttrLocation = 'Name'; } - this[nameAttrLocation] = element.attr[nameAttr]; + this[this.nameAttrLocation] = element.attr[this.nameAttr]; + delete this.nameAttr; + delete this.nameAttrLocation; } - if(this.validElements !== undefined || this.validAttributes !== undefined) { + if(this.validElements !== undefined || this.validAttributes !== undefined || + this.attributeHandlers !== undefined || this.elementHandlers !== undefined) { this.parseEntity(element, entityTypeName); delete this.validElements; delete this.validAttributes; + delete this.attributeHandlers; + delete this.elementHandlers; + } + if(this.postInitCleanup !== undefined) { + this.postInitCleanup(); } } @@ -33,70 +41,20 @@ class ParserCommon { parseChildElement(element) { let elemName = element.name; - if(this.validElements === undefined || this.validElements[elemName] === undefined) { + if(this.elementHandlers === undefined || this.elementHandlers[elemName] === undefined) { throw new Error('Unknown element name '+elemName+' in Parent '+this.constructor.name); } - let options = this.validElements[elemName]; - if(options.parent === undefined) { - options.parent = this; - } - if(options.helperFunc !== undefined) { - options.helperFunc(element); - return; - } - let name = false; - if(options.name !== undefined) { - name = options.name; - } - else if(options.nameProp !== undefined) { - name = element.attr[options.nameProp]; - } - if(options.passthru === true) { - options.parent[name] = element; - return; - } - if(name === false) { - if(options.getText === true) { - options.parent.push(element.val); - return; - } - let type = require('./'+elemName); - options.parent.push(new type(element)); - return; - } - if(options.getText === true) { - options.parent[name] = element.val; - return; - } - var type = require('./'+elemName); - options.parent[name] = new type(element); + let handler = this.elementHandlers[elemName]; + handler.func(element, handler.data); } parseAttribute(name, value) { - if(this.validAttributes === undefined || this.validAttributes[name] === undefined) { - throw new Error('Unknown attribute name '+name); - } - let options = this.validAttributes[name]; - if(options.alreadyHandeled === true) { - return; - } - if(options.parent === undefined) { - options.parent = this; + if(this.attributeHandlers === undefined || this.attributeHandlers[name] === undefined) { + throw new Error('Unknown attribute name '+name+' in Parent '+this.constructor.name); } - if(options.name === undefined) { - options.name = name; - } - if(options.bool === true) { - this.parseBooleanAttribute(options.parent, value, options.name); - } - else if(options.integer === true) { - options.parent[options.name] = value*1; - } - else { - options.parent[options.name] = value; - if(options.helperFunc !== undefined) { - options.parent[options.name] = options.helperFunc(options.parent[options.name]); - } + let handler = this.attributeHandlers[name]; + if(handler.func !== null) { + handler.func(name, value, handler.data); } } @@ -111,6 +69,82 @@ class ParserCommon { throw new Error('Unknown value '+value+' for attribute named '+name); } } + + addElementHandler(elementName, func, funcData) { + if(this.elementHandlers === undefined) { + this.elementHandlers = {}; + } + let funcVar = func; + funcVar = func.bind(this); + this.elementHandlers[elementName] = {func: funcVar, data: funcData}; + } + + addAttributeHandler(attributeName, func, funcData) { + if(this.attributeHandlers === undefined) { + this.attributeHandlers = {}; + } + let funcVar = func; + if(func) { + funcVar = func.bind(this); + } + this.attributeHandlers[attributeName] = {func: funcVar, data: funcData}; + } + + getObjectFromElement(element) { + let elemName = element.name; + let type = require('./'+elemName); + let child = new type(); + child.init(element); + return child; + } + + addElementToObj(element, data) { + let par = data.parent || this; + let name = data.name; + if(name == undefined && data.nameProp !== undefined) { + name = element.attr[data.nameProp]; + } + par[name] = this.getObjectFromElement(element); + } + + addElementToArray(element, data) { + let par = data.parent; + par.push(this.getObjectFromElement(element)); + } + + addStringToObj(element, data) { + let par = data.parent || this; + let name = data.name; + par[name] = element.val; + } + + addStringToArray(element, data) { + let par = data.parent; + par.push(element.val); + } + + addXMLToObj(element, data) { + let par = data.parent || this; + let name = data.name; + par[name] = element; + } + + addAttributeToObj(name, value, data) { + let par = data.parent || this; + if(data.name) { + name = data.name; + } + par[name] = value; + } + + addBoolAttributeToObj(name, value, data) { + let par = data.parent || this; + this.parseBooleanAttribute(par, value, name) + } + + addIntAttributeToObj(name, value, data) { + this.addAttributeToObj(name, value*1, data); + } } module.exports = ParserCommon; diff --git a/lib/Property.js b/lib/Property.js index 5016fdc..80e8299 100644 --- a/lib/Property.js +++ b/lib/Property.js @@ -1,27 +1,10 @@ -const ParserCommon = require('./ParserCommon'); +const Parameter = require('./Parameter'); -class Property extends ParserCommon { - constructor(element) { +class Property extends Parameter { + constructor() { super(); - - this.Annotations = {}; - - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - }; - this.validAttributes = { - 'Type': {}, - 'Nullable': {bool: true}, - 'MaxLength': {integer: true}, - 'Precision': {integer: true}, - 'Scale': {}, - 'Unicode': {bool: true}, - 'SRID': {}, - 'DefaultValue': {}, - 'Name': {alreadyHandeled: true} - }; - - this.init(element, 'Name'); + this.addAttributeHandler('DefaultValue', this.addAttributeToObj, {}); + this.nameAttr = 'Name'; } } diff --git a/lib/PropertyValue.js b/lib/PropertyValue.js index 83a2ae0..6aa9a45 100644 --- a/lib/PropertyValue.js +++ b/lib/PropertyValue.js @@ -1,23 +1,19 @@ -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); -class PropertyValue extends ParserCommon { - constructor(element) { +class PropertyValue extends AnnotatedObject { + constructor() { super(); - this.Annotations = {}; this.Records = []; - this.validElements = { - 'Record': {parent: this.Records}, - 'Collection': {parent: this, name: 'Collection'} - }; - this.validAttributes = { - 'Bool': {bool: true}, - 'String': {}, - 'Path': {}, - 'Property': {alreadyHandeled: true}, - 'EnumMember': {} - }; - this.init(element, 'Property'); + this.addElementHandler('Record', this.addElementToArray, {parent: this.Records}); + this.addElementHandler('Collection', this.addElementToObj, {name: 'Collection'}); + + this.addAttributeHandler('Property', null, {}); + this.addAttributeHandler('Path', this.addAttributeToObj, {}); + this.addAttributeHandler('String', this.addAttributeToObj, {}); + this.addAttributeHandler('EnumMember', this.addAttributeToObj, {}); + this.addAttributeHandler('Bool', this.addBoolAttributeToObj, {}); + this.nameAttr = 'Property'; } } diff --git a/lib/Record.js b/lib/Record.js index 3a8ac9f..8e0d23e 100644 --- a/lib/Record.js +++ b/lib/Record.js @@ -1,19 +1,12 @@ -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); -class Record extends ParserCommon { - constructor(element) { +class Record extends AnnotatedObject { + constructor() { super(); - this.Annotations = {}; this.PropertyValues = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'PropertyValue': {parent: this.PropertyValues, nameProp: 'Property'} - }; - this.validAttributes = { - 'Type': {} - }; - this.init(element); + this.addElementHandler('PropertyValue', this.addElementToObj, {parent: this.PropertyValues, nameProp: 'Property'}); + this.addAttributeHandler('Type', this.addAttributeToObj, {}); } } diff --git a/lib/Reference.js b/lib/Reference.js index 83fccb1..21898e1 100644 --- a/lib/Reference.js +++ b/lib/Reference.js @@ -1,25 +1,17 @@ -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); -class Reference extends ParserCommon { - constructor(element) { +class Reference extends AnnotatedObject { + constructor() { super(); this.Uri = null; this.Includes = {}; - this.Annotations = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'Include': {parent: this.Includes, helperFunc: this.processInclude.bind(this)}, - 'edmx:Include': {parent: this.Includes, helperFunc: this.processInclude.bind(this)} - }; - this.validAttributes = { - 'Uri': {} - }; - - this.init(element); + this.addElementHandler('Include', this.processInclude, {}); + this.addElementHandler('edmx:Include', this.processInclude, {}); + this.addAttributeHandler('Uri', this.addAttributeToObj, {}); } - processInclude(element) { + processInclude(element, data) { let namespace = element.attr['Namespace']; let aliasAttr = element.attr['Alias']; if(aliasAttr) { diff --git a/lib/ReturnType.js b/lib/ReturnType.js index da2dc9b..2790885 100644 --- a/lib/ReturnType.js +++ b/lib/ReturnType.js @@ -2,16 +2,12 @@ const ParserCommon = require('./ParserCommon'); class ReturnType extends ParserCommon { - constructor(element) { + constructor() { super(); - this.validAttributes = { - 'Nullable': {bool: true}, - 'Type': {}, - 'Name': {alreadyHandeled: true} - }; - - this.init(element); + this.addAttributeHandler('Nullable', this.addBoolAttributeToObj, {}); + this.addAttributeHandler('Type', this.addAttributeToObj, {}); + this.addAttributeHandler('Name', null, {}); } } diff --git a/lib/Schema.js b/lib/Schema.js index 5828c79..c484934 100644 --- a/lib/Schema.js +++ b/lib/Schema.js @@ -1,29 +1,24 @@ 'use strict' -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); -class Schema extends ParserCommon { - constructor(element) { +class Schema extends AnnotatedObject { + constructor() { super(); - this.Annotations = {}; - this.validElements = { - 'Action': {parent: this, nameProp: 'Name'}, - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'ComplexType': {parent: this, nameProp: 'Name'}, - 'EntityContainer': {parent: this, nameProp: 'Name'}, - 'EntityType': {parent: this, nameProp: 'Name'}, - 'EnumType': {parent: this, nameProp: 'Name'}, - 'Function': {parent: this, nameProp: 'Name'}, - 'Term': {parent: this, nameProp: 'Name'}, - 'TypeDefinition': {parent: this, nameProp: 'Name'} - }; - this.validAttributes = { - 'Namespace': {alreadyHandeled: true}, - 'Alias': {name: '_Alias'}, - 'xmlns': {alreadyHandeled: true} - }; + this.addElementHandler('Action', this.addElementToObj, {nameProp: 'Name'}); + this.addElementHandler('ComplexType', this.addElementToObj, {nameProp: 'Name'}); + this.addElementHandler('EntityContainer', this.addElementToObj, {nameProp: 'Name'}); + this.addElementHandler('EntityType', this.addElementToObj, {nameProp: 'Name'}); + this.addElementHandler('EnumType', this.addElementToObj, {nameProp: 'Name'}); + this.addElementHandler('Function', this.addElementToObj, {nameProp: 'Name'}); + this.addElementHandler('Term', this.addElementToObj, {nameProp: 'Name'}); + this.addElementHandler('TypeDefinition', this.addElementToObj, {nameProp: 'Name'}); - this.init(element, 'Namespace', '_Name'); + this.addAttributeHandler('Alias', this.addAttributeToObj, {name: '_Alias'}); + this.addAttributeHandler('Namespace', null, {}); + this.addAttributeHandler('xmlns', null, {}); + this.nameAttr = 'Namespace'; + this.nameAttrLocation = '_Name'; } } diff --git a/lib/Singleton.js b/lib/Singleton.js index 58ea741..0a89361 100644 --- a/lib/Singleton.js +++ b/lib/Singleton.js @@ -1,18 +1,11 @@ -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); -class Singleton extends ParserCommon { - constructor(element) { +class Singleton extends AnnotatedObject { + constructor() { super(); - this.Annotations = {}; - - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - }; - this.validAttributes = { - 'Type': {}, - 'Name': {alreadyHandeled: true} - }; - this.init(element, 'Name'); + this.addAttributeHandler('Type', this.addAttributeToObj, {}); + this.addAttributeHandler('Name', null, {}); + this.nameAttr = 'Name'; } } diff --git a/lib/Term.js b/lib/Term.js index fcbc194..f2a3e48 100644 --- a/lib/Term.js +++ b/lib/Term.js @@ -1,30 +1,23 @@ -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); -class Term extends ParserCommon { - constructor(element) { +class Term extends AnnotatedObject { + constructor() { super(); - this.Annotations = {}; - - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - }; - this.validAttributes = { - 'Name': {alreadyHandeled: true}, - 'Type': {}, - 'BaseTerm': {}, - 'DefaultValue': {}, - 'AppliesTo': {helperFunc: this.splitAppliesTo.bind(this)}, - 'Nullable': {bool: true}, - 'MaxLength': {integer: true}, - 'Precision': {integer: true}, - 'Scale': {}, - 'SRID': {} - }; - this.init(element, 'Name'); + this.addAttributeHandler('Name', null, {}); + this.addAttributeHandler('Type', this.addAttributeToObj, {}); + this.addAttributeHandler('BaseTerm', this.addAttributeToObj, {}); + this.addAttributeHandler('Nullable', this.addBoolAttributeToObj, {}); + this.addAttributeHandler('MaxLength', this.addIntAttributeToObj, {}); + this.addAttributeHandler('Precision', this.addIntAttributeToObj, {}); + this.addAttributeHandler('Scale', this.addAttributeToObj, {}); + this.addAttributeHandler('SRID', this.addAttributeToObj, {}); + this.addAttributeHandler('DefaultValue', this.addAttributeToObj, {}); + this.addAttributeHandler('AppliesTo', this.addAppliesTo, {}); + this.nameAttr = 'Name'; } - splitAppliesTo(value) { - return value.split(' '); + addAppliesTo(name, value, data) { + this.addAttributeToObj(name, value.split(' '), data); } } diff --git a/lib/TypeDefinition.js b/lib/TypeDefinition.js index 19324e2..9ef5282 100644 --- a/lib/TypeDefinition.js +++ b/lib/TypeDefinition.js @@ -1,23 +1,16 @@ -const ParserCommon = require('./ParserCommon'); +const AnnotatedObject = require('./AnnotatedObject'); -class TypeDefinition extends ParserCommon { - constructor(element) { +class TypeDefinition extends AnnotatedObject { + constructor() { super(); - this.Annotations = {}; - - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - }; - this.validAttributes = { - 'UnderlyingType': {}, - 'Name': {alreadyHandeled: true}, - 'MaxLength': {integer: true}, - 'Precision': {integer: true}, - 'Scale': {}, - 'Unicode': {bool: true}, - 'SRID': {} - }; - this.init(element, 'Name'); + this.addAttributeHandler('Name', null, {}); + this.addAttributeHandler('UnderlyingType', this.addAttributeToObj, {}); + this.addAttributeHandler('MaxLength', this.addIntAttributeToObj, {}); + this.addAttributeHandler('Precision', this.addIntAttributeToObj, {}); + this.addAttributeHandler('Scale', this.addAttributeToObj, {}); + this.addAttributeHandler('Unicode', this.addBoolAttributeToObj, {}); + this.addAttributeHandler('SRID', this.addAttributeToObj, {}); + this.nameAttr = 'Name'; } } diff --git a/test/corner.js b/test/corner.js index 1655684..f37eff9 100644 --- a/test/corner.js +++ b/test/corner.js @@ -51,7 +51,7 @@ describe('Corner Cases', function() { it('Attribute parent case', function() { let test = {}; let myobj = new ParserCommon(); - myobj.validAttributes = {'x': {'parent': test}}; + myobj.addAttributeHandler('x', myobj.addAttributeToObj, {'parent': test}); let doc = new xmldoc.XmlDocument(''); myobj.init(doc, 'Test'); assert.equal(test.x, 'value'); diff --git a/test/negative.js b/test/negative.js index 71a4dbd..81bd3b7 100644 --- a/test/negative.js +++ b/test/negative.js @@ -20,15 +20,15 @@ describe('Negative', function(){ }); it('Unknown Element', function(){ let doc = new xmldoc.XmlDocument(invalidAnnotationElement); - assert.throws(function(){new Annotation(doc);}, Error, 'Unknown element name BadElement'); + assert.throws(function(){let ann = new Annotation(); ann.init(doc);}, Error, 'Unknown element name BadElement'); }); it('Unknown Attribute', function(){ let doc = new xmldoc.XmlDocument(invalidAnnotationAttribute); - assert.throws(function(){new Annotation(doc);}, Error, 'Unknown attribute name BadAttr'); + assert.throws(function(){let ann = new Annotation(); ann.init(doc);}, Error, 'Unknown attribute name BadAttr'); }); it('Unknown Attribute Value', function(){ let doc = new xmldoc.XmlDocument(invalidAnnotationBadBool); - assert.throws(function(){new Annotation(doc);}, Error, 'Unknown value Bad for attribute named Bool'); + assert.throws(function(){let ann = new Annotation(); ann.init(doc);}, Error, 'Unknown value Bad for attribute named Bool'); }); it('Non CSDL', function(done) { csdl.parseMetadata(simpleWithText, {}, function(error, data){ diff --git a/test/search.js b/test/search.js index 0d76841..a377dc2 100644 --- a/test/search.js +++ b/test/search.js @@ -61,7 +61,7 @@ describe('Search', function(){ type = csdl.findByType(fakeCache, 'Test2.Type2'); assert.equal(type, null); }); - it('Reference Search', function() { + it('Reference FindByType', function() { var type = csdl.findByType(fakeCache2, 'Test3.Type1'); assert.notEqual(type, undefined); assert.notEqual(type, null); @@ -94,5 +94,10 @@ describe('Search', function(){ let type = csdl.search(metadata, undefined, undefined); assert.notEqual(type, undefined); }); + it('Reference Search', function() { + var type = csdl.search(fakeCache2, 'References', null, true); + assert.notEqual(type, undefined); + assert.notEqual(type, null); + }); }); /* vim: set tabstop=2 shiftwidth=2 expandtab: */ From cd3449f5e7f029aa7bc026685174ea0b6b2c5e0a Mon Sep 17 00:00:00 2001 From: Patrick Boyd Date: Thu, 28 Feb 2019 16:49:30 -0600 Subject: [PATCH 2/3] Further address code climate issues --- lib/CSDLSearch.js | 78 ++++++++++++++++++++++++++++----------------- lib/Metadata.js | 20 ++++++++---- lib/ParserCommon.js | 25 ++++++++------- 3 files changed, 74 insertions(+), 49 deletions(-) diff --git a/lib/CSDLSearch.js b/lib/CSDLSearch.js index 31f8060..0ac44e7 100644 --- a/lib/CSDLSearch.js +++ b/lib/CSDLSearch.js @@ -2,12 +2,7 @@ function searchAnnotation(collection, elementName) { var ret = []; if(elementName === undefined) { - for(var name in collection) { - if(name[0] === '_') { - continue; - } - ret.push(collection[name]); - } + return getAllValidElementsInCollection(collection); } else { if(collection[elementName] !== undefined) { @@ -17,6 +12,17 @@ function searchAnnotation(collection, elementName) { return ret; } +function getAllValidElementsInCollection(collection) { + let ret = []; + for(var name in collection) { + if(name[0] === '_') { + continue; + } + ret.push(collection[name]); + } + return ret; +} + function getElementIfNameEqual(element, elementName) { if(elementName === undefined) { return element; @@ -52,29 +58,38 @@ function searchElementPart(key, element, elementType, elementName, includeRefere let ret = []; switch(key) { case 'Annotations': - if(elementType === 'Annotation') { - return searchAnnotation(element, elementName); - } - return ret; + return processAnnotationsKey(element, elementType, elementName); case 'References': if(includeReferences !== true) { return ret; } //Deliberate fallthrough... default: - if(elementInvalid(element)) { - return ret; - } - if(elementType === undefined) { - pushIfNotUndefined(ret, getElementIfNameEqual(element, elementName)); - return ret; - } - if(elementType === element.constructor.name) { - pushIfNotUndefined(ret, getElementIfNameEqual(element, elementName)); - return ret; - } - return searchCSDL(element, elementType, elementName); + return processDefaultKey(element, elementType, elementName); + } +} + +function processAnnotationsKey(element, elementType, elementName) { + if(elementType === 'Annotation') { + return searchAnnotation(element, elementName); } + return []; +} + +function processDefaultKey(element, elementType, elementName) { + let ret = []; + if(elementInvalid(element)) { + return ret; + } + if(elementType === undefined) { + pushIfNotUndefined(ret, getElementIfNameEqual(element, elementName)); + return ret; + } + if(elementType === element.constructor.name) { + pushIfNotUndefined(ret, getElementIfNameEqual(element, elementName)); + return ret; + } + return searchCSDL(element, elementType, elementName); } function remapNamespace(references, namespace) { @@ -109,14 +124,7 @@ function findByType(metadata, typeName) { function findSchema(metadata, namespace, justType) { let schemas = metadata._options.cache.getSchemas(namespace); if(schemas.length === 0) { - if(metadata.References === undefined) { - return undefined; - } - namespace = remapNamespace(metadata.References, namespace); - if(namespace !== undefined) { - return findSchema(metadata, namespace, justType); - } - return undefined; + return findSchemaWithReferences(metadata, namespace, justType); } for(let i = 0; i < schemas.length; i++) { if(schemas[i][justType] !== undefined) { @@ -126,6 +134,16 @@ function findSchema(metadata, namespace, justType) { return undefined; } +function findSchemaWithReferences(metadata, namespace, justType) { + if(metadata.References !== undefined) { + namespace = remapNamespace(metadata.References, namespace); + if(namespace !== undefined) { + return findSchema(metadata, namespace, justType); + } + } + return undefined; +} + module.exports.search = searchCSDL; module.exports.findByType = findByType; /* vim: set tabstop=2 shiftwidth=2 expandtab: */ diff --git a/lib/Metadata.js b/lib/Metadata.js index 024c846..70b91c3 100644 --- a/lib/Metadata.js +++ b/lib/Metadata.js @@ -28,7 +28,6 @@ class Metadata { } parse(string, callback, context) { - let arr = []; let doc; try { doc = new xmldoc.XmlDocument(string); @@ -38,6 +37,18 @@ class Metadata { return; } let me = this; + let arr = this.getChildElementPromises(doc); + Promise.all(arr).then((values) => { + callback(null, me); + me._options.cache.addMetadata(me); + }).catch((e) => { + callback(e, null); + }); + } + + getChildElementPromises(doc) { + let arr = []; + let me = this; doc.eachChild(function(child, index, array) { let elemName = child.name; switch(elemName) { @@ -57,12 +68,7 @@ class Metadata { break; } }); - Promise.all(arr).then((values) => { - callback(null, me); - me._options.cache.addMetadata(me); - }).catch((e) => { - callback(e, null); - }); + return arr; } parseDataServices(element) { diff --git a/lib/ParserCommon.js b/lib/ParserCommon.js index 8065719..c0a457a 100644 --- a/lib/ParserCommon.js +++ b/lib/ParserCommon.js @@ -3,20 +3,10 @@ class ParserCommon { init(element) { let entityTypeName = this.constructor.name; - if(this.nameAttr !== undefined) { - if(this.nameAttrLocation === undefined) { - this.nameAttrLocation = 'Name'; - } - this[this.nameAttrLocation] = element.attr[this.nameAttr]; - delete this.nameAttr; - delete this.nameAttrLocation; - } + this.parseName(element); - if(this.validElements !== undefined || this.validAttributes !== undefined || - this.attributeHandlers !== undefined || this.elementHandlers !== undefined) { + if(this.attributeHandlers !== undefined || this.elementHandlers !== undefined) { this.parseEntity(element, entityTypeName); - delete this.validElements; - delete this.validAttributes; delete this.attributeHandlers; delete this.elementHandlers; } @@ -25,6 +15,17 @@ class ParserCommon { } } + parseName(element) { + if(this.nameAttr !== undefined) { + if(this.nameAttrLocation === undefined) { + this.nameAttrLocation = 'Name'; + } + this[this.nameAttrLocation] = element.attr[this.nameAttr]; + delete this.nameAttr; + delete this.nameAttrLocation; + } + } + parseEntity(element, entityName) { let me = this; if(element.val.trim().length !== 0) { From 17937780e21267356f26a8ed1285b0f97b6699ff Mon Sep 17 00:00:00 2001 From: Patrick Boyd Date: Fri, 1 Mar 2019 10:51:36 -0600 Subject: [PATCH 3/3] Fix ESLint errors --- .eslintrc | 3 +- lib/EnumType.js | 4 +-- lib/Metadata.js | 63 +++++++++++++++++++++--------------------- lib/ParserCommon.js | 7 +++-- lib/Reference.js | 4 +-- lib/cache/csdlCache.js | 2 +- lib/cache/fileCache.js | 6 ++-- test/corner.js | 2 +- test/redfish.js | 4 +-- 9 files changed, 47 insertions(+), 48 deletions(-) diff --git a/.eslintrc b/.eslintrc index 9faa375..dcb4be5 100644 --- a/.eslintrc +++ b/.eslintrc @@ -51,13 +51,12 @@ rules: dot-location: 0 dot-notation: 0 eqeqeq: 2 - guard-for-in: 2 + guard-for-in: 0 no-alert: 2 no-caller: 2 no-case-declarations: 2 no-div-regex: 2 no-else-return: 0 - no-empty-label: 2 no-empty-pattern: 2 no-eq-null: 2 no-eval: 2 diff --git a/lib/EnumType.js b/lib/EnumType.js index bed1815..cde1368 100644 --- a/lib/EnumType.js +++ b/lib/EnumType.js @@ -17,7 +17,7 @@ class EnumType extends AnnotatedObject { delete this._index; } - addMember(element, data) { + addMember(element) { let name = element.attr['Name']; let value = element.attr['Value']; this.Members[name] = {}; @@ -29,7 +29,7 @@ class EnumType extends AnnotatedObject { this.Members[name].value = this._index++; } let me = this; - element.eachChild(function(child, index, array) { + element.eachChild(function(child) { if(child.name === 'Annotation') { let annotation = new Annotation(); annotation.init(child); diff --git a/lib/Metadata.js b/lib/Metadata.js index 70b91c3..154b936 100644 --- a/lib/Metadata.js +++ b/lib/Metadata.js @@ -2,7 +2,6 @@ const xmldoc = require('xmldoc'); const fs = require('fs'); const request = require('request'); -const ParserCommon = require('./ParserCommon'); const Reference = require('./Reference'); const Schema = require('./Schema'); const CSDLCache = require('./cache/csdlCache'); @@ -27,7 +26,7 @@ class Metadata { } } - parse(string, callback, context) { + parse(string, callback) { let doc; try { doc = new xmldoc.XmlDocument(string); @@ -38,9 +37,9 @@ class Metadata { } let me = this; let arr = this.getChildElementPromises(doc); - Promise.all(arr).then((values) => { - callback(null, me); + Promise.all(arr).then(() => { me._options.cache.addMetadata(me); + callback(null, me); }).catch((e) => { callback(e, null); }); @@ -49,15 +48,12 @@ class Metadata { getChildElementPromises(doc) { let arr = []; let me = this; - doc.eachChild(function(child, index, array) { + doc.eachChild(function(child) { let elemName = child.name; switch(elemName) { case 'Reference': case 'edmx:Reference': - let ref = new Reference(); - ref.init(child); - arr.push(ref.bind(me._options.cache)); - me.References.push(ref); + arr.push(me.getReferencePromise(child)); break; case 'DataServices': case 'edmx:DataServices': @@ -71,22 +67,30 @@ class Metadata { return arr; } + getReferencePromise(child) { + let ref = new Reference(); + ref.init(child); + this.References.push(ref); + return ref.bind(this._options.cache); + } + parseDataServices(element) { let me = this; - element.eachChild(function(child, index, array) { + let ret = Promise.resolve(null); + element.eachChild(function(child) { let elemName = child.name; + let namespace; switch(elemName) { case 'Schema': - let namespace = child.attr['Namespace']; + namespace = child.attr['Namespace']; me[namespace] = new Schema(); me[namespace].init(child); break; default: - arr.push(Promise.reject(new Error('Unknown element name '+elemName))); + ret = Promise.reject(new Error('Unknown element name '+elemName)); } }); - //Just resolve this with null as we have no new references to add - return Promise.resolve(null); + return ret; } resolve() { @@ -100,24 +104,19 @@ class Metadata { module.exports.construct = Metadata; module.exports.parseMetadata = function(string, options, callback) { - try { - var meta = new Metadata(options); - meta.parse(string, (err, data) => { - if(err) { - callback(err, data); - return; - } - let promise = data.resolve(); - promise.then(() => { - callback(null, data); - }).catch((e) => { - callback(e, data); - }); - }); - } - catch(e) { - callback(e, null); - } + var meta = new Metadata(options); + meta.parse(string, (err, data) => { + if(err) { + callback(err, data); + return; + } + let promise = data.resolve(); + promise.then(() => { + callback(null, data); + }).catch((e) => { + callback(e, data); + }); + }); } module.exports.parseMetadataFile = function(filename, options, callback) { diff --git a/lib/ParserCommon.js b/lib/ParserCommon.js index c0a457a..67d67ad 100644 --- a/lib/ParserCommon.js +++ b/lib/ParserCommon.js @@ -1,4 +1,5 @@ 'use strict' +/* eslint global-require: 0 */ class ParserCommon { init(element) { @@ -31,7 +32,7 @@ class ParserCommon { if(element.val.trim().length !== 0) { throw new Error('Unknown text element in '+entityName+'! Text = "'+element.val+'"'); } - element.eachChild(function(child, index, array) { + element.eachChild(function(child) { me.parseChildElement(child); }); @@ -92,7 +93,7 @@ class ParserCommon { } getObjectFromElement(element) { - let elemName = element.name; + let elemName = element.name; let type = require('./'+elemName); let child = new type(); child.init(element); @@ -102,7 +103,7 @@ class ParserCommon { addElementToObj(element, data) { let par = data.parent || this; let name = data.name; - if(name == undefined && data.nameProp !== undefined) { + if(name === undefined && data.nameProp !== undefined) { name = element.attr[data.nameProp]; } par[name] = this.getObjectFromElement(element); diff --git a/lib/Reference.js b/lib/Reference.js index 21898e1..6fb5ad6 100644 --- a/lib/Reference.js +++ b/lib/Reference.js @@ -11,7 +11,7 @@ class Reference extends AnnotatedObject { this.addAttributeHandler('Uri', this.addAttributeToObj, {}); } - processInclude(element, data) { + processInclude(element) { let namespace = element.attr['Namespace']; let aliasAttr = element.attr['Alias']; if(aliasAttr) { @@ -31,7 +31,7 @@ class Reference extends AnnotatedObject { let promise = cache.getMetadata(this.Uri); return new Promise((resolve, reject) => { promise.then((data) => { - this.Metadata = data; + me.Metadata = data; resolve(null); }).catch(reject); }); diff --git a/lib/cache/csdlCache.js b/lib/cache/csdlCache.js index 30a3baf..a3ca8ed 100644 --- a/lib/cache/csdlCache.js +++ b/lib/cache/csdlCache.js @@ -1,5 +1,5 @@ +/* eslint accessor-pairs: 0 */ const fileCache = require('./fileCache'); - const Metadata = require('../Metadata'); function CSDLCache(localDirs, useNetwork) { diff --git a/lib/cache/fileCache.js b/lib/cache/fileCache.js index f7320cc..a9b4f07 100644 --- a/lib/cache/fileCache.js +++ b/lib/cache/fileCache.js @@ -31,14 +31,14 @@ FileCache.prototype.getLocalFile = function(uri, resolve, reject, self) { } } if(self.useNetwork) { - self.getRemoteFile(uri, resolve, reject, self); + self.getRemoteFile(uri, resolve, reject); } else { reject(new Error('Unable to find file '+filename)); } } -FileCache.prototype.getRemoteFile = function(uri, resolve, reject, self) { +FileCache.prototype.getRemoteFile = function(uri, resolve, reject) { request.get(uri, function(error, response, body) { if(error) { reject(error); @@ -60,7 +60,7 @@ FileCache.prototype.getFile = function(uri) { self.getLocalFile(uri, resolve, reject, self); } if(self.useNetwork) { - self.getRemoteFile(uri, resolve, reject, self); + self.getRemoteFile(uri, resolve, reject); } }); } diff --git a/test/corner.js b/test/corner.js index f37eff9..506c6e4 100644 --- a/test/corner.js +++ b/test/corner.js @@ -31,7 +31,7 @@ describe('Corner Cases', function() { }); }); describe('EnumType', function() { - it('Member Child Element other than Annotation', function() { + it('Member Child Element other than Annotation', function(done) { csdl.parseMetadata('', {}, (error, meta) => { assert.equal(error, null); assert.notEqual(meta, null); diff --git a/test/redfish.js b/test/redfish.js index a34b3a6..4db20a3 100644 --- a/test/redfish.js +++ b/test/redfish.js @@ -84,7 +84,7 @@ describe('Redfish', function() { describe('Remote File: Resource', function() { let metadata; before(function(done) { - this.timeout(10000); + this.timeout(20000); csdl.parseMetadataUri('https://redfish.dmtf.org/schemas/Resource_v1.xml', null, function(error, meta) { assert.equal(error, null); metadata = meta; @@ -115,7 +115,7 @@ describe('Redfish', function() { describe('Remote File: ServiceRoot', function() { let metadata; before(function(done) { - this.timeout(10000); + this.timeout(20000); csdl.parseMetadataUri('https://redfish.dmtf.org/schemas/ServiceRoot_v1.xml', {}, function(error, meta) { assert.equal(error, null); metadata = meta;