
js.prompto.value.ConcreteInstance.js Maven / Gradle / Ivy
var CategoryType = null;
var ContextualExpression = require("../value/ContextualExpression").ContextualExpression;
var NotMutableError = require("../error/NotMutableError").NotMutableError;
var StorableDocument = require("../memstore/StorableDocument").StorableDocument;
var ExpressionValue = require("../value/ExpressionValue").ExpressionValue;
var DecimalType = require("../type/DecimalType").DecimalType;
var Variable = require("../runtime/Variable").Variable;
var Identifier = require("../grammar/Identifier").Identifier;
var Operator = require("../grammar/Operator").Operator;
var NullValue = require("./NullValue").NullValue;
var Decimal = require("./Decimal").Decimal;
var Integer = require("./Integer").Integer;
var Text = require("./Text").Text;
var Instance = require("./Value").Instance;
var DataStore = require("../store/DataStore").DataStore;
var TypeUtils = require("../utils/TypeUtils");
exports.resolve = function() {
CategoryType = require("../type/CategoryType").CategoryType;
};
function ConcreteInstance(context, declaration) {
Instance.call(this, new CategoryType(declaration.id));
this.declaration = declaration;
this.storable = false;
if(declaration.storable) {
var categories = declaration.collectCategories(context);
this.storable = DataStore.instance.newStorableDocument(categories);
}
this.mutable = false;
this.values = {};
return this;
}
ConcreteInstance.prototype = Object.create(Instance.prototype);
ConcreteInstance.prototype.constructor = ConcreteInstance;
ConcreteInstance.prototype.getType = function() {
return this.type;
};
ConcreteInstance.prototype.convertToJavaScript = function() {
return this; // TODO, until we have a translator
};
ConcreteInstance.prototype.getDbId = function() {
var dbId = this.values["dbId"] || null;
return dbId == null ? null : dbId.getStorableData();
};
ConcreteInstance.prototype.getOrCreateDbId = function() {
var dbId = this.getDbId();
if(dbId==null) {
dbId = this.storable.getOrCreateDbId();
var value = TypeUtils.convertFromJavaScript(dbId);
this.values["dbId"] = value;
}
return dbId;
};
ConcreteInstance.prototype.getStorableData = function() {
// this is called when storing the instance as a field value, so we just return the dbId
// the instance data itself will be collected as part of collectStorables
if (this.storable == null)
throw new NotStorableError();
else
return this.getOrCreateDbId();
};
ConcreteInstance.prototype.getMemberNames = function() {
return Object.getOwnPropertyNames(this.values);
};
ConcreteInstance.prototype.collectStorables = function(list) {
if (this.storable==null)
throw new NotStorableError();
if (this.storable.dirty) {
this.getOrCreateDbId();
list.push(this.storable);
}
for(var field in this.values) {
this.values[field].collectStorables(list);
}
};
// don't call getters from getters, so register them
// TODO: thread local storage
var activeGetters = {};
function getActiveGetters() {
return activeGetters;
}
ConcreteInstance.prototype.getMemberValue = function(context, attrName) {
/* if(typeof(attrName) != typeof(""))
throw "What?"; */
var stacked = getActiveGetters()[attrName] || null;
var first = stacked==null;
if(first)
getActiveGetters()[attrName] = context;
try {
return this.doGetMember(context, attrName, first);
} finally {
if(first) {
delete getActiveGetters()[attrName];
}
}
};
ConcreteInstance.prototype.doGetMember = function(context, attrName, allowGetter) {
var getter = allowGetter ? this.declaration.findGetter(context, attrName) : null;
if (getter != null) {
context = context.newInstanceContext(this, null).newChildContext();
return getter.interpret(context);
} else if (this.declaration.hasAttribute(context, attrName) || "dbId" == attrName) {
return this.values[attrName] || NullValue.instance;
} else if ("text" == attrName) {
return new Text(this.toString());
} else
return NullValue.instance;
};
// don't call setters from setters, so register them
var activeSetters = {};
function getActiveSetters() {
return activeSetters;
}
ConcreteInstance.prototype.setMember = function(context, attrName, value) {
/* if(typeof(attrName) != typeof(""))
throw "What?"; */
if(!this.mutable)
throw new NotMutableError();
var stacked = getActiveSetters()[attrName] || null;
var first = stacked==null;
if(first)
getActiveSetters()[attrName] = context;
try {
this.doSetMember(context, attrName, value, first);
} finally {
if(first) {
delete getActiveSetters()[attrName];
}
}
};
ConcreteInstance.prototype.doSetMember = function(context, attrName, value, allowSetter) {
var decl = context.getRegisteredDeclaration(attrName);
var setter = allowSetter ? this.declaration.findSetter(context,attrName) : null;
if(setter!=null) {
// use attribute name as parameter name for incoming value
context = context.newInstanceContext(this, null).newChildContext();
var id = new Identifier(attrName);
context.registerValue(new Variable(id, decl.getType()));
context.setValue(id, value);
value = setter.interpret(context);
}
value = this.autocast(decl, value);
this.values[attrName] = value;
if (this.storable && decl.storable) // TODO convert object graph if(value instanceof IInstance)
this.storable.setData(attrName, value.getStorableData());
};
ConcreteInstance.prototype.autocast = function(decl, value) {
if(value instanceof Integer && decl.getType()==DecimalType.instance)
value = new Decimal(value.DecimalValue());
return value;
};
ConcreteInstance.prototype.equals = function(obj) {
if(obj==this) {
return true;
} else if(!(obj instanceof ConcreteInstance)) {
return false;
} else {
var names = Object.getOwnPropertyNames(this.values);
var otherNames = Object.getOwnPropertyNames(obj.values);
if(names.length!=otherNames.length) {
return false;
}
for(var i=0;i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy