152 lines
4.2 KiB
JavaScript
152 lines
4.2 KiB
JavaScript
// The Antville Project
|
||
// http://code.google.com/p/antville
|
||
//
|
||
// Copyright 2001–2014 by the Workers of Antville.
|
||
//
|
||
// 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.
|
||
|
||
/**
|
||
* @fileoverview Defines the Metadata prototype (version 2).
|
||
*/
|
||
|
||
/**
|
||
* Get an object representing the type properties settings suitable for
|
||
* defining prototypes with the definePrototype() method.
|
||
* @returns {Object} The type properties settings as object.
|
||
* @see <a href='http://helma.org/wiki/Defining+HopObject+mappings+programmatically'>Helma documentation</a>
|
||
*/
|
||
Metadata.getTypeProperties = function() {
|
||
return {
|
||
collection: 'Metadata',
|
||
'local.1': '$id',
|
||
'foreign.1': 'parent_id',
|
||
'local.2': '$prototype',
|
||
'foreign.2': 'parent_type',
|
||
accessName: 'name'
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Prepare a value for writing it to the metadata database table.
|
||
* The type of each metadata is stored along with its value.
|
||
* The normalize() method determines the type and possibly modifies
|
||
* the value accordingly.
|
||
* @param {Object} value
|
||
* @returns {Array} Compound value consisting of two elements,
|
||
* the (normalized) metadata value and its type.
|
||
*/
|
||
Metadata.normalize = function(value) {
|
||
if (value === null || value === undefined) {
|
||
return [null, null];
|
||
}
|
||
|
||
if (!value.constructor) {
|
||
value = String(value);
|
||
}
|
||
|
||
var Constructor = value.constructor;
|
||
switch (Constructor) {
|
||
case Boolean:
|
||
case String:
|
||
case Number:
|
||
value = String(value);
|
||
break;
|
||
|
||
case Date:
|
||
value = Number(value);
|
||
break;
|
||
|
||
default:
|
||
value = value.toSource();
|
||
}
|
||
return [value, Constructor.name];
|
||
}
|
||
|
||
/**
|
||
* @name Metadata
|
||
* @constructor
|
||
* @description The Metadata prototype provides means to store one metadata key-value
|
||
* pair per record in the metadata database table. Each record is assigned to a
|
||
* parent HopObject which is fitted with convenient methods to easily retrieve
|
||
* and modify the attached metadata objects.
|
||
* @see HopObject#handleMetadata
|
||
* @property {HopObject} parent The HopObject the metadata belongs to.
|
||
* @property {String} name The name (key) of the metadata object.
|
||
* @property {Object} value The value of the metadata object.
|
||
* @property {String} type The type of the metadata object.
|
||
*/
|
||
Metadata.prototype.constructor = function(parent, name, value) {
|
||
if (parent && name && value) {
|
||
this.parent = parent;
|
||
this.name = name;
|
||
this.setValue(value);
|
||
}
|
||
return this;
|
||
}
|
||
|
||
/**
|
||
* Set the value of a metadata object. If the value equals null
|
||
* the metadata object will be removed.
|
||
* @param {Object} value The desired metadata value.
|
||
*/
|
||
Metadata.prototype.setValue = function(value) {
|
||
[this.value, this.type] = Metadata.normalize(value);
|
||
if (this.value === null) {
|
||
this.remove();
|
||
}
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* Get the value of a metadata object.
|
||
* @returns {Object} The value of the metadata object.
|
||
*/
|
||
Metadata.prototype.getValue = function() {
|
||
var Constructor = global[this.type];
|
||
switch (Constructor) {
|
||
case null:
|
||
case undefined:
|
||
return null;
|
||
|
||
case Boolean:
|
||
return eval(this.value).valueOf();
|
||
|
||
case Date:
|
||
return new Date(Number(this.value));
|
||
|
||
case Number:
|
||
case String:
|
||
return (new Constructor(this.value)).valueOf();
|
||
|
||
default:
|
||
return eval(this.value);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get a textual representation of the metadata object.
|
||
* @returns {String} A textual representation of the metadata object.
|
||
*/
|
||
Metadata.prototype.toString = function() {
|
||
return 'Metadata of ' + this.parent + ' (' + this.name + ' = ' + this.value + ')';
|
||
}
|
||
|
||
/**
|
||
* Handle macros which are not defined elsewhere.
|
||
* @param {String} name The name of the macro.
|
||
* @returns {Object} The resulting value.
|
||
*/
|
||
// FIXME: Is this obsolete?
|
||
Metadata.prototype.onUnhandledMacro = function(name) {
|
||
return this.get(name);
|
||
}
|