summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-12-11 08:59:40 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-12-11 08:59:40 +0000
commit7661a3bec8209546aa8219aa361cdcfd3391c246 (patch)
treeee7aff68d00cfbc089b2622613ef592630bf1bd8
parent7c6f4f6ff1c8653ff6110490ea5f5d5de941175d (diff)
Port XML, ATOM and SCDL parsing logic to Javascript. Implement minimal component rendering functions.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1044594 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/atomutil.js168
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/elemutil.js231
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/graph.js489
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/scdl.js109
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/util.js153
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/xmlutil.js188
-rwxr-xr-xsca-cpp/trunk/modules/server/server-conf6
7 files changed, 1316 insertions, 28 deletions
diff --git a/sca-cpp/trunk/modules/js/htdocs/atomutil.js b/sca-cpp/trunk/modules/js/htdocs/atomutil.js
new file mode 100644
index 0000000000..1c9137b668
--- /dev/null
+++ b/sca-cpp/trunk/modules/js/htdocs/atomutil.js
@@ -0,0 +1,168 @@
+/*
+ * 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.
+ */
+
+/**
+ * ATOM data conversion functions.
+ */
+
+/**
+ * Convert a list of elements to a list of values representing an ATOM entry.
+ */
+function entryElementsToValues(e) {
+ var lt = filter(selector(mklist(element, "'title")), e);
+ var t = isNil(lt)? '' : elementValue(car(lt));
+ var li = filter(selector(mklist(element, "'id")), e);
+ var i = isNil(li)? '' : elementValue(car(li));
+ var lc = filter(selector(mklist(element, "'content")), e);
+ return mklist(t, i, elementValue(car(lc)));
+}
+
+/**
+ * Convert a list of elements to a list of values representing ATOM entries.
+ */
+function entriesElementsToValues(e) {
+ if (isNil(e))
+ return e;
+ return cons(entryElementsToValues(car(e)), entriesElementsToValues(cdr(e)));
+}
+
+/**
+ * Convert a list of strings to a list of values representing an ATOM entry.
+ */
+function readATOMEntry(l) {
+ var e = readXML(l);
+ if (isNil(e))
+ return mklist();
+ return entryElementsToValues(car(e));
+}
+
+/**
+ * Convert a list of values representy an ATOM entry to a value.
+ */
+function entryValue(e) {
+ var v = elementsToValues(mklist(caddr(e)));
+ return cons(car(e), (cadr(e), cdr(car(v))));
+}
+
+/**
+ * Return true if a list of strings represents an ATOM feed.
+ */
+function isATOMFeed(l) {
+ if (isNil(l))
+ return false;
+ if (car(l).substring(0, 5) != "<?xml")
+ return false;
+ return car(l).match("<feed") != null;
+}
+
+/**
+ * Convert a DOM document to a list of values representing an ATOM feed.
+ */
+function readATOMFeedDocument(doc) {
+ var f = readXMLDocument(doc);
+ if (isNil(f))
+ return mklist();
+ var t = filter(selector(mklist(element, "'title")), car(f));
+ var i = filter(selector(mklist(element, "'id")), car(f));
+ var e = filter(selector(mklist(element, "'entry")), car(f));
+ if (isNil(e))
+ return mklist(elementValue(car(t)), elementValue(car(i)));
+ return cons(elementValue(car(t)), cons(elementValue(car(i)), entriesElementsToValues(e)));
+}
+
+/**
+ * Convert a list of strings to a list of values representing an ATOM feed.
+ */
+function readATOMFeed(l) {
+ return readAtomFeedDocument(parseXML(l));
+}
+
+/**
+ * Convert an ATOM feed containing elements to an ATOM feed containing values.
+ */
+function feedValuesLoop(e) {
+ if (isNil(e))
+ return e;
+ return cons(entryValue(car(e)), feedValuesLoop(cdr(e)));
+}
+
+function feedValues(e) {
+ return cons(car(e), cons(cadr(e), feedValuesLoop(cddr(e))));
+}
+
+/**
+ * Convert a list of values representy an ATOM entry to a list of elements.
+ */
+function entryElement(l) {
+ return mklist(element, "'entry", mklist(attribute, "'xmlns", "http://www.w3.org/2005/Atom"),
+ mklist(element, "'title", mklist(attribute, "'type", "text"), car(l)),
+ mklist(element, "'id", cadr(l)),
+ mklist(element, "'content", mklist(attribute, "'type", (isList(caddr(l))? "application/xml" : "text")), caddr(l)),
+ mklist(element, "'link", mklist(attribute, "'href", cadr(l))));
+}
+
+/**
+ * Convert a list of values representing ATOM entries to a list of elements.
+ */
+function entriesElements(l) {
+ if (isNil(l))
+ return l;
+ return cons(entryElement(car(l)), entriesElements(cdr(l)));
+}
+
+/**
+ * Convert a list of values representing an ATOM entry to an ATOM entry.
+ */
+function writeATOMEntry(l) {
+ return writeXML(mklist(entryElement(l)), true);
+}
+
+/**
+ * Convert a list of values representing an ATOM feed to an ATOM feed.
+ */
+function writeATOMFeed(l) {
+ var f = mklist(element, "'feed", mklist(attribute, "'xmlns", "http://www.w3.org/2005/Atom"),
+ mklist(element, "'title", mklist(attribute, "'type", "text"), car(l)),
+ mklist(element, "'id", cadr(l)));
+ if (isNil(cddr(l)))
+ return writeXML(mklist(f), true);
+ var fe = append(f, entriesElements(cddr(l)));
+ return writeXML(mklist(fe), true);
+}
+
+/**
+ * Convert an ATOM entry containing a value to an ATOM entry containing an item element.
+ */
+function entryValuesToElements(v) {
+ return cons(car(v), cons(cadr(v), valuesToElements(mklist(cons("'item", caddr(v))))));
+}
+
+/**
+ * Convert an ATOM feed containing values to an ATOM feed containing elements.
+ */
+function feedValuesToElementsLoop(v) {
+ if (isNil(v))
+ return v;
+ return cons(entryValuesToElements(car(v)), feedValuesToElementsLoop(cdr(v)));
+}
+
+function feedValuesToElements(v) {
+ return cons(car(v), cons(cadr(v), feedValuesToElementsLoop(cddr(v))));
+}
+
diff --git a/sca-cpp/trunk/modules/js/htdocs/elemutil.js b/sca-cpp/trunk/modules/js/htdocs/elemutil.js
new file mode 100644
index 0000000000..76eeb9d974
--- /dev/null
+++ b/sca-cpp/trunk/modules/js/htdocs/elemutil.js
@@ -0,0 +1,231 @@
+/*
+ * 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) {
+ if (!isList(v) || isNil(v) || car(v) != element)
+ return false;
+ return true;
+}
+
+/**
+ * Return true if a value is an attribute.
+ */
+function isAttribute(v) {
+ if (!isList(v) || isNil(v) || car(v) != attribute)
+ return false;
+ return true;
+}
+
+/**
+ * Return the name of an attribute.
+ */
+function attributeName(l) {
+ return cadr(l);
+}
+
+/**
+ * Return the value of an attribute.
+ */
+function attributeValue(l) {
+ return caddr(l);
+}
+
+/**
+ * Return the name of an element.
+ */
+function elementName(l) {
+ return cadr(l);
+}
+
+/**
+ * Return true if an element has children.
+ */
+function elementHasChildren(l) {
+ return !isNil(cddr(l));
+}
+
+/**
+ * Return the children of an element.
+ */
+function elementChildren(l) {
+ return cddr(l);
+}
+
+
+/**
+ * Return true if an element has a value.
+ */
+function elementHasValue(l) {
+ r = reverse(l);
+ if (isSymbol(car(r)))
+ return false;
+ if (isList(car(r)) && !isNil(car(r)) && isSymbol(car(car(r))))
+ return false;
+ return true;
+}
+
+/**
+ * Return the value of an element.
+ */
+function elementValue(l) {
+ return car(reverse(l));
+}
+
+/**
+ * Convert an element to a value.
+ */
+function elementToValueIsList(v) {
+ if (!isList(v))
+ return false;
+ return isNil(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) {
+ if (!isList(v))
+ return false;
+ if (isNil(v))
+ return false;
+ if (!isSymbol(car(v)))
+ return false;
+ return true;
+}
+
+function elementToValueGroupValues(v, l) {
+ if (isNil(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 (isNil(e))
+ return e;
+ return elementToValueGroupValues(elementToValue(car(e)), elementsToValues(cdr(e)));
+}
+
+/**
+ * Convert a value to an element.
+ */
+function valueToElement(t) {
+ if (isList(t) && !isNil(t) && isSymbol(car(t))) {
+ var n = car(t);
+ var v = cadr(t)
+ if (!isList(v)) {
+ if (n.substring(0, 2) == atsign)
+ return mklist(attribute, n.substring(1), v);
+ return mklist(element, n, v);
+ }
+ if (isNil(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 (isNil(l))
+ return l;
+ return cons(valueToElement(car(l)), valuesToElements(cdr(l)));
+}
+
+/**
+ * Return a selector lambda function which can be used to filter elements.
+ */
+function evalSelect(s, v) {
+ if (isNil(s))
+ return true;
+ if (isNil(v))
+ return false;
+ if (car(s) != car(v))
+ return false;
+ return evalSelect(cdr(s), cdr(v));
+}
+
+function selector(s) {
+ return function(v) { return evalSelect(s, v); };
+}
+
+/**
+ * Return the value of the attribute with the given name.
+ */
+function namedAttributeValue(name, l) {
+ var f = filter(function(v) { return isAttribute(v) && attributeName(v) == name; }, l);
+ if (isNil(f))
+ return null;
+ return caddr(car(f));
+}
+
+/**
+ * Return child elements with the given name.
+ */
+function namedElementChildren(name, l) {
+ 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 (isNil(f))
+ return null;
+ return car(f);
+}
+
diff --git a/sca-cpp/trunk/modules/js/htdocs/graph.js b/sca-cpp/trunk/modules/js/htdocs/graph.js
new file mode 100644
index 0000000000..07afa37a65
--- /dev/null
+++ b/sca-cpp/trunk/modules/js/htdocs/graph.js
@@ -0,0 +1,489 @@
+/*
+ * 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.
+ */
+
+/**
+ * SVG and VML component rendering functions.
+ */
+
+/**
+ * Detect browser VML support.
+ */
+function supportsVML() {
+ if (typeof supportsVML.supported != 'undefined')
+ return supportsVML.supported;
+ supportsVML.supported = navigator.appName == 'Microsoft Internet Explorer';
+ return supportsVML.supported;
+}
+
+/**
+ * Detect browser SVG support.
+ */
+function supportsSVG() {
+ if (typeof supportsSVG.supported != 'undefined')
+ return supportsSVG.supported;
+ supportsSVG.supported = navigator.appName != 'Microsoft Internet Explorer';
+ return supportsSVG.supported;
+}
+
+/**
+ * Basic colors
+ */
+var red = 'red';
+var green = 'green';
+var blue = 'blue';
+var yellow = 'yellow';
+var orange = '#ffa500';
+var gray = 'gray'
+
+/**
+ * Base path class.
+ */
+function BasePath() {
+ this.path = '';
+ this.x = 0;
+ this.y = 0;
+
+ this.pos = function(x, y) {
+ this.x = x;
+ this.y = y;
+ return this;
+ };
+
+ this.xpos = function() {
+ return this.x;
+ };
+
+ this.ypos = function() {
+ return this.y;
+ };
+
+ this.rmove = function(x, y) {
+ return this.move(this.x + x, this.y + y);
+ };
+
+ this.rline = function(x, y) {
+ return this.line(this.x + x, this.y + y);
+ };
+
+ this.rcurve = function(x1, y1, x, y) {
+ return this.curve(this.x + x1, this.y + y1, this.x + x1 + x, this.y + y1 + y);
+ };
+
+ this.str = function() {
+ return this.path;
+ };
+}
+
+/**
+ * Rendering functions that work both with VML and SVG.
+ */
+var mkgraph;
+var mkcompshape;
+var graph;
+
+/**
+ * VML rendering.
+ */
+if (supportsVML()) {
+
+ var vmlns='urn:schemas-microsoft-com:vml';
+
+ /**
+ * Make a shape path.
+ */
+ var mkpath = function() {
+ function Path() {
+ this.BasePath = BasePath;
+ this.BasePath();
+
+ this.move = function(x, y) {
+ this.path += 'M ' + x + ',' + y + ' ';
+ return this.pos(x, y);
+ };
+
+ this.line = function(x, y) {
+ this.path += 'L ' + x + ',' + y + ' ';
+ return this.pos(x, y);
+ };
+
+ this.curve = function(x1, y1, x, y) {
+ this.path += 'QB ' + x1 + ',' + y1 + ',' + x + ',' + y + ' ';
+ return this.pos(x, y);
+ };
+
+ this.end = function() {
+ this.path += 'X E';
+ return this;
+ };
+ }
+
+ return new Path();
+ }
+
+ /**
+ * Make a title element.
+ */
+ var mktitle = function(t) {
+ var title = document.createElement('v:textbox');
+ title.style.left = '40';
+ title.style.top = '30';
+ title.style.position = 'absolute';
+ var tnode = document.createTextNode(t);
+ title.appendChild(tnode);
+ return title;
+ }
+
+ /**
+ * Return the width of a title.
+ */
+ var textWidthDiv;
+
+ var titlewidth = function(t) {
+ textWidthDiv.innerHTML = t;
+ var twidth = textWidthDiv.offsetWidth + 10;
+ textWidthDiv.innerHTML = '';
+ return twidth;
+ }
+
+ /**
+ * Make a component shape.
+ */
+ mkcompshape = function(name, color, tsvcs, lsvcs, brefs, rrefs) {
+ var title = mktitle(name);
+ var twidth = titlewidth(name);
+
+ var d = mkcomppath(twidth, tsvcs, lsvcs, brefs, rrefs).str();
+
+ var shape = document.createElement('v:shape');
+ shape.style.width = 500;
+ shape.style.height = 500;
+ shape.coordsize = '500,500';
+ shape.path = d;
+ shape.fillcolor = color;
+ shape.stroked = 'false';
+
+ var contour = document.createElement('v:shape');
+ contour.style.width = 500;
+ contour.style.height = 500;
+ contour.coordsize = '500,500';
+ contour.setAttribute('path', d);
+ contour.filled = 'false';
+ contour.strokecolor = gray;
+ contour.strokeweight = '3';
+ contour.style.top = 1;
+ contour.style.left = 1;
+ var stroke = document.createElement('v:stroke');
+ stroke.opacity = '20%';
+ contour.appendChild(stroke);
+
+ var g = document.createElement('v:group');
+ g.style.width = 500;
+ g.style.height = 500;
+ g.coordsize = '500,500';
+ g.appendChild(shape);
+ g.appendChild(contour);
+ g.appendChild(title);
+ return g;
+ }
+
+ /**
+ * Drag and drop support.
+ */
+ var dragX;
+ var dragY;
+ var dragging = null;
+
+ /**
+ * Make a graph.
+ */
+ mkgraph = function() {
+ var div = document.createElement('div');
+ div.id = 'vmldiv';
+ document.body.appendChild(div);
+
+ textWidthDiv = document.createElement('span');
+ textWidthDiv.style.visibility = 'hidden'
+ div.appendChild(textWidthDiv);
+
+ var vmlg = document.createElement('v:group');
+ vmlg.style.width = 500;
+ vmlg.style.height = 500;
+ vmlg.coordsize = '500,500';
+ div.appendChild(vmlg);
+
+ function draggable(n) {
+ if (n == vmlg)
+ return null;
+ if (n.nodeName == 'group')
+ return n;
+ return draggable(n.parentNode);
+ }
+
+ vmlg.onmousedown = function() {
+ window.event.returnValue = false;
+ dragging = draggable(window.event.srcElement);
+ if (dragging == null)
+ return false;
+ dragging.parentNode.appendChild(dragging);
+ dragX = window.event.clientX;
+ dragY = window.event.clientY;
+ vmlg.setCapture();
+ return false;
+ };
+
+ vmlg.onmouseup = function() {
+ if (dragging == null)
+ return false;
+ dragging = null;
+ vmlg.releaseCapture();
+ return false;
+ };
+
+ vmlg.onmousemove = function() {
+ if (dragging == null)
+ return false;
+ var origX = dragging.coordorigin.X;
+ var origY = dragging.coordorigin.Y;
+ var newX = origX - (window.event.clientX - dragX);
+ var newY = origY - (window.event.clientY - dragY);
+ dragX = window.event.clientX;
+ dragY = window.event.clientY;
+ dragging.setAttribute('coordorigin', newX + ' ' + newY);
+ return false;
+ };
+
+ graph = vmlg;
+ return vmlg;
+ }
+
+ document.write('<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />');
+}
+
+/**
+ * SVG rendering.
+ */
+if (supportsSVG()) {
+
+ var svgns='http://www.w3.org/2000/svg';
+
+ /**
+ * Make a shape path.
+ */
+ var mkpath = function() {
+ function Path() {
+ this.BasePath = BasePath;
+ this.BasePath();
+
+ this.move = function(x, y) {
+ this.path += 'M' + x + ',' + y + ' ';
+ return this.pos(x, y);
+ };
+
+ this.line = function(x, y) {
+ this.path += 'L' + x + ',' + y + ' ';
+ return this.pos(x, y);
+ };
+
+ this.curve = function(x1, y1, x, y) {
+ this.path += 'Q' + x1 + ',' + y1 + ' ' + x + ',' + y + ' ';
+ return this.pos(x, y);
+ };
+
+ this.end = function() {
+ this.path += 'Z';
+ return this;
+ };
+ }
+
+ return new Path();
+ }
+
+ /**
+ * Make a title element.
+ */
+ var mktitle = function(t) {
+ var title = document.createElementNS(svgns, 'text');
+ title.setAttribute('text-anchor', 'start');
+ title.setAttribute('x', 40);
+ title.setAttribute('y', 50);
+ title.appendChild(document.createTextNode(t));
+ graph.appendChild(title);
+ return title;
+ }
+
+ /**
+ * Make a component shape.
+ */
+ mkcompshape = function(name, color, tsvcs, lsvcs, brefs, rrefs) {
+ var title = mktitle(name);
+ var twidth = title.getBBox().width;
+
+ var d = mkcomppath(twidth, tsvcs, lsvcs, brefs, rrefs).str();
+
+ var shape = document.createElementNS(svgns, 'path');
+ shape.setAttribute('d', d);
+ shape.setAttribute('fill', color);
+
+ var contour = document.createElementNS(svgns, 'path');
+ contour.setAttribute('d', d);
+ contour.setAttribute('fill', 'none');
+ contour.setAttribute('stroke', gray);
+ contour.setAttribute('stroke-width', '4');
+ contour.setAttribute('stroke-opacity', '0.20');
+ contour.setAttribute('transform', 'translate(1,1)');
+
+ var g = document.createElementNS(svgns, 'g');
+ g.appendChild(shape);
+ g.appendChild(contour);
+ g.appendChild(title);
+ return g;
+ }
+
+ /**
+ * Drag and drop support.
+ */
+ var dragX;
+ var dragY;
+ var dragging = null;
+
+ /**
+ * Make a graph.
+ */
+ mkgraph = function() {
+ var div = document.createElement('div');
+ div.id = 'svgdiv';
+ document.body.appendChild(div);
+
+ var svg = document.createElementNS(svgns, 'svg');
+ svg.style.height = '100%';
+ svg.style.width = '100%';
+ div.appendChild(svg);
+
+ function draggable(n) {
+ if (n == svg)
+ return null;
+ if (n.nodeName == 'g')
+ return n;
+ return draggable(n.parentNode);
+ }
+
+ svg.onmousedown = function(e) {
+ if (e.preventDefault)
+ e.preventDefault();
+ else
+ e.returnValue= false;
+ dragging = draggable(e.target);
+ if (dragging == null)
+ return false;
+ dragging.parentNode.appendChild(dragging);
+ var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
+ dragX = pos.clientX;
+ dragY = pos.clientY;
+ return false;
+ };
+
+ svg.ontouchstart = svg.onmousedown;
+
+ svg.onmouseup = function(e) {
+ if (dragging == null)
+ return false;
+ dragging = null;
+ return false;
+ };
+
+ svg.ontouchend = svg.onmouseup;
+
+ svg.onmousemove = function(e) {
+ if (dragging == null)
+ return false;
+ var matrix = dragging.getCTM();
+ var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
+ var newX = Number(matrix.e) + (pos.clientX - dragX);
+ var newY = Number(matrix.f) + (pos.clientY - dragY);
+ dragX = pos.clientX;
+ dragY = pos.clientY;
+ dragging.setAttribute('transform', 'translate(' + newX + ',' + newY + ')');
+ return false;
+ };
+
+ svg.ontouchmove = svg.onmousemove;
+
+ graph = svg;
+ return svg;
+ }
+}
+
+/**
+ * Make a reference shape path, positioned to the right of a component shape.
+ */
+function mkrrefpath(path) {
+ return path.rline(0,10).rcurve(0,5,-5,0).rcurve(-5,0,0,-5).rcurve(0,-5,-5,0).rcurve(-5,0,0,5).rline(0,20).rcurve(0,5,5,0).rcurve(5,0,0,-5).rcurve(0,-5,5,0).rcurve(5,0,0,5).rline(0,10);
+}
+
+/**
+ * Make a reference shape path, positioned at the bottom of a component shape.
+ */
+function mkbrefpath(path) {
+ return path.rline(-10,0).rcurve(-5,0,0,-5).rcurve(0,-5,5,0).rcurve(5,0,0,-5).rcurve(0,-5,-5,0).rline(-20,0).rcurve(-5,0,0,5).rcurve(0,5,5,0).rcurve(5,0,0,5).rcurve(0,5,-5,0).rline(-10,0);
+}
+
+/**
+ * Make a service shape path, positioned to the left of a component shape.
+ */
+function mklsvcpath(path) {
+ return path.rline(0,-10).rcurve(0,-5,-5,0).rcurve(-5,0,0,5).rcurve(0,5,-5,0).rcurve(-5,0,0,-5).rline(0,-20).rcurve(0,-5,5,0).rcurve(5,0,0,5).rcurve(0,5,5,0).rcurve(5,0,0,-5).rline(0,-10);
+}
+
+/**
+ * Make a service shape path, positioned at the top of a component shape.
+ */
+function mktsvcpath(path) {
+ return path.rline(10,0).rcurve(5,0,0,-5).rcurve(0,-5,-5,0).rcurve(-5,0,0,-5).rcurve(0,-5,5,0).rline(20,0).rcurve(5,0,0,5).rcurve(0,5,-5,0).rcurve(-5,0,0,5).rcurve(0,5,5,0).rline(10,0);
+}
+
+
+/**
+* Make a component shape path.
+*/
+function mkcomppath(twidth, tsvcs, lsvcs, brefs, rrefs) {
+ var height = Math.max(lsvcs, rrefs) * 40 + 60;
+ var width = Math.max(Math.max(tsvcs, brefs) * 40 + 60, twidth + 20);
+
+ var path = mkpath().rmove(40,30).rline(20,0);
+ for (var s = 0; s < tsvcs; s++)
+ path = mktsvcpath(path);
+
+ path = path.line(20 + width,path.ypos()).rcurve(10,0,0,10).rline(0,20);
+ for (var r = 0; r < rrefs; r++)
+ path = mkrrefpath(path);
+
+ var boffset = 10 + 30 + (brefs * 40);
+ path = path.line(path.xpos(),20 + height).rcurve(0,10,-10,0).line(20 + boffset,path.ypos());
+ for (var r = 0; r < brefs; r++)
+ path = mkbrefpath(path);
+
+ var loffset = 10 + 30 + (lsvcs * 40);
+ path = path.line(40,path.ypos()).rcurve(-10,0,0,-10).line(path.xpos(), 20 + loffset);
+ for (var s = 0; s < lsvcs; s++)
+ path = mklsvcpath(path);
+
+ path = path.line(30,40).rcurve(0,-10,10,0);
+ return path.end();
+}
+
diff --git a/sca-cpp/trunk/modules/js/htdocs/scdl.js b/sca-cpp/trunk/modules/js/htdocs/scdl.js
index a98056d790..5f3934b060 100644
--- a/sca-cpp/trunk/modules/js/htdocs/scdl.js
+++ b/sca-cpp/trunk/modules/js/htdocs/scdl.js
@@ -21,4 +21,113 @@
* SCDL parsing functions.
*/
+/**
+ * Returns a list of components in a composite.
+ */
+function components(l) {
+ var cs = namedElementChildren("'composite", l);
+ if (isNil(cs))
+ return cs;
+ return namedElementChildren("'component", car(cs));
+}
+
+/**
+ * Returns the name of a component, service or reference.
+ */
+function name(l) {
+ return namedAttributeValue("'name", l);
+}
+
+/**
+ * Returns the implementation of a component.
+ */
+function implementation(l) {
+ function filterImplementation(v) {
+ return isElement(v) && cadr(v).match("implementation.") != null;
+ }
+
+ var n = filter(filterImplementation, l);
+ if (isNil(n))
+ return null;
+ return car(n);
+}
+
+/**
+ * Returns the type of an implementation.
+ */
+function implementationType(l) {
+ return elementName(l).substring(1);
+}
+
+/**
+ * Returns the URI of a service, reference or implementation.
+ */
+function uri(l) {
+ return namedAttributeValue("'uri", l);
+}
+
+/**
+ * Returns a list of services in a component.
+ */
+function services(l) {
+ return namedElementChildren("'service", l);
+}
+
+/**
+ * Returns a list of references in a component.
+ */
+function references(l) {
+ return namedElementChildren("'reference", l);
+}
+
+/**
+ * Returns a list of bindings in a service or reference.
+ */
+function bindings(l) {
+ function filterBinding(v) {
+ return isElement(v) && cadr(v).match("binding.") != null;
+ }
+
+ return filter(filterBinding, l);
+}
+
+/**
+ * Returns the type of a binding.
+ */
+function bindingType(l) {
+ return elementName(l).substring(1);
+}
+
+/**
+ * Returns the target of a reference.
+ */
+function target(l) {
+ function bindingsTarget(l) {
+ if (isNil(l))
+ return null;
+ var u = uri(car(l));
+ if (!isNil(u))
+ return u;
+ return bindingsTarget(cdr(l));
+ }
+
+ var t = namedAttributeValue("'target", l);
+ if (!isNil(t))
+ return t;
+ return bindingsTarget(bindings(l));
+}
+
+/**
+ * Returns a list of properties in a component.
+ */
+function properties(l) {
+ return namedElementChildren("'property", l);
+}
+
+/**
+ * Returns the value of a property.
+ */
+function propertyValue(l) {
+ return elementValue(l);
+}
diff --git a/sca-cpp/trunk/modules/js/htdocs/util.js b/sca-cpp/trunk/modules/js/htdocs/util.js
index 96a84af6d6..da069d7ae6 100644
--- a/sca-cpp/trunk/modules/js/htdocs/util.js
+++ b/sca-cpp/trunk/modules/js/htdocs/util.js
@@ -18,11 +18,11 @@
*/
/**
- * Utility functions.
+ * Simple utility functions.
*/
/**
- * Simple scheme-like lists.
+ * Scheme-like lists.
*/
function cons(car, cdr) {
return new Array(car).concat(cdr);
@@ -32,10 +32,76 @@ function car(l) {
return l[0];
}
+function first(l) {
+ return car(l);
+}
+
function cdr(l) {
return l.slice(1);
}
+function rest(l) {
+ return cdr(l);
+}
+
+function cadr(l) {
+ return car(cdr(l));
+}
+
+function cddr(l) {
+ return cdr(cdr(l));
+}
+
+function caddr(l) {
+ return car(cddr(l));
+}
+
+function append(a, b) {
+ return a.concat(b);
+}
+
+function reverse(l) {
+ return l.slice(0).reverse();
+}
+
+function isNil(v) {
+ if (v == null)
+ return true;
+ if ('' + v == 'undefined')
+ return true;
+ try {
+ if (isList(v) && v.length == 0)
+ return true;
+ } catch (e) {}
+ return false;
+}
+
+function isSymbol(v) {
+ if (typeof v == 'string' && v.slice(0, 1) == "'")
+ return true;
+ return false;
+}
+
+function isString(v) {
+ if (typeof v == 'string')
+ return true;
+ return false;
+}
+
+function isList(v) {
+ try {
+ if (v.constructor == Array)
+ return true;
+ } catch (e) {}
+ return false;
+}
+
+function isTaggedList(v, t) {
+ if (isList(v) && !isNil(v) && car(v) == t)
+ return true;
+ return false;
+}
+
function mklist() {
var a = new Array();
for (i = 0; i < arguments.length; i++)
@@ -43,39 +109,38 @@ function mklist() {
return a;
}
-function isList(v) {
- return toString.call(v) === '[object Array]';
-}
-
-function isNil(v) {
- return v == 'undefined' || v == null;
+/**
+ * Scheme-like associations.
+ */
+function assoc(k, l) {
+ if (isNil(l))
+ return mklist();
+ if (k == car(car(l)))
+ return car(l);
+ return assoc(k, cdr(l));
}
-function isEmpty(l) {
- return l.length == 0;
+/**
+ * Map and filter functions.
+ */
+function map(f, l) {
+ if (isNil(l))
+ return l;
+ return cons(f(car(l)), map(f, cdr(l)));
}
-/**
- * convert an array or object to a non-sparse array.
- */
-function array(obj) {
- if (isNil(obj.length)) {
- var a = new Array();
- a[0] = obj;
- return a;
- } else {
- var a = new Array();
- var n = 0;
- for (var i in obj)
- a[n++] = obj[i];
- return a;
- }
+function filter(f, l) {
+ if (isNil(l))
+ return l;
+ if (f(car(l)))
+ return cons(car(l), filter(f, cdr(l)));
+ return filter(f, cdr(l));
}
/**
- * Dump an object to the console.
+ * Dump an object to the debug console.
*/
-function dump(o) {
+function debug(o) {
for (f in o) {
try {
console.log(f + '=' + o[f]);
@@ -83,3 +148,37 @@ function dump(o) {
}
}
+/**
+ * Write a list of strings.
+ */
+function writeStrings(l) {
+ if (isNil(l))
+ return '';
+ return car(l) + writeStrings(cdr(l));
+}
+
+/**
+ * Write a value using a Scheme-like syntax.
+ */
+function writeValue(v) {
+ function writePrimitive(p) {
+ if (isSymbol(p))
+ return '' + p.substring(1);
+ if (isString(p))
+ return '"' + p + '"';
+ return '' + p;
+ }
+
+ function writeList(l) {
+ if (isNil(l))
+ return '';
+ return ' ' + writeValue(car(l)) + writeList(cdr(l));
+ }
+
+ if (!isList(v))
+ return writePrimitive(v);
+ if (isNil(v))
+ return '()';
+ return '(' + writeValue(car(v)) + writeList(cdr(v)) + ')';
+}
+
diff --git a/sca-cpp/trunk/modules/js/htdocs/xmlutil.js b/sca-cpp/trunk/modules/js/htdocs/xmlutil.js
new file mode 100644
index 0000000000..121bf8692c
--- /dev/null
+++ b/sca-cpp/trunk/modules/js/htdocs/xmlutil.js
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+
+/**
+ * XML handling functions.
+ */
+
+/**
+ * Convert a DOM node list to a regular list.
+ */
+function nodeList(n) {
+ var l = new Array();
+ if (isNil(n))
+ return l;
+ for (var i = 0; i < n.length; i++)
+ l[i] = n[i];
+ return l;
+}
+
+/**
+ * Return the child attributes of an element.
+ */
+function childAttributes(e) {
+ return filter(function(n) { return n.nodeType == 2; }, nodeList(e.attributes));
+}
+
+/**
+ * Return the child elements of an element.
+ */
+function childElements(e) {
+ return filter(function(n) { return n.nodeType == 1; }, nodeList(e.childNodes));
+}
+
+/**
+ * Return the child text nodes of an element.
+ */
+function childText(e) {
+ return filter(function(n) { return n.nodeType == 3; }, nodeList(e.childNodes));
+}
+
+/**
+ * Read a list of XML attributes.
+ */
+function readAttributes(a) {
+ if (isNil(a))
+ return a;
+ return cons(mklist(attribute, "'" + car(a).nodeName, car(a).nodeValue), readAttributes(cdr(a)));
+}
+
+/**
+ * Read an XML element.
+ */
+function readElement(e) {
+ var l = append(append(mklist(element, "'" + e.nodeName), readAttributes(childAttributes(e))), readElements(childElements(e)));
+ var t = childText(e);
+ if (isNil(t))
+ return l;
+ return append(l, mklist(car(t).nodeValue));
+}
+
+/**
+ * Read a list of XML elements.
+ */
+function readElements(l) {
+ if (isNil(l))
+ return l;
+ return cons(readElement(car(l)), readElements(cdr(l)));
+}
+
+/**
+ * Parse a list of strings representing an XML document.
+ */
+function parseXML(l) {
+ var s = writeStrings(l);
+ if (window.DOMParser) {
+ var p =new DOMParser();
+ return p.parseFromString(s, "text/xml");
+ }
+ var doc;
+ try {
+ doc = new ActiveXObject("MSXML2.DOMDocument");
+ } catch (e) {
+ doc = new ActiveXObject("Microsoft.XMLDOM");
+ }
+ doc.async = 'false';
+ doc.loadXML(s);
+ return doc;
+}
+
+/**
+ * Read a list of values from an XML document.
+ */
+function readXMLDocument(doc) {
+ var root = nodeList(doc.childNodes);
+ if (isNil(root))
+ return mklist();
+ return mklist(readElement(car(root)));
+}
+
+/**
+ * Read a list of values from a list of strings representing an XML document.
+ */
+function readXML(l) {
+ return readXMLDocument(parseXML(l));
+}
+
+/**
+ * Make an XML document.
+ */
+/**
+ * Return a list of strings representing an XML document.
+ */
+function writeXMLDocument(doc) {
+ if (typeof(XMLSerializer) != 'undefined')
+ return mklist(new XMLSerializer().serializeToString(doc));
+ return mklist(doc.xml);
+}
+
+/**
+ * Write a list of XML element and attribute tokens.
+ */
+function expandElementValues(n, l) {
+ if (isNil(l))
+ return l;
+ return cons(cons(element, cons(n, car(l))), expandElementValues(n, cdr(l)));
+}
+
+function writeList(l, node, doc) {
+ if (isNil(l))
+ return node;
+ var token = car(l);
+ if (isTaggedList(token, attribute)) {
+ node.setAttribute(attributeName(token).substring(1), '' + attributeValue(token));
+ } else if (isTaggedList(token, element)) {
+ if (elementHasValue(token)) {
+ var v = elementValue(token);
+ if (isList(v)) {
+ var e = expandElementValues(elementName(token), v);
+ writeList(e, node, doc);
+ } else {
+ var child = doc.createElement(elementName(token).substring(1));
+ writeList(elementChildren(token), child, doc);
+ node.appendChild(child);
+ }
+ } else {
+ var child = doc.createElement(elementName(token).substring(1));
+ writeList(elementChildren(token), child, doc);
+ node.appendChild(child);
+ }
+ } else
+ node.appendChild(doc.createTextNode('' + token));
+ writeList(cdr(l), node, doc);
+ return node;
+}
+
+/**
+ * Convert a list of values to a list of strings representing an XML document.
+ */
+function writeXML(l, xmlTag) {
+ function mkdoc() {
+ if (document.implementation && document.implementation.createDocument)
+ return document.implementation.createDocument('', '', null);
+ return new ActiveXObject("MSXML2.DOMDocument");
+ }
+
+ var doc = mkdoc();
+ writeList(l, doc, doc);
+ if (!xmlTag)
+ return writeXMLDocument(doc);
+ return mklist('<?xml version="1.0" encoding="UTF-8"?>\n' + writeXMLDocument(doc) + '\n');
+}
+
diff --git a/sca-cpp/trunk/modules/server/server-conf b/sca-cpp/trunk/modules/server/server-conf
index b4984e2701..742d48d614 100755
--- a/sca-cpp/trunk/modules/server/server-conf
+++ b/sca-cpp/trunk/modules/server/server-conf
@@ -57,10 +57,14 @@ SCAWiringServerName $servername
# Serve JavaScript client scripts
Alias /component.js $jsprefix/htdocs/component.js
-Alias /scdl.js $jsprefix/htdocs/scdl.js
Alias /util.js $jsprefix/htdocs/util.js
+Alias /elemutil.js $jsprefix/htdocs/elemutil.js
+Alias /xmlutil.js $jsprefix/htdocs/xmlutil.js
+Alias /atomutil.js $jsprefix/htdocs/atomutil.js
Alias /ui.js $jsprefix/htdocs/ui.js
Alias /ui.css $jsprefix/htdocs/ui.css
+Alias /scdl.js $jsprefix/htdocs/scdl.js
+Alias /graph.js $jsprefix/htdocs/graph.js
<Location /component.js>
AuthType None