/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 'use strict'; const Field = require('../introspect/field'); /** * Object is an instance with a namespace and a type. * * This class is abstract. * @abstract * @class * @memberof module:composer-common */ class Typed { /** * Create an instance. * <p> * <strong>Note: Only to be called by framework code. Applications should * retrieve instances from {@link Factory}</strong> * </p> * * @param {ModelManager} modelManager - The ModelManager for this instance * @param {string} ns - The namespace this instance. * @param {string} type - The type this instance. * @private */ constructor(modelManager, ns, type) { this.$modelManager = modelManager; this.$namespace = ns; this.$type = type; } /** * Visitor design pattern * @param {Object} visitor - the visitor * @param {Object} parameters - the parameter * @return {Object} the result of visiting or null * @private */ accept(visitor,parameters) { return visitor.visit(this, parameters); } /** * Get the ModelManager for this instance * @return {ModelManager} The ModelManager for this object * @private */ getModelManager() { return this.$modelManager; } /** * Get the type of the instance (a short name, not including namespace). * @return {string} The type of this object */ getType() { return this.$type; } /** * Get the fully-qualified type name of the instance (including namespace). * @return {string} The fully-qualified type name of this object */ getFullyQualifiedType() { return this.$namespace + '.' + this.$type; } /** * Get the namespace of the instance. * @return {string} The namespace of this object */ getNamespace() { return this.$namespace; } /** * Returns the class declaration for this instance object. * * @return {ClassDeclaration} - the class declaration for this instance * @throws {Error} - if the class or namespace for the instance is not declared * @private */ getClassDeclaration() { // do we have a model file? let modelFile = this.getModelManager().getModelFile(this.getNamespace()); if (!modelFile) { throw new Error('No model for namespace ' + this.getNamespace() + ' is registered with the ModelManager'); } // do we have a class? let classDeclaration = modelFile.getType(this.getType()); if (!classDeclaration) { throw new Error('The namespace ' + this.getNamespace() + ' does not contain the type ' + this.getType()); } return classDeclaration; } /** * Sets a property on this Resource * @param {string} propName - the name of the field * @param {string} value - the value of the property */ setPropertyValue(propName, value) { this[propName] = value; } /** * Adds a value to an array property on this Resource * @param {string} propName - the name of the field * @param {string} value - the value of the property */ addArrayValue(propName, value) { if(this[propName]) { this[propName].push(value); } else { this[propName] = [value]; } } /** * Sets the fields to their default values, based on the model * @private */ assignFieldDefaults() { let classDeclaration = this.getClassDeclaration(); let fields = classDeclaration.getProperties(); for (let n = 0; n < fields.length; n++) { let field = fields[n]; if (field instanceof Field) { let defaultValue = field.getDefaultValue(); if (defaultValue) { if (field.getType() === 'String') { this.setPropertyValue(field.getName(), defaultValue); } else if (field.getType() === 'Integer') { this.setPropertyValue(field.getName(), parseInt(defaultValue)); } else if (field.getType() === 'Long') { this.setPropertyValue(field.getName(), parseInt(defaultValue)); } else if (field.getType() === 'Double') { this.setPropertyValue(field.getName(), parseFloat(defaultValue)); } else if (field.getType() === 'Boolean') { this.setPropertyValue(field.getName(), (defaultValue === 'true')); } else if (field.getType() === 'DateTime') { const dateTime = new Date(); dateTime.setTime(Date.parse(defaultValue)); this.setPropertyValue(field.getName(), dateTime); } } } } } /** * Overriden to prevent people accidentally converting a resource to JSON * without using the Serializer. * @private */ toJSON() { throw new Error('Use Serializer.toJSON to convert resource instances to JSON objects.'); } } module.exports = Typed;