UNPKG

@pilotlab/data

Version:

A luxurious user experience framework, developed by your friends at Pilot.

185 lines (150 loc) 7.76 kB
import is from '@pilotlab/is'; import Debug from '@pilotlab/debug'; import { NodeFactoryBase } from '@pilotlab/nodes'; import Attribute from './attribute'; import AttributeCreateOptions from './attributeCreateOptions'; import DataTools from '../dataTools'; import IAttributesFactory from './interfaces/iAttributesFactory'; import IAttributeFactory from './interfaces/iAttributeFactory'; import IAttribute from './interfaces/iAttribute'; import { DataType } from './attributeEnums'; import AttributeChangeOptions from './attributeChangeOptions'; import AttributeBase from './attributeBase'; import AttributesBase from './attributesBase'; export abstract class AttributeFactoryBase<TAttribute extends IAttribute> extends NodeFactoryBase<TAttribute> implements IAttributeFactory { instance(options?:AttributeCreateOptions):TAttribute { if (is.notEmpty(options)) { let dataType:(DataType | string) = options.dataType; if (is.empty(dataType, true)) dataType = DataType.ANY; /// IMPORTANT: We need to initialize the new attribute with any value that was /// passed in. If the new attribute is to be a collection, it must be initialized /// with an object representing the proper schema, otherwise we won't be able /// to properly set child values later. let attribute:any; if (this.getBaseDataType(dataType) === DataType.COLLECTION) { let value:any = options.value; if (value instanceof AttributesBase) value = value.toObject(true, true, true); else if (value instanceof AttributeBase) value = value.attributes.toObject(true, true, true); attribute = this.p_factoryManager.instance(dataType, value); } else { attribute = this.p_factoryManager.instance(dataType); } if (is.empty(attribute, false)) return <TAttribute><IAttribute>new Attribute(); if (is.notEmpty(options)) { if (is.notEmpty(options.key)) attribute.key = options.key; if (is.notEmpty(options.label)) attribute.label = options.label; if (is.notEmpty(options.isEditable)) attribute.isEditable = options.isEditable; if (is.notEmpty(options.isHidden)) attribute.isHidden = options.isHidden; attribute.set(options.value, options.changeOptions); } return attribute; } else return <TAttribute><IAttribute>new Attribute(); } get collection():IAttributesFactory { return null; } fromAny(value:(TAttribute | Object | string), ...args:any[]):TAttribute { let node:TAttribute; if (value instanceof AttributeBase) { node = <TAttribute>value.copy; } else if (value instanceof AttributesBase) { node = this.fromObject((<AttributesBase<any, any>>value).toObject(true, true, true)); } else if (typeof value === 'string') { node = this.fromString(value, ...args); } else if (Array.isArray(value)) { node = this.fromArray(value, ...args); } else node = this.fromObject(value, ...args); if (is.empty(node)) return this.instance(); return node; } fromObject(obj:any, ...args:any[]):TAttribute { try { if (is.empty(obj)) return null; let key:string; let value:any; let dataType:(DataType | string); let label:string; let isEditable:boolean = false; let isHidden:boolean = false; let index:number; let hasValueProperty:boolean = true; if (obj.hasOwnProperty('key')) key = obj['key']; else if (obj.hasOwnProperty('id')) key = obj['id']; else if (obj.hasOwnProperty('_id')) key = obj['_id']; if (obj.hasOwnProperty('value')) { value = obj['value']; if (is.notEmpty(value) && value.hasOwnProperty('value')) { if (is.notEmpty(key, true)) value['key'] = key; return this.fromAny(value); } } else if (obj.hasOwnProperty('children')) value = obj['children']; else if (obj.hasOwnProperty('attributes')) value = obj['attributes']; else if (obj.hasOwnProperty('nodes')) value = obj['nodes']; else { hasValueProperty = false; } if (obj.hasOwnProperty('label')) label = obj['label']; if (obj.hasOwnProperty('isEditable')) { if (typeof obj['isEditable'] === 'string') { isEditable = obj['isEditable'].toLowerCase() === 'true'; } else { isEditable = obj['isEditable']; } } if (obj.hasOwnProperty('isHidden')) { if (typeof obj['isHidden'] === 'string') { isHidden = obj['isHidden'].toLowerCase() === 'true'; } else { isHidden = obj['isHidden']; } } if (obj.hasOwnProperty('index') && is.number(parseFloat('' + obj['index']))) { index = parseFloat('' + obj['index']); } if (hasValueProperty) { /// The object has a value property, so we'll assume it's /// describing an attribute. if (obj.hasOwnProperty('dataType') && is.notEmpty(obj['dataType'], true)) { if (typeof obj['dataType'] === 'string') { dataType = obj['dataType'].toLowerCase(); } else { dataType = DataTools.getDataType(value); } } else { dataType = DataTools.getDataType(value); } } else if (is.notEmpty(key, true) || is.notEmpty(label, true) || (value.hasOwnProperty('dataType') && is.notEmpty(obj['dataType'], true))) { /// The object doesn't have a value property, but it has a label and/or /// a dataType property, so it appears to be describing an attribute. /// In this case, we'll give it a dataType of ANY. dataType = DataType.ANY; value = null; } else { /// The object doesn't have a value property, it must describe a collection, /// so pass the entire object as the value. dataType = DataType.COLLECTION; value = this.fromObject({ value: obj }); } return this.instance(new AttributeCreateOptions(value, dataType, label, index, key, AttributeChangeOptions.zero, obj, isEditable, isHidden)); } catch (e) { Debug.error(e, 'Attribute.create.fromObject(...)'); } } fromArray(values:any[], ...args:any[]):TAttribute { let attributeNew:TAttribute = this.instance(new AttributeCreateOptions(null, DataType.COLLECTION)); for (let i = 0, length = values.length; i < length; i++) { let value:any = values[i]; let attributeChild:IAttribute = this.fromAny(value); if (is.notEmpty(attributeChild)) { attributeNew.attributes.add(attributeChild); } } return attributeNew; } getBaseDataType(dataType:string):string { const dataTypeDescription:any = this.p_factoryManager.getDescription(dataType); return is.notEmpty(dataTypeDescription) && is.notEmpty(dataTypeDescription.baseType) ? dataTypeDescription.baseType : 'any'; } } // End class export default AttributeFactoryBase;