Joose.Managed.Attribute = new Joose.Managed.Class('Joose.Managed.Attribute', {
isa : Joose.Managed.Property.Attribute,
have : {
is : null,
builder : null,
isPrivate : false,
role : null,
publicName : null,
setterName : null,
getterName : null,
//indicates the logical readableness/writeableness of the attribute
readable : false,
writeable : false,
//indicates the physical presense of the accessor (may be absent for "combined" accessors for example)
hasGetter : false,
hasSetter : false,
required : false
},
after : {
initialize : function () {
var name = this.name
this.publicName = name.replace(/^_+/, '')
this.slot = this.isPrivate ? '$$' + name : name
this.setterName = this.setterName || this.getSetterName()
this.getterName = this.getterName || this.getGetterName()
this.readable = this.hasGetter = /^r/i.test(this.is)
this.writeable = this.hasSetter = /^.w/i.test(this.is)
}
},
override : {
computeValue : function () {
if (!Joose.O.isFunction(this.init)) this.SUPER()
},
preApply : function (targetClass) {
targetClass.meta.extend({
methods : this.getAccessorsFor(targetClass)
})
},
postUnApply : function (from) {
from.meta.extend({
removeMethods : this.getAccessorsFrom(from)
})
}
},
methods : {
getAccessorsFor : function (targetClass) {
var targetMeta = targetClass.meta
var setterName = this.setterName
var getterName = this.getterName
var methods = {}
if (this.hasSetter && !targetMeta.hasMethod(setterName)) {
methods[setterName] = this.getSetter()
methods[setterName].ACCESSOR_FROM = this
}
if (this.hasGetter && !targetMeta.hasMethod(getterName)) {
methods[getterName] = this.getGetter()
methods[getterName].ACCESSOR_FROM = this
}
return methods
},
getAccessorsFrom : function (from) {
var targetMeta = from.meta
var setterName = this.setterName
var getterName = this.getterName
var setter = this.hasSetter && targetMeta.getMethod(setterName)
var getter = this.hasGetter && targetMeta.getMethod(getterName)
var removeMethods = []
if (setter && setter.value.ACCESSOR_FROM == this) removeMethods.push(setterName)
if (getter && getter.value.ACCESSOR_FROM == this) removeMethods.push(getterName)
return removeMethods
},
getGetterName : function () {
return 'get' + Joose.S.uppercaseFirst(this.publicName)
},
getSetterName : function () {
return 'set' + Joose.S.uppercaseFirst(this.publicName)
},
getSetter : function () {
var slot = this.slot
return function (value) {
this[ slot ] = value
return this
}
},
getGetter : function () {
var slot = this.slot
return function () {
return this[ slot ]
}
},
getValueFrom : function (instance) {
var getterName = this.getterName
if (this.readable && instance.meta.hasMethod(getterName)) return instance[getterName]()
return instance[ this.slot ]
},
setValueTo : function (instance, value) {
var setterName = this.setterName
if (this.writeable && instance.meta.hasMethod(setterName))
instance[setterName](value)
else
instance[ this.slot ] = value
},
initFromConfig : function (instance, config) {
var name = this.name
var value, isSet = false
if (config.hasOwnProperty(name)) {
value = config[name]
isSet = true
} else
if (Joose.O.isFunction(this.init)) {
value = this.init.call(instance, config, name)
isSet = true
} else if (this.builder) {
value = instance[ this.builder.replace(/^this\./, '') ](name, config)
isSet = true
}
if (isSet)
this.setValueTo(instance, value)
else
if (this.required) throw "Required attribute [" + name + "] is missed during initialization of " + instance
}
}
}).c