antville/code/Metadata/Metadata.js

152 lines
4.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// The Antville Project
// http://code.google.com/p/antville
//
// Copyright 20012014 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);
}