/**
* @copyright 2015 Tridium, Inc. All Rights Reserved.
* @author Gareth Johnson
*/
/**
* Defines `OrdTarget` (not exposed on `baja` namespace).
* @module baja/ord/OrdTarget
*/
define([ "bajaScript/sys" ], function (baja) {
"use strict";
var subclass = baja.subclass,
BaseBajaObj = baja.BaseBajaObj;
/**
* ORD Target.
*
* This constructor shouldn't be invoked directly.
*
* @class
* @alias module:baja/ord/OrdTarget
* @extends baja.BaseBajaObj
* @inner
* @public
*
* @param {module:baja/ord/OrdTarget} [base] the base ORD Target
*/
var OrdTarget = function OrdTarget(base) {
this.base = base || null;
this.slot = base && base.slot;
this.propertyPath = base && base.propertyPath;
this.slotPath = base && base.slotPath;
this.container = base && base.container;
this.object = null;
this.ord = (base && base.ord) || null;
this.$serverPermissionsStr = base && base.$serverPermissionsStr;
this.$canRead = base && base.$canRead;
this.$canWrite = base && base.$canWrite;
this.$canInvoke = base && base.$canInvoke;
};
subclass(OrdTarget, BaseBajaObj);
/**
* Return a clone of this OrdTarget object.
*
* @returns {module:baja/ord/OrdTarget}
* @since Niagara 4.14
*/
OrdTarget.prototype.clone = function () {
const target = new OrdTarget();
target.base = this.base;
target.slot = this.slot;
target.propertyPath = this.propertyPath;
target.slotPath = this.slotPath;
target.container = this.container;
target.object = this.object;
target.ord = this.ord;
target.$facets = this.getFacets();
target.$canRead = this.canRead();
target.$canWrite = this.canWrite();
target.$canInvoke = this.canInvoke();
target.$serverPermissionsStr = this.$serverPermissionsStr;
return target;
};
/**
* Return the ord used to resolve the target.
*
* @returns {baja.Ord}
* @since Niagara 4.10
*/
OrdTarget.prototype.getOrd = function () {
return this.ord;
};
/**
* Return the Component for the ORD Target.
*
* @returns {baja.Component}
*/
OrdTarget.prototype.getComponent = function () {
var that = this,
container = that.container,
object = that.object,
base = that.base,
o;
if (baja.hasType(container, 'baja:Component')) {
return container;
}
if (baja.hasType(object)) {
if (object.getType().isComponent()) {
return object;
}
if (object.getType().isComplex()) {
o = object.getParent();
while (o !== null) {
if (o.getType().isComponent()) {
break;
}
o = o.getParent();
}
if (o !== null) {
return o;
}
}
}
if (base && typeof base === "object") {
return base.getComponent();
}
return null;
};
/**
* Return the object associated with this `OrdTarget`.
*
* This method will attempt to access any resolved value from its
* Property. If the resolved value wasn't resolved from a Property then
* the original resolved object is returned.
*
* @returns {baja.Object}
*/
OrdTarget.prototype.getObject = function () {
var that = this,
parent = that.container,
slot = that.slot,
propertyPath = that.propertyPath,
i,
val;
if (parent) {
// Walk up the Property Path
if (propertyPath) {
if (propertyPath.length > 0) {
val = parent;
for (i = 0; i < propertyPath.length; ++i) {
val = val.get(propertyPath[i]);
}
return val;
}
// If no PropertyPath then access from the Slot
} else if (slot && slot.isProperty()) {
return parent.get(slot);
}
}
// By default, just return the object originally resolved
return that.object;
};
/**
* If the ord resolves to a slot within a component, then return the slot
* of `getComponent()`. If not applicable, then return null.
* @since Niagara 4.10
* @returns {baja.Slot | null}
*/
OrdTarget.prototype.getSlotInComponent = function () {
var that = this,
base = that.base,
container = that.container,
object = that.object,
slot = that.slot;
if (slot) {
return slot;
}
if (!object || !base || container) {
return null;
}
if (!object.getType().isComplex() || !object.getParentComponent()) {
return base.getSlotInComponent();
}
return null;
};
/**
* Convenience to check if the underlying target is readable.
*
* @since Niagara 4.12
* @returns {boolean}
*/
OrdTarget.prototype.canRead = function () {
const comp = this.getComponent();
if (comp) {
return comp.canRead(this);
}
return !!this.$canRead;
};
/**
* Convenience to check if the underlying target is writable.
*
* @since Niagara 4.10
* @returns {boolean}
*/
OrdTarget.prototype.canWrite = function () {
const comp = this.getComponent();
if (comp) {
return comp.canWrite(this);
}
return !!this.$canWrite;
};
/**
* Convenience to check if the underlying target is invokable.
*
* @since Niagara 4.12
* @returns {boolean}
*/
OrdTarget.prototype.canInvoke = function () {
const comp = this.getComponent();
if (comp) {
return comp.canInvoke(this);
}
return !!this.$canInvoke;
};
/**
* @since Niagara 4.14
* @returns {baja.Permissions}
*/
OrdTarget.prototype.getPermissionsOnTarget = function () {
return this.$serverPermissionsStr ?
baja.Permissions.make(this.$serverPermissionsStr) : baja.Permissions.all;
};
/**
* @returns {baja.Facets} the correct slot facets, merged from the parent
* component through to the target object. If no parent component or no
* property path, returns `baja.Facets.DEFAULT`.
* @since Niagara 4.10
*/
OrdTarget.prototype.getFacets = function () {
var facets = this.$facets;
if (facets) { return facets; }
var serverFacets = this.$serverFacets;
var comp = this.getComponent();
if (comp) {
facets = baja.Facets.mergeSlotFacets(comp, this.propertyPath || this.slot);
}
if (serverFacets) {
facets = baja.Facets.make(serverFacets, facets);
delete this.$serverFacets;
}
return (this.$facets = facets || baja.Facets.DEFAULT);
};
return OrdTarget;
});