@pilotlab/data
Version:
A luxurious user experience framework, developed by your friends at Pilot.
185 lines (150 loc) • 7.76 kB
text/typescript
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;