
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1517412 13f79535-47bb-0310-9956-ffa450edef68
238 lines
5.8 KiB
JavaScript
238 lines
5.8 KiB
JavaScript
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you 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.
|
|
*/
|
|
|
|
/**
|
|
* Functions to help represent data as lists of elements and attributes.
|
|
*/
|
|
|
|
var element = "'element"
|
|
var attribute = "'attribute"
|
|
var atsign = "'@"
|
|
|
|
/**
|
|
* Return true if a value is an element.
|
|
*/
|
|
function isElement(v) {
|
|
return (!(!isList(v) || isNull(v) || car(v) != element));
|
|
}
|
|
|
|
/**
|
|
* Return true if a value is an attribute.
|
|
*/
|
|
function isAttribute(v) {
|
|
return (!(!isList(v) || isNull(v) || car(v) != attribute));
|
|
}
|
|
|
|
/**
|
|
* Return the name of an attribute.
|
|
*/
|
|
var attributeName = cadr;
|
|
|
|
/**
|
|
* Return the value of an attribute.
|
|
*/
|
|
var attributeValue = caddr;
|
|
|
|
/**
|
|
* Return the name of an element.
|
|
*/
|
|
var elementName = cadr;
|
|
|
|
/**
|
|
* Return true if an element has children.
|
|
*/
|
|
function elementHasChildren(l) {
|
|
return !isNull(l) && !isNull(cddr(l));
|
|
}
|
|
|
|
/**
|
|
* Return the children of an element.
|
|
*/
|
|
var elementChildren = cddr;
|
|
|
|
/**
|
|
* Return true if an element has a value.
|
|
*/
|
|
function elementHasValue(l) {
|
|
if (isNull(l))
|
|
return false;
|
|
var v = last(l);
|
|
if (isSymbol(v))
|
|
return false;
|
|
return (!(isList(v) && !isNull(v) && isSymbol(car(v))))
|
|
}
|
|
|
|
/**
|
|
* Return the value of an element.
|
|
*/
|
|
function elementValue(l) {
|
|
return last(l);
|
|
}
|
|
|
|
/**
|
|
* Convert an element to a value.
|
|
*/
|
|
function elementToValueIsList(v) {
|
|
if (!isList(v))
|
|
return false;
|
|
return isNull(v) || !isSymbol(car(v));
|
|
}
|
|
|
|
function elementToValue(t) {
|
|
if (isTaggedList(t, attribute))
|
|
return mklist(atsign + attributeName(t).substring(1), attributeValue(t));
|
|
if (isTaggedList(t, element)) {
|
|
if (elementHasValue(t)) {
|
|
if (!elementToValueIsList(elementValue(t)))
|
|
return mklist(elementName(t), elementValue(t));
|
|
return cons(elementName(t), mklist(elementsToValues(elementValue(t))));
|
|
}
|
|
return cons(elementName(t), elementsToValues(elementChildren(t)));
|
|
}
|
|
if (!isList(t))
|
|
return t;
|
|
return elementsToValues(t);
|
|
}
|
|
|
|
/**
|
|
* Convert a list of elements to a list of values.
|
|
*/
|
|
function elementToValueIsSymbol(v) {
|
|
return (!(!isList(v)) || isNull(v) || !isSymbol(car(v)));
|
|
}
|
|
|
|
function elementToValueGroupValues(v, l) {
|
|
if (isNull(l) || !elementToValueIsSymbol(v) || !elementToValueIsSymbol(car(l)))
|
|
return cons(v, l);
|
|
if (car(car(l)) != car(v))
|
|
return cons(v, l);
|
|
if (!elementToValueIsList(cadr(car(l)))) {
|
|
var g = mklist(car(v), mklist(cdr(v), cdr(car(l))));
|
|
return elementToValueGroupValues(g, cdr(l));
|
|
}
|
|
var g = mklist(car(v), cons(cdr(v), cadr(car(l))));
|
|
return elementToValueGroupValues(g, cdr(l));
|
|
}
|
|
|
|
function elementsToValues(e) {
|
|
if (isNull(e))
|
|
return e;
|
|
return elementToValueGroupValues(elementToValue(car(e)), elementsToValues(cdr(e)));
|
|
}
|
|
|
|
/**
|
|
* Convert a value to an element.
|
|
*/
|
|
function valueToElement(t) {
|
|
if (isList(t) && !isNull(t) && isSymbol(car(t))) {
|
|
var n = car(t);
|
|
var v = isNull(cdr(t))? nil : cadr(t);
|
|
if (!isList(v)) {
|
|
if (n.substring(0, 2) == atsign)
|
|
return mklist(attribute, "'" + n.substring(2), v);
|
|
return mklist(element, n, v);
|
|
}
|
|
if (isNull(v) || !isSymbol(car(v)))
|
|
return cons(element, cons(n, mklist(valuesToElements(v))));
|
|
return cons(element, cons(n, valuesToElements(cdr(t))));
|
|
}
|
|
if (!isList(t))
|
|
return t;
|
|
return valuesToElements(t);
|
|
}
|
|
|
|
/**
|
|
* Convert a list of values to a list of elements.
|
|
*/
|
|
function valuesToElements(l) {
|
|
if (isNull(l))
|
|
return l;
|
|
return cons(valueToElement(car(l)), valuesToElements(cdr(l)));
|
|
}
|
|
|
|
/**
|
|
* Return a selector lambda function which can be used to filter elements.
|
|
*/
|
|
function selector(s) {
|
|
function evalSelect(s, v) {
|
|
if (isNull(s))
|
|
return true;
|
|
if (!isList(v) || isNull(v))
|
|
return false;
|
|
if (car(s) != car(v))
|
|
return false;
|
|
return evalSelect(cdr(s), cdr(v));
|
|
}
|
|
|
|
return function(v) { return evalSelect(s, v); };
|
|
}
|
|
|
|
/**
|
|
* Return the attribute with the given name.
|
|
*/
|
|
function namedAttribute(name, l) {
|
|
return memo(l, name, function() {
|
|
var f = filter(function(v) { return isAttribute(v) && attributeName(v) == name; }, l);
|
|
if (isNull(f))
|
|
return null;
|
|
return car(f);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Return the value of the attribute with the given name.
|
|
*/
|
|
function namedAttributeValue(name, l) {
|
|
var a = namedAttribute(name, l);
|
|
if (a == null)
|
|
return null
|
|
return attributeValue(a);
|
|
}
|
|
|
|
/**
|
|
* Return child elements with the given name.
|
|
*/
|
|
function namedElementChildren(name, l) {
|
|
return memo(l, name, function() {
|
|
return filter(function(v) { return isElement(v) && elementName(v) == name; }, l);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Return the child element with the given name.
|
|
*/
|
|
function namedElementChild(name, l) {
|
|
var f = namedElementChildren(name, l);
|
|
if (isNull(f))
|
|
return null;
|
|
return car(f);
|
|
}
|
|
|
|
/**
|
|
* Side effect functions. Use with moderation.
|
|
*/
|
|
|
|
/**
|
|
* Set the contents of an element.
|
|
*/
|
|
function setElement(l, e) {
|
|
setList(l, e);
|
|
l.memo = {};
|
|
}
|
|
|