You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by js...@apache.org on 2011/01/06 08:12:30 UTC

svn commit: r1055767 - in /tuscany/sca-cpp/trunk/modules: edit/ edit/domains/relay/ edit/domains/store/ edit/htdocs/ edit/htdocs/edit/ js/htdocs/ scdl/

Author: jsdelfino
Date: Thu Jan  6 07:12:30 2011
New Revision: 1055767

URL: http://svn.apache.org/viewvc?rev=1055767&view=rev
Log:
Support service promotion and improve component layout algorithm.

Added:
    tuscany/sca-cpp/trunk/modules/edit/htdocs/edit/graph.js
      - copied, changed from r1054345, tuscany/sca-cpp/trunk/modules/edit/htdocs/graph.js
Removed:
    tuscany/sca-cpp/trunk/modules/edit/htdocs/graph.js
Modified:
    tuscany/sca-cpp/trunk/modules/edit/Makefile.am
    tuscany/sca-cpp/trunk/modules/edit/domains/relay/app.composite
    tuscany/sca-cpp/trunk/modules/edit/domains/store/app.composite
    tuscany/sca-cpp/trunk/modules/edit/htdocs/edit/edit.html
    tuscany/sca-cpp/trunk/modules/edit/htdocs/edit/index.html
    tuscany/sca-cpp/trunk/modules/js/htdocs/scdl.js
    tuscany/sca-cpp/trunk/modules/js/htdocs/ui.js
    tuscany/sca-cpp/trunk/modules/scdl/scdl.hpp

Modified: tuscany/sca-cpp/trunk/modules/edit/Makefile.am
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/Makefile.am?rev=1055767&r1=1055766&r2=1055767&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/modules/edit/Makefile.am Thu Jan  6 07:12:30 2011
@@ -17,6 +17,6 @@
 
 
 moddir = $(prefix)/modules/js
-nobase_dist_mod_DATA = htdocs/*.js htdocs/*.html
-EXTRA_DIST = htdocs/*.js htdocs/*.html
+nobase_dist_mod_DATA = htdocs/*.html htdocs/main/*.html htdocs/edit/*.html htdocs/edit/*.js
+EXTRA_DIST = htdocs/*.html htdocs/main/*.html htdocs/edit/*.html htdocs/edit/*.js
 

Modified: tuscany/sca-cpp/trunk/modules/edit/domains/relay/app.composite
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/domains/relay/app.composite?rev=1055767&r1=1055766&r2=1055767&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/domains/relay/app.composite (original)
+++ tuscany/sca-cpp/trunk/modules/edit/domains/relay/app.composite Thu Jan  6 07:12:30 2011
@@ -22,7 +22,13 @@
   targetNamespace="http://relay"
   name="relay">
         
-    <component name="JSONTwit">
+    <service name="JSONTwit" promote="JSONTwit"/>
+    <service name="XMLTwit" promote="XMLTwit"/>
+    <service name="RSSTwit" promote="RSSTwit"/>
+    <service name="HTML" promote="HTML"/>
+    <service name="JSONFB" promote="JSONFB"/>
+
+    <component name="JSONTwit" color="red">
         <t:implementation.python script="relay.py"/>
         <service name="Relay">
             <t:binding.http uri="jsontwit"/>
@@ -32,7 +38,7 @@
         </reference>
     </component>
     
-    <component name="XMLTwit">
+    <component name="XMLTwit" color="green">
         <t:implementation.python script="relay.py"/>
         <service name="Relay">
             <t:binding.http uri="xmltwit"/>
@@ -42,7 +48,7 @@
         </reference>
     </component>
     
-    <component name="RSSTwit">
+    <component name="RSSTwit" color="blue">
         <t:implementation.python script="relay.py"/>
         <service name="Relay">
             <t:binding.http uri="rsstwit"/>
@@ -52,7 +58,7 @@
         </reference>
     </component>
     
-    <component name="HTML">
+    <component name="HTML" color="yellow">
         <t:implementation.python script="relay.py"/>
         <service name="Relay">
             <t:binding.http uri="html"/>
@@ -62,7 +68,7 @@
         </reference>
     </component>
     
-    <component name="JSONFB">
+    <component name="JSONFB" color="orange">
         <t:implementation.python script="relay.py"/>
         <service name="Relay">
             <t:binding.http uri="jsonfb"/>

Modified: tuscany/sca-cpp/trunk/modules/edit/domains/store/app.composite
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/domains/store/app.composite?rev=1055767&r1=1055766&r2=1055767&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/domains/store/app.composite (original)
+++ tuscany/sca-cpp/trunk/modules/edit/domains/store/app.composite Thu Jan  6 07:12:30 2011
@@ -21,18 +21,21 @@
   xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
   targetNamespace="http://store"
   name="store">
-        
-    <component name="Store">
+
+    <service name="Store" promote="Store"/>
+    <service name="ShoppingCart" promote="ShoppingCart"/>
+
+    <component name="Store" color="green">
         <t:implementation.python script="store.py"/>
         <service name="Widget">
             <t:binding.http uri="store"/>
         </service>
         <reference name="catalog" target="Catalog"/>
-        <reference name="shoppingCart" target="ShoppingCart/Cart"/>
-        <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+        <reference name="shoppingCart" target="ShoppingCart"/>
+        <reference name="shoppingTotal" target="ShoppingCart"/>
     </component>
     
-    <component name="Catalog">
+    <component name="Catalog" color="yellow">
         <t:implementation.python script="fruits-catalog.py"/> 
         <property name="currencyCode">USD</property>
         <service name="Catalog">
@@ -41,25 +44,22 @@
         <reference name="currencyConverter" target="CurrencyConverter"/>
     </component> 
      
-    <component name="ShoppingCart">
+    <component name="ShoppingCart" color="magenta">
         <t:implementation.python script="shopping-cart.py"/>
         <service name="ShoppingCart">
-            <t:binding.atom uri="shoppingCart"/>
-        </service>        
-        <service name="Total">
-            <t:binding.jsonrpc uri="total"/>
+            <t:binding.http uri="shoppingCart"/>
         </service>        
         <reference name="cache" target="Cache"/>
     </component>
     
-    <component name="CurrencyConverter">
+    <component name="CurrencyConverter" color="blue">
         <t:implementation.python script="currency-converter.py"/>
         <service name="CurrencyConverter">
             <t:binding.jsonrpc uri="currencyConverter"/>
         </service>        
     </component>     
 
-    <component name="Cache">
+    <component name="Cache" color="orange">
         <implementation.cpp path="../../components/cache" library="libmemcache"/>
         <service name="Cache">
             <t:binding.atom uri="cache"/>

Modified: tuscany/sca-cpp/trunk/modules/edit/htdocs/edit/edit.html
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/htdocs/edit/edit.html?rev=1055767&r1=1055766&r2=1055767&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/htdocs/edit/edit.html (original)
+++ tuscany/sca-cpp/trunk/modules/edit/htdocs/edit/edit.html Thu Jan  6 07:12:30 2011
@@ -26,7 +26,7 @@
 <script type="text/javascript" src="/scdl.js"></script>
 <script type="text/javascript" src="/ui.js"></script>
 <script type="text/javascript" src="/component.js"></script>
-<script type="text/javascript" src="/graph.js"></script>
+<script type="text/javascript" src="/edit/graph.js"></script>
 </head>  
 <body>
 
@@ -39,20 +39,14 @@ var apps = sca.reference(editWidget, "ap
  * Return the current app name.
  */
 function appname() {
-    var qs = window.location.toString().split('?');
-    if (isNil(cdr(qs)))
-        return null;
-    var p = cadr(qs).split('=');
-    if (isNil(p) || isNil(cdr(p)))
-        return null;
-    return cadr(p);
+    return ui.queryParams()['app'];
 }
 
 /**
  * Get an app and display it.
  */
 function getapp(name) {
-    if (name == null)
+    if (isNil(name))
         return;
     apps.get(name, function(doc) {
         var entry = atom.readATOMEntryDocument(doc);
@@ -62,7 +56,6 @@ function getapp(name) {
 
         var g = graph.mkgraph();
         var shapes = graph.composite(composite);
-        log(shapes);
         for (var s in shapes)
             g.appendChild(shapes[s]);
     });

Copied: tuscany/sca-cpp/trunk/modules/edit/htdocs/edit/graph.js (from r1054345, tuscany/sca-cpp/trunk/modules/edit/htdocs/graph.js)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/htdocs/edit/graph.js?p2=tuscany/sca-cpp/trunk/modules/edit/htdocs/edit/graph.js&p1=tuscany/sca-cpp/trunk/modules/edit/htdocs/graph.js&r1=1054345&r2=1055767&rev=1055767&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/htdocs/graph.js (original)
+++ tuscany/sca-cpp/trunk/modules/edit/htdocs/edit/graph.js Thu Jan  6 07:12:30 2011
@@ -52,7 +52,7 @@ graph.colors.blue = '#0000ff';
 graph.colors.cyan = '#00ffff';
 graph.colors.gray = '#808080'
 graph.colors.green = '#008000';
-graph.colors.magenta = '#008000';
+graph.colors.magenta = '#ff00ff';
 graph.colors.orange = '#ffa500';
 graph.colors.pink = '#ffc0cb';
 graph.colors.purple = '#800080';
@@ -102,7 +102,6 @@ graph.BasePath = function() {
 /**
  * Rendering functions that work both with VML and SVG.
  */
-var graph;
 
 /**
  * VML rendering.
@@ -184,6 +183,10 @@ if (graph.supportsVML()) {
             this.BasePath = graph.BasePath;
             this.BasePath();
 
+            this.clone = function() {
+                return graph.mkpath().pos(this.xpos(), this.ypos());
+            };
+
             this.move = function(x, y) {
                 this.path += 'M ' + x + ',' + y + ' '; 
                 return this.pos(x, y);
@@ -209,14 +212,14 @@ if (graph.supportsVML()) {
     };
 
     /**
-     * Make a title element.
+     * Return an element representing the title of a component.
      */
-    graph.mktitle = function(comp) {
+    graph.title = function(comp) {
         var t = scdl.name(comp);
         var tsvcs = graph.tsvcs(comp);
         var lsvcs = graph.lsvcs(comp);
         var title = document.createElement('v:textbox');
-        title.style.left = '' + (isNil(lsvcs)? 7 : 27);
+        title.style.left = '' + (isNil(lsvcs)? 5 : 25);
         title.style.top = '' + (isNil(tsvcs)? 5 : 25);
         title.style.position = 'absolute';
         var tnode = document.createTextNode(t);
@@ -225,7 +228,7 @@ if (graph.supportsVML()) {
     };
 
     /**
-     * Return the width of a title.
+     * Return the width of the title of a component.
      */
     graph.titlewidth = function(comp) {
         var t = scdl.name(comp);
@@ -236,12 +239,12 @@ if (graph.supportsVML()) {
     };
 
     /**
-     * Make a component shape.
+     * Return a shape representing a component.
      */
-    graph.mkcompshape = function(comp, cassoc) {
-        var title = graph.mktitle(comp);
+    graph.compshape = function(comp, cassoc, pos) {
+        var title = graph.title(comp);
 
-        var d = graph.mkcomppath(comp, cassoc).str();
+        var d = graph.comppath(comp, cassoc).str();
 
         var shape = document.createElement('v:shape');
         shape.style.width = 500;
@@ -259,19 +262,22 @@ if (graph.supportsVML()) {
         contour.filled = 'false';
         contour.strokecolor = graph.colors.gray;
         contour.strokeweight = '2';
-        contour.style.top = 1;
         contour.style.left = 1;
+        contour.style.top = 1;
         var stroke = document.createElement('v:stroke');
         stroke.opacity = '20%';
         contour.appendChild(stroke);
 
         var g = document.createElement('v:group');
+        g.id = scdl.name(comp);
         g.style.width = 500;
         g.style.height = 500;
         g.coordsize = '500,500';
+        g.style.left = pos.xpos();
+        g.style.top = pos.ypos();
         g.appendChild(shape);
-        g.appendChild(contour);
-        g.appendChild(title);
+        shape.appendChild(title);
+        g.appendChild(contour)
         return g;
     };
 }
@@ -335,10 +341,13 @@ if (graph.supportsSVG()) {
         svg.onmousemove = function(e) {
             if (graph.dragging == null)
                 return false;
+            var pmatrix = graph.dragging.parentNode.getCTM();
             var matrix = graph.dragging.getCTM();
+            var curX = pmatrix != null? (Number(matrix.e) - Number(pmatrix.e)): Number(matrix.e);
+            var curY = pmatrix != null? (Number(matrix.f) - Number(pmatrix.f)): Number(matrix.f);
             var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
-            var newX = Number(matrix.e) + (pos.clientX - graph.dragX);
-            var newY = Number(matrix.f) + (pos.clientY - graph.dragY);
+            var newX = curX + (pos.clientX - graph.dragX);
+            var newY = curY + (pos.clientY - graph.dragY);
             graph.dragX = pos.clientX;
             graph.dragY = pos.clientY;
             graph.dragging.setAttribute('transform', 'translate(' + newX + ',' + newY + ')');
@@ -364,6 +373,10 @@ if (graph.supportsSVG()) {
             this.BasePath = graph.BasePath;
             this.BasePath();
 
+            this.clone = function() {
+                return graph.mkpath().pos(this.xpos(), this.ypos());
+            };
+
             this.move = function(x, y) {
                 this.path += 'M' + x + ',' + y + ' '; 
                 return this.pos(x, y);
@@ -389,9 +402,9 @@ if (graph.supportsSVG()) {
     };
 
     /**
-     * Make a title element.
+     * Return an element representing the title of a component.
      */
-    graph.mktitle = function(comp) {
+    graph.title = function(comp) {
         var t = scdl.name(comp);
         var title = document.createElementNS(graph.svgns, 'text');
         title.setAttribute('text-anchor', 'start');
@@ -403,22 +416,22 @@ if (graph.supportsSVG()) {
     };
 
     /**
-     * Return a width of a title.
+     * Return the width of the title of a component.
      */
     graph.titlewidth = function(comp) {
-        var title = graph.mktitle(comp);
+        var title = graph.title(comp);
         var width = title.getBBox().width;
         graph.textWidthSvg.removeChild(title);
         return width;
     };
 
     /**
-     * Make a component shape.
+     * Return a shape representing a component.
      */
-    graph.mkcompshape = function(comp, cassoc) {
-        var title = graph.mktitle(comp);
+    graph.compshape = function(comp, cassoc, pos) {
+        var title = graph.title(comp);
 
-        var d = graph.mkcomppath(comp, cassoc).str();
+        var d = graph.comppath(comp, cassoc).str();
 
         var shape = document.createElementNS(graph.svgns, 'path');
         shape.setAttribute('d', d);
@@ -433,6 +446,8 @@ if (graph.supportsSVG()) {
         contour.setAttribute('transform', 'translate(1,1)');
 
         var g = document.createElementNS(graph.svgns, 'g');
+        g.id = scdl.name(comp);
+        g.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')');
         g.appendChild(shape);
         g.appendChild(contour);
         g.appendChild(title);
@@ -441,43 +456,6 @@ if (graph.supportsSVG()) {
 }
 
 /**
- * Make a reference shape path, positioned to the right of a component shape.
- */
-graph.mkrrefpath = function(ref, cassoc, path) {
-    var height = graph.refheight(ref, cassoc);
-    var ypos = path.ypos();
-    return path.rline(0,10).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).line(path.xpos(),ypos + height);
-};
-
-/**
- * Make a reference shape path, positioned at the bottom of a component shape.
- */
-graph.mkbrefpath = function(ref, cassoc, path) {
-    var width = graph.refwidth(ref, cassoc);
-    var xpos = path.xpos();
-    return path.line(xpos - width + 60,path.ypos()).rline(-10,0).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).line(xpos - width,path.ypos());
-};
-
-/**
- * Make a service shape path, positioned to the left of a component shape.
- */
-graph.mklsvcpath = function(svc, path) {
-    var height = 60;
-    var ypos = path.ypos();
-    return path.rline(0,-10).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).line(path.xpos(), ypos - height);
-};
-
-/**
- * Make a service shape path, positioned at the top of a component shape.
- */
-graph.mktsvcpath = function(svc, path) {
-    var width = 60;
-    var xpos = path.xpos();
-    return path.rline(10,0).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).line(xpos + width,path.ypos());
-};
-
-
-/**
  * Return the services and references of a component.
  */
 graph.tsvcs = function(comp) {
@@ -485,7 +463,11 @@ graph.tsvcs = function(comp) {
 };
 
 graph.lsvcs = function(comp) {
-    return filter(function(s) { var a = scdl.align(s); return a == null || a == 'left'; }, scdl.services(comp));
+    var svcs = scdl.services(comp);
+    if (isNil(svcs))
+        return mklist("'element","'service","'attribute","'name",scdl.name(comp));
+    var l = filter(function(s) { var a = scdl.align(s); return a == null || a == 'left'; }, scdl.services(comp));
+    return l;
 };
 
 graph.brefs = function(comp) {
@@ -568,81 +550,156 @@ graph.compwidth = function(comp, cassoc)
 };
 
 /**
-* Make a component shape path.
-*/
-graph.mkcomppath = function(comp, cassoc) {
-    var tsvcs = graph.tsvcs(comp);
-    var lsvcs = graph.lsvcs(comp);
-    var brefs = graph.brefs(comp);
-    var rrefs = graph.rrefs(comp);
+ * Return a path representing a reference positioned to the right of a component.
+ */
+graph.rrefpath = function(ref, cassoc, path) {
+    var height = graph.refheight(ref, cassoc);
+    var ypos = path.ypos();
+    return path.rline(0,10).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).line(path.xpos(),ypos + height);
+};
+
+/**
+ * Return a path representing a reference positioned at the bottom of a component.
+ */
+graph.brefpath = function(ref, cassoc, path) {
+    var width = graph.refwidth(ref, cassoc);
+    var xpos = path.xpos();
+    return path.line(xpos - width + 60,path.ypos()).rline(-10,0).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).line(xpos - width,path.ypos());
+};
 
+/**
+ * Return a path representing a service positioned to the left of a component.
+ */
+graph.lsvcpath = function(svc, cassoc, path) {
+    var height = 60;
+    var ypos = path.ypos();
+    return path.rline(0,-10).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).line(path.xpos(), ypos - height);
+};
+
+/**
+ * Return a path representing a service positioned at the top of a component.
+ */
+graph.tsvcpath = function(svc, cassoc, path) {
+    var width = 60;
+    var xpos = path.xpos();
+    return path.rline(10,0).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).line(xpos + width,path.ypos());
+};
+
+/**
+* Return a path representing a component.
+*/
+graph.comppath = function(comp, cassoc) {
     var height = graph.compheight(comp, cassoc);
     var width = graph.compwidth(comp, cassoc);
 
+    function renderpath(x, f, cassoc, path) {
+        if (isNil(x))
+            return path;
+        return renderpath(cdr(x), f, cassoc, f(car(x), cassoc, path));
+    }
+
+    var tsvcs = graph.tsvcs(comp);
     var path = graph.mkpath().move(10,0);
-    for (var s = 0; s < length(tsvcs); s++)
-        path = graph.mktsvcpath(tsvcs[s], path);
+    path = renderpath(tsvcs, graph.tsvcpath, cassoc, path);
 
+    var rrefs = graph.rrefs(comp);
     path = path.line(width - 10,path.ypos()).rcurve(10,0,0,10);
-    for (var r = 0; r < length(rrefs); r++)
-        path = graph.mkrrefpath(rrefs[r], cassoc, path);
+    path = renderpath(rrefs, graph.rrefpath, cassoc, path);
 
+    var brefs = graph.brefs(comp);
     var boffset = 10 + graph.refswidth(brefs, cassoc);
     path = path.line(path.xpos(),height - 10).rcurve(0,10,-10,0).line(boffset, path.ypos());
-    for (var r = 0; r < length(brefs); r++)
-        path = graph.mkbrefpath(brefs[r], cassoc, path);
+    path = renderpath(brefs, graph.brefpath, cassoc, path);
 
+    var lsvcs = graph.lsvcs(comp);
     var loffset = 10 + (length(lsvcs) * 60);
     path = path.line(10,path.ypos()).rcurve(-10,0,0,-10).line(path.xpos(), loffset);
-    for (var s = 0; s < length(lsvcs); s++)
-        path = graph.mklsvcpath(lsvcs[s], path);
+    path = renderpath(lsvcs, graph.lsvcpath, cassoc, path);
 
     path = path.line(0,10).rcurve(0,-10,10,0);
     return path.end();
 };
 
 /**
- * Render a component.
- */
-graph.component = function(comp, cassoc) {
-    return graph.mkcompshape(comp, cassoc);
-};
-
-/**
  * Render a composite.
  */
 graph.composite = function(compos) {
     var name = scdl.name(compos);
     var comps = scdl.components(compos);
     var cassoc = scdl.nameToElementAssoc(comps);
+    var proms = scdl.promotions(compos);
 
-    function renderReference(ref, cassoc) {
-        var target = assoc(scdl.target(ref), cassoc);
-        if (isNil(target))
-            return mklist();
-        return renderComponent(cadr(target), cassoc);
-    }
+    function rendercomp(comp, cassoc, pos) {
+        function appendg(nodes, parent) {
+            if (isNil(nodes))
+                return parent;
+            parent.appendChild(car(nodes));
+            return appendg(cdr(nodes), parent);
+        }
 
-    function renderReferences(refs, cassoc) {
-        if (isNil(refs))
-            return mklist();
-        var rref = renderReference(car(refs), cassoc);
-        if (isNil(rref))
-            return renderReferences(cdr(refs), cassoc);
-        return append(rref, renderReferences(cdr(refs), cassoc));
-    }
+        function renderrrefs(refs, cassoc, pos) {
+            function renderrref(ref, cassoc, pos) {
+                var target = assoc(scdl.target(ref), cassoc);
+                if (isNil(target))
+                    return mklist();
+                return rendercomp(cadr(target), cassoc, pos);
+            }
+
+            function rendermove(ref, cassoc, pos) {
+                var target = assoc(scdl.target(ref), cassoc);
+                if (isNil(target))
+                    return pos;
+                return pos.clone().rmove(0, graph.compheight(cadr(target), cassoc));
+            }
+
+            if (isNil(refs))
+                return mklist();
+            return append(renderrref(car(refs), cassoc, pos), renderrrefs(cdr(refs), cassoc, rendermove(car(refs), cassoc, pos)));
+        }
 
-    function renderComponent(comp, cassoc) {
-        return append(renderReferences(scdl.references(comp), cassoc), mklist(graph.component(comp, cassoc)));
+        function renderbrefs(refs, cassoc, pos) {
+            function renderbref(ref, cassoc, pos) {
+                var target = assoc(scdl.target(ref), cassoc);
+                if (isNil(target))
+                    return mklist();
+                return rendercomp(cadr(target), cassoc, pos);
+            }
+
+            if (isNil(refs))
+                return mklist();
+            return append(renderbref(car(refs), cassoc, pos), renderbrefs(cdr(refs), cassoc, pos));
+        }
+
+        var gcomp = graph.compshape(comp, cassoc, pos);
+        var rrefs = graph.rrefs(comp);
+        var rpos = graph.mkpath().rmove(graph.compwidth(comp, cassoc), 0);
+        appendg(renderrrefs(rrefs, cassoc, rpos), gcomp);
+        var brefs = graph.brefs(comp);
+        appendg(renderbrefs(brefs, cassoc, rpos), gcomp);
+        return mklist(gcomp);
     }
 
-    function renderComponents(comps, cassoc) {
-        if (isNil(comps))
+    function renderproms(svcs, cassoc, pos) {
+        function renderprom(svc, cassoc, pos) {
+            var comp = assoc(scdl.promote(svc), cassoc);
+            if (isNil(comp))
+                return mklist();
+            return rendercomp(cadr(comp), cassoc, pos);
+        }
+
+        function rendermove(svc, cassoc, pos) {
+            var comp = assoc(scdl.promote(svc), cassoc);
+            if (isNil(comp))
+                return pos;
+            return pos.clone().rmove(0, graph.compheight(cadr(comp), cassoc) + 20);
+        }
+
+        if (isNil(svcs))
             return mklist();
-        return append(renderComponent(car(comps), cassoc), renderComponents(cdr(comps), cassoc));
+        return append(renderprom(car(svcs), cassoc, pos), renderproms(cdr(svcs), cassoc, rendermove(car(svcs), cassoc, pos)));
     }
 
-    var rcomps = renderComponents(comps, cassoc);
+    var rcomps = renderproms(proms, cassoc, graph.mkpath().rmove(20,20));
     return rcomps;
 };
 

Modified: tuscany/sca-cpp/trunk/modules/edit/htdocs/edit/index.html
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/htdocs/edit/index.html?rev=1055767&r1=1055766&r2=1055767&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/htdocs/edit/index.html (original)
+++ tuscany/sca-cpp/trunk/modules/edit/htdocs/edit/index.html Thu Jan  6 07:12:30 2011
@@ -32,20 +32,14 @@
  * Return the current app name.
  */
 function appname() {
-    var qs = window.location.toString().split('?');
-    if (isNil(cdr(qs)))
-        return null;
-    var p = cadr(qs).split('=');
-    if (isNil(p) || isNil(cdr(p)))
-        return null;
-    return cadr(p);
+    return ui.queryParams()['app'];
 }
 
 /**
  * Display the editor for an app.
  */
 function editapp(name) {
-    if (name == null)
+    if (isNil(name))
         return;
     $('titleDiv').innerHTML = 'Editing: ' + name;
     $('editDiv').innerHTML =

Modified: tuscany/sca-cpp/trunk/modules/js/htdocs/scdl.js
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/htdocs/scdl.js?rev=1055767&r1=1055766&r2=1055767&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/htdocs/scdl.js (original)
+++ tuscany/sca-cpp/trunk/modules/js/htdocs/scdl.js Thu Jan  6 07:12:30 2011
@@ -33,6 +33,26 @@ scdl.components = function(l) {
 };
 
 /**
+ * Returns a list of service promotions in a composite.
+ */
+scdl.promotions = function(l) {
+    var cs = namedElementChildren("'composite", l);
+    if (isNil(cs))
+        return cs;
+    return namedElementChildren("'service", car(cs));
+};
+
+/**
+ * Returns the target of a service promotion.
+ */
+scdl.promote = function(l) {
+    var puri = namedAttributeValue("'promote", l);
+    if (isNil(puri))
+        return puri;
+    return car(tokens(puri));
+};
+
+/**
  * Returns the name of a component, service or reference.
  */
 scdl.name = function(l) {
@@ -121,7 +141,7 @@ scdl.target = function(l) {
         function bindingsTarget(l) {
             if (isNil(l))
                 return null;
-            var u = uri(car(l));
+            var u = scdl.uri(car(l));
             if (!isNil(u))
                 return u;
             return bindingsTarget(cdr(l));

Modified: tuscany/sca-cpp/trunk/modules/js/htdocs/ui.js
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/htdocs/ui.js?rev=1055767&r1=1055766&r2=1055767&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/htdocs/ui.js (original)
+++ tuscany/sca-cpp/trunk/modules/js/htdocs/ui.js Thu Jan  6 07:12:30 2011
@@ -204,6 +204,20 @@ function $(id) {
 };
 
 /**
+ * Return a dictionary of the query parameters.
+ */
+ui.queryParams = function() {
+    var qp = new Array();
+    var qs = window.location.search.substring(1).split('&');
+    for (var i = 0; i < qs.length; i++) {
+        var e = qs[i].indexOf('=');
+        if (e > 0)
+            qp[qs[i].substring(0, e)] = unescape(qs[i].substring(e + 1));
+    }
+    return qp;
+}
+
+/**
  * Bind a widget iframe to an element.
  */
 ui.widgets = new Array();

Modified: tuscany/sca-cpp/trunk/modules/scdl/scdl.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/scdl/scdl.hpp?rev=1055767&r1=1055766&r2=1055767&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/scdl/scdl.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/scdl/scdl.hpp Thu Jan  6 07:12:30 2011
@@ -46,6 +46,23 @@ const list<value> components(const value
 }
 
 /**
+ * Returns a list of service promotions in a composite.
+ */
+const list<value> promotions(const value& l) {
+    const list<value> cs = elementChildren("composite", l);
+    if (isNil(cs))
+        return cs;
+    return elementChildren("service", car(cs));
+}
+
+/**
+ * Returns the target or a service promotion.
+ */
+const value promote(const value& l) {
+    return attributeValue("promote", l);
+}
+
+/**
  * Returns the name of a component, service or reference.
  */
 const value name(const value& l) {