summaryrefslogtreecommitdiffstats
path: root/sca-cpp/branches/lightweight-sca/hosting/server
diff options
context:
space:
mode:
Diffstat (limited to 'sca-cpp/branches/lightweight-sca/hosting/server')
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/Makefile.am66
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/accounts.py36
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/apps.py111
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/authn.py40
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/client-test.cpp39
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/client-test.hpp436
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/composites.py97
-rwxr-xr-xsca-cpp/branches/lightweight-sca/hosting/server/config-backup22
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/dashboards.py105
-rwxr-xr-xsca-cpp/branches/lightweight-sca/hosting/server/data-backup22
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/accounts/admin/user.account1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/accounts/jane/user.account1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/accounts/john/user.account1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/me360/app.composite100
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/me360/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/me360/htdocs/app.html82
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme/app.composite451
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme/htdocs/app.html61
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme2/app.composite198
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme2/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme2/htdocs/app.html37
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/new/app.composite59
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/new/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/new/htdocs/app.html34
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/ourphotos/app.composite170
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/ourphotos/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/ourphotos/htdocs/app.html43
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/shoppingcart/app.composite603
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/shoppingcart/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/shoppingcart/htdocs/app.html79
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/slice/app.composite511
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/slice/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/slice/htdocs/app.html75
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/test/app.composite70
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/test/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/test/htdocs/app.html40
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testanimation/app.composite176
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testanimation/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testanimation/htdocs/app.html34
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testdb/app.composite106
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testdb/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testdb/htdocs/app.html31
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testevents/app.composite202
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testevents/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testevents/htdocs/app.html64
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testhttp/app.composite287
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testhttp/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testhttp/htdocs/app.html38
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testlogic/app.composite209
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testlogic/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testlogic/htdocs/app.html31
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsearch/app.composite248
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsearch/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsearch/htdocs/app.html31
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsms/app.composite105
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsms/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsms/htdocs/app.html31
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsocial/app.composite186
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsocial/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsocial/htdocs/app.html31
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testtext/app.composite223
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testtext/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testtext/htdocs/app.html31
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testurl/app.composite159
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testurl/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testurl/htdocs/app.html31
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testvalues/app.composite498
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testvalues/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testvalues/htdocs/app.html34
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets/app.composite196
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets/htdocs/app.html61
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets2/app.composite154
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets2/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets2/htdocs/app.html93
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets3/app.composite213
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets3/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets3/htdocs/app.html46
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/twsms/app.composite137
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/twsms/app.stats1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/apps/twsms/htdocs/app.html40
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/jane@example.com/user.apps1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/jane@localhost/user.apps1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/john@example.com/user.apps1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/john@localhost/user.apps1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/animation/palette.composite103
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/control/palette.composite86
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/database/palette.composite72
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/http/palette.composite116
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/lists/palette.composite131
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/logic/palette.composite70
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/math/palette.composite138
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/python/palette.composite35
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/search/palette.composite100
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/social/palette.composite120
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/talk/palette.composite55
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/text/palette.composite76
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/transform/palette.composite59
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/values/palette.composite79
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/store/all/store.apps1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/store/featured/store.apps1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/store/new/store.apps1
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/data/store/top/store.apps1
-rwxr-xr-xsca-cpp/branches/lightweight-sca/hosting/server/delete-auth61
-rwxr-xr-xsca-cpp/branches/lightweight-sca/hosting/server/get-auth62
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/account/index.html222
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/app/cache-template.cmf17
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/app/index.html1012
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/cache-template.cmf18
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/clone/index.html157
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/config.js53
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/create/index.html123
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/delete/index.html139
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/favicon.icobin0 -> 2238 bytes
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/graph/index.html2100
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/home/home.b641
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/home/home.pngbin0 -> 9595 bytes
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/home/index.html76
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/index.html640
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/login/index.html337
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/page/index.html1081
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/proxy/public/oops/index.html193
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/app.b641
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/app.pngbin0 -> 147 bytes
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/app.xcfbin0 -> 1294 bytes
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/config.js45
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/delete.b641
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/delete.pngbin0 -> 906 bytes
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/delete.xcfbin0 -> 2008 bytes
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/grid72.b641
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/grid72.pngbin0 -> 138 bytes
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/iframe.html28
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/img.b641
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/img.pngbin0 -> 357 bytes
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/img.xcfbin0 -> 1639 bytes
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/notauth/index.html195
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/notfound/index.html194
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/notyet/index.html194
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/oops/index.html193
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/touchicon.b641
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/touchicon.pngbin0 -> 606 bytes
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/touchicon.xcfbin0 -> 3400 bytes
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/user.b641
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/user.pngbin0 -> 147 bytes
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/robots.txt2
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/stats/index.html179
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/htdocs/store/index.html170
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/log.py24
-rwxr-xr-xsca-cpp/branches/lightweight-sca/hosting/server/logic-test28
-rwxr-xr-xsca-cpp/branches/lightweight-sca/hosting/server/mkapplinks37
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/pages.py96
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/palettes.py36
-rwxr-xr-xsca-cpp/branches/lightweight-sca/hosting/server/proxy-start164
-rwxr-xr-xsca-cpp/branches/lightweight-sca/hosting/server/put-auth80
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/selector.py28
-rwxr-xr-xsca-cpp/branches/lightweight-sca/hosting/server/server-test31
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/server.composite149
-rwxr-xr-xsca-cpp/branches/lightweight-sca/hosting/server/ssl-proxy-start252
-rwxr-xr-xsca-cpp/branches/lightweight-sca/hosting/server/ssl-start208
-rwxr-xr-xsca-cpp/branches/lightweight-sca/hosting/server/start126
-rwxr-xr-xsca-cpp/branches/lightweight-sca/hosting/server/stop30
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/store.py112
-rwxr-xr-xsca-cpp/branches/lightweight-sca/hosting/server/test.py296
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/test/__init__.py17
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/test/cache.py48
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/test/property.py38
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/test/reference.py38
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/user.py27
-rw-r--r--sca-cpp/branches/lightweight-sca/hosting/server/util.py164
170 files changed, 18114 insertions, 0 deletions
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/Makefile.am b/sca-cpp/branches/lightweight-sca/hosting/server/Makefile.am
new file mode 100644
index 0000000000..d6e15f819b
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/Makefile.am
@@ -0,0 +1,66 @@
+# 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.
+
+if WANT_PYTHON
+
+moddir = $(prefix)/hosting/server
+dist_mod_SCRIPTS = start stop ssl-start mkapplinks config-backup data-backup put-auth get-auth delete-auth
+
+not_minified = htdocs/public/iframe.html htdocs/create/index.html htdocs/page/index.html htdocs/login/index.html htdocs/public/notfound/index.html htdocs/public/oops/index.html htdocs/proxy/public/oops/index.html htdocs/graph/index.html htdocs/public/notauth/index.html htdocs/account/index.html htdocs/home/index.html htdocs/index.html htdocs/public/notyet/index.html htdocs/clone/index.html htdocs/delete/index.html htdocs/stats/index.html htdocs/app/index.html htdocs/store/index.html htdocs/config.js htdocs/public/config.js htdocs/cache-template.cmf htdocs/app/cache-template.cmf htdocs/cache-template.cmf htdocs/app/cache-template.cmf
+
+minified = htdocs/public/iframe-min.html htdocs/create/index-min.html htdocs/page/index-min.html htdocs/login/index-min.html htdocs/public/notfound/index-min.html htdocs/public/oops/index-min.html htdocs/proxy/public/oops/index-min.html htdocs/graph/index-min.html htdocs/public/notauth/index-min.html htdocs/account/index-min.html htdocs/home/index-min.html htdocs/index-min.html htdocs/public/notyet/index-min.html htdocs/clone/index-min.html htdocs/delete/index-min.html htdocs/stats/index-min.html htdocs/app/index-min.html htdocs/store/index-min.html htdocs/config-min.js htdocs/public/config-min.js
+
+js_minified = ../../modules/js/htdocs/all-min.js ../../modules/js/htdocs/ui-min.css
+
+resources = server.composite *.py data/palettes/*/palette.composite data/accounts/*/*.account data/apps/*/app.composite data/apps/*/app.stats data/apps/*/htdocs/app.html data/dashboards/*/user.apps data/store/*/store.apps htdocs/cache-manifest.cmf htdocs/app/cache-manifest.cmf htdocs/*.ico htdocs/home/*.png htdocs/home/*.b64 htdocs/*.txt htdocs/public/*.png htdocs/public/*.b64 ${minified}
+
+nobase_dist_mod_DATA = ${resources}
+EXTRA_DIST = ${resources} ${not_minified}
+
+SUFFIXES = -min.html -min.js
+.html-min.html:
+ ../../modules/http/minify-html $< $@
+
+.js-min.js:
+ ../../modules/http/minify-js $< $@
+
+htdocs/cache-manifest.cmf: htdocs/cache-template.cmf ${minified} ${js_minified}
+ ../../modules/http/cache-manifest htdocs $^
+
+htdocs/app/cache-manifest.cmf: htdocs/app/cache-template.cmf ${minified} ${js_minified}
+ ../../modules/http/cache-manifest htdocs/app $^
+
+nuvem:
+ ln -s "../../../nuvem/nuvem-parallel/nuvem" "nuvem"
+
+lib:
+ ln -s "../../components" "lib"
+
+install-data-hook:
+ cd $(moddir); rm -f nuvem; ln -s "../../../nuvem/nuvem-parallel/nuvem" "nuvem"
+ cd $(moddir); rm -f lib; ln -s "../../components" "lib"
+
+CLEANFILES = ${minified} nuvem lib htdocs/cache-manifest.cmf htdocs/app/cache-manifest.cmf
+
+client_test_SOURCES = client-test.cpp
+client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+
+dist_noinst_SCRIPTS = logic-test server-test test.py
+noinst_PROGRAMS = client-test
+TESTS = logic-test
+
+endif
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/accounts.py b/sca-cpp/branches/lightweight-sca/hosting/server/accounts.py
new file mode 100644
index 0000000000..3587f5fb65
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/accounts.py
@@ -0,0 +1,36 @@
+# 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.
+
+# Accounts collection implementation
+from time import strftime
+from util import *
+
+# Convert a particular user id to an account id
+def accountid(user):
+ return ('accounts', user.get(()), 'user.account')
+
+# Get the current user's account
+def get(id, user, cache):
+ account = cache.get(accountid(user))
+ if isNil(account) or account is None:
+ return (("'entry", ("'title", user.get(())), ("'id", user.get(())), ("'updated", strftime('%b %d, %Y'))),)
+ return account
+
+# Update the user's account
+def put(id, account, user, cache):
+ return cache.put(accountid(user), account)
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/apps.py b/sca-cpp/branches/lightweight-sca/hosting/server/apps.py
new file mode 100644
index 0000000000..064701a7df
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/apps.py
@@ -0,0 +1,111 @@
+# 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.
+
+# App collection implementation
+from time import strftime
+from util import *
+from sys import debug
+
+# Convert an id to an app id
+def appid(id):
+ return ("apps", car(id), "app.stats")
+
+# Put an app into the apps db
+def put(id, app, user, cache, dashboard, store, composites, pages):
+ debug('apps.py::put::id', id)
+ debug('apps.py::put::app', app)
+
+ # Update an app
+ eid = cadr(assoc("'id", car(app)))
+ if car(id) == eid:
+ # Check app author
+ eapp = cache.get(appid(id));
+ if (not (isNil(eapp) or eapp is None)) and (cadr(assoc("'author", car(eapp))) != user.get(())):
+ debug('apps.py::put', 'different author', cadr(assoc("'author", car(eapp))))
+ return False
+
+ # Update the app in the apps db
+ appentry = (("'entry", assoc("'title", car(app)), ("'id", car(id)), ("'author", user.get(())), ("'updated", strftime('%b %d, %Y')), assoc("'content", car(app))),)
+ debug('apps.py::put::appentry', appentry)
+ cache.put(appid(id), appentry)
+ dashboard.put(id, appentry)
+
+ # Create new page and composite if necessary
+ if isNil(eapp) or eapp is None:
+ comp = (("'entry", ("'title", car(id)), ("'id", car(id))),)
+ composites.put(id, comp);
+ page = (("'entry", ("'title", car(id)), ("'id", car(id))),)
+ pages.put(id, comp);
+ return True
+ return True
+
+ # Check app author
+ eapp = cache.get(appid(id));
+ if (not (isNil(eapp) or eapp is None)) and (cadr(assoc("'author", car(eapp))) != user.get(())):
+ debug('apps.py::put', 'different author', cadr(assoc("'author", car(eapp))))
+ return False
+
+ # Clone an app
+ appentry = (("'entry", assoc("'title", car(app)), ("'id", car(id)), ("'author", user.get(())), ("'updated", strftime('%b %d, %Y')), assoc("'content", car(app))),)
+ debug('apps.py::put::appentry', appentry)
+ cache.put(appid(id), appentry)
+ composites.put(id, composites.get((eid,)))
+ pages.put(id, pages.get((eid,)))
+ dashboard.put(id, appentry)
+ return True
+
+# Get an app from the apps db
+def get(id, user, cache, dashboard, store, composites, pages):
+ debug('apps.py::get::id', id)
+ if isNil(id):
+ return (("'feed", ("'title", "Apps"), ("'id", "apps")),)
+
+ # Get the requested app
+ app = cache.get(appid(id));
+ if isNil(app) or app is None:
+ debug('apps.py::get', 'app not found', id)
+
+ # Return a default new app
+ return (("'entry", ("'title", car(id)), ("'id", car(id)), ("'author", user.get(())), ("'updated", strftime('%b %d, %Y')), ("'content", ("'stats", ("'description", '')))),)
+
+ # Return the app
+ debug('apps.py::get::app', app)
+ return app
+
+# Delete an app from the apps db
+def delete(id, user, cache, dashboard, store, composites, pages):
+ debug('apps.py::delete::id', id)
+
+ # Get the requested app
+ app = cache.get(appid(id));
+ if isNil(app) or app is None:
+ debug('apps.py::delete', 'app not found', id)
+ return False
+
+ # Check app author
+ author = cadr(assoc("'author", car(app)))
+ if author != user.get(()):
+ debug('apps.py::delete', 'different author', author)
+ return False
+
+ # Delete the app, its composite and page
+ dashboard.delete(id)
+ composites.delete(id)
+ pages.delete(id)
+ cache.delete(appid(id))
+ return True
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/authn.py b/sca-cpp/branches/lightweight-sca/hosting/server/authn.py
new file mode 100644
index 0000000000..4d4f34b9fb
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/authn.py
@@ -0,0 +1,40 @@
+# 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.
+
+# User authenticator implementation
+from time import strftime
+from util import *
+
+# Convert a particular user id to an authentication id
+def authnid(id):
+ return append(append(('authn',), id), ('user.authn',))
+
+# Get a user's authentication
+def get(id, cache):
+ authn = cache.get(authnid(id))
+ if isNil(authn) or authn is None:
+ return None
+ return authn
+
+# Update a user's authentication
+def put(id, authn, cache):
+ return cache.put(authnid(id), authn)
+
+# Delete a user's authentication
+def delete(id, cache):
+ return cache.delete(authnid(id))
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/client-test.cpp b/sca-cpp/branches/lightweight-sca/hosting/server/client-test.cpp
new file mode 100644
index 0000000000..c0a01b5237
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/client-test.cpp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Test HTTP client functions.
+ */
+
+#include "stream.hpp"
+#include "string.hpp"
+#include "client-test.hpp"
+
+int main(const int argc, const char** argv) {
+ tuscany::cout << "Testing..." << tuscany::endl;
+ tuscany::server::testURI = argc > 1? argv[1] : "https://jane:jane@www.example.com:8453";
+
+ tuscany::server::testServer();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/client-test.hpp b/sca-cpp/branches/lightweight-sca/hosting/server/client-test.hpp
new file mode 100644
index 0000000000..7d85fc99a6
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/client-test.hpp
@@ -0,0 +1,436 @@
+/*
+ * 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.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Test HTTP client functions.
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "parallel.hpp"
+#include "perf.hpp"
+#include "../../modules/http/http.hpp"
+
+namespace tuscany {
+namespace server {
+
+string testURI = "http://localhost:8090";
+bool testBlobs = true;
+
+ostream* curlWriter(const string& s, ostream* os) {
+ (*os) << s;
+ return os;
+}
+
+const bool testGetDoc() {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ {
+ ostringstream os;
+ const failable<list<ostream*> > r = http::get<ostream*>(curlWriter, &os, testURI + "/", ch);
+ assert(hasContent(r));
+ assert(contains(str(os), "HTTP/1.1 200") || contains(str(os), "HTTP/1.0 200"));
+ assert(contains(str(os), "<base href=\"/\"/>"));
+ }
+ {
+ const failable<value> r = http::getcontent(testURI + "/", ch);
+ assert(hasContent(r));
+ assert(contains(car(list<value>(content(r))), "<base href=\"/\"/>"));
+ }
+ return true;
+}
+
+struct getDocLoop {
+ http::CURLSession& ch;
+ getDocLoop(http::CURLSession& ch) : ch(ch) {
+ }
+ const bool operator()() const {
+ const failable<value> r = http::getcontent(testURI + "/", ch);
+ assert(hasContent(r));
+ assert(contains(car(list<value>(content(r))), "<base href=\"/\"/>"));
+ return true;
+ }
+};
+
+const bool testGetDocPerf() {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ const lambda<bool()> gl = getDocLoop(ch);
+ cout << "GET doc test " << time(gl, 10, 50) << " ms" << endl;
+ return true;
+}
+
+struct getCompositeLoop {
+ http::CURLSession& ch;
+ getCompositeLoop(http::CURLSession& ch) : ch(ch) {
+ }
+ const bool operator()() const {
+ const failable<value> r = http::getcontent(testURI + "/r/Editor/composites/test", ch);
+ assert(hasContent(r));
+ return true;
+ }
+};
+
+const bool testGetCompositePerf() {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ const lambda<bool()> gl = getCompositeLoop(ch);
+ cout << "GET composite test " << time(gl, 10, 50) << " ms" << endl;
+ return true;
+}
+
+struct getPageLoop {
+ http::CURLSession& ch;
+ getPageLoop(http::CURLSession& ch) : ch(ch) {
+ }
+ const bool operator()() const {
+ const failable<value> r = http::getcontent(testURI + "/r/Editor/pages/test", ch);
+ assert(hasContent(r));
+ return true;
+ }
+};
+
+const bool testGetPagePerf() {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ const lambda<bool()> gl = getPageLoop(ch);
+ cout << "GET page test " << time(gl, 10, 50) << " ms" << endl;
+ return true;
+}
+
+struct getAppLoop {
+ http::CURLSession& ch;
+ getAppLoop(http::CURLSession& ch) : ch(ch) {
+ }
+ const bool operator()() const {
+ const failable<value> r = http::getcontent(testURI + "/r/Editor/apps/test", ch);
+ assert(hasContent(r));
+ return true;
+ }
+};
+
+const bool testGetAppPerf() {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ const lambda<bool()> gl = getAppLoop(ch);
+ cout << "GET app test " << time(gl, 10, 50) << " ms" << endl;
+ return true;
+}
+
+const bool testEval() {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ const failable<value> r = http::evalExpr(mklist<value>(string("echo"), string("Hello")), testURI, ch);
+ assert(hasContent(r));
+ assert(content(r) == string("Hello"));
+ return true;
+}
+
+struct evalLoop {
+ const string uri;
+ http::CURLSession& ch;
+ evalLoop(const string& uri, http::CURLSession& ch) : uri(uri), ch(ch) {
+ }
+ const bool operator()() const {
+ const failable<value> r = http::evalExpr(mklist<value>(string("echo"), string("Hello")), uri, ch);
+ assert(hasContent(r));
+ assert(content(r) == string("Hello"));
+ return true;
+ }
+};
+
+const value blob(string(2048, 'A'));
+const list<value> blobs = mklist(blob, blob);
+
+struct blobEvalLoop {
+ const string uri;
+ http::CURLSession& ch;
+ blobEvalLoop(const string& uri, http::CURLSession& ch) : uri(uri), ch(ch) {
+ }
+ const bool operator()() const {
+ const failable<value> r = content(http::evalExpr(mklist<value>(string("echo"), blobs), uri, ch));
+ assert(hasContent(r));
+ assert(content(r) == blobs);
+ return true;
+ }
+};
+
+const bool testEvalPerf() {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ const lambda<bool()> el = evalLoop(testURI, ch);
+ cout << "JSON-RPC eval echo test " << time(el, 5, 200) << " ms" << endl;
+
+ if (testBlobs) {
+ const lambda<bool()> bel = blobEvalLoop(testURI, ch);
+ cout << "JSON-RPC eval blob test " << time(bel, 5, 200) << " ms" << endl;
+ }
+ return true;
+}
+
+bool testPost() {
+ gc_scoped_pool pool;
+ const list<value> i = list<value>() + "content" + (list<value>() + "item"
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99")));
+ const list<value> a = list<value>() + (list<value>() + "entry"
+ + (list<value>() + "title" + string("item"))
+ + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ + i);
+ http::CURLSession ch("", "", "", "", 0);
+ const failable<value> id = http::post(a, testURI, ch);
+ assert(hasContent(id));
+ return true;
+}
+
+struct postLoop {
+ const string uri;
+ const value val;
+ http::CURLSession& ch;
+ postLoop(const string& uri, const value& val, http::CURLSession& ch) : uri(uri), val(val), ch(ch) {
+ }
+ const bool operator()() const {
+ const failable<value> id = http::post(val, uri, ch);
+ assert(hasContent(id));
+ return true;
+ }
+};
+
+struct postBlobLoop {
+ const string uri;
+ const value val;
+ http::CURLSession& ch;
+ postBlobLoop(const string& uri, const value& val, http::CURLSession& ch) : uri(uri), val(val), ch(ch) {
+ }
+ const bool operator()() const {
+ gc_scoped_pool pool;
+ const failable<value> id = http::post(val, uri, ch);
+ assert(hasContent(id));
+ return true;
+ }
+};
+
+const bool testPostPerf() {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ {
+ const list<value> i = list<value>() + "content" + (list<value>() + "item"
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99")));
+ const list<value> val = list<value>() + (list<value>() + "entry"
+ + (list<value>() + "title" + string("item"))
+ + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ + i);
+ const lambda<bool()> pl = postLoop(testURI, val, ch);
+ cout << "ATOMPub POST small test " << time(pl, 5, 200) << " ms" << endl;
+ }
+ if (testBlobs) {
+ const list<value> i = list<value>() + "content" + (list<value>() + "item"
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "blob1" + blob)
+ + (list<value>() + "blob2" + blob)
+ + (list<value>() + "price" + string("$2.99")));
+ const list<value> val = list<value>() + (list<value>() + "entry"
+ + (list<value>() + "title" + string("item"))
+ + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ + i);
+ const lambda<bool()> pl = postBlobLoop(testURI, val, ch);
+ cout << "ATOMPub POST blob test " << time(pl, 5, 200) << " ms" << endl;
+ }
+ return true;
+}
+
+#ifdef WANT_THREADS
+
+const bool postThread(const string& uri, const int count, const value& val) {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ const lambda<bool()> pl = postLoop(uri, val, ch);
+ time(pl, 0, count);
+ return true;
+}
+
+const list<future<bool> > startPost(worker& w, const int threads, const lambda<bool()>& l) {
+ if (threads == 0)
+ return list<future<bool> >();
+ return cons(submit(w, l), startPost(w, threads - 1, l));
+}
+
+const bool checkPost(const list<future<bool> >& r) {
+ if (isNil(r))
+ return true;
+ assert(car(r) == true);
+ return checkPost(cdr(r));
+}
+
+struct postThreadLoop {
+ const lambda<bool()> l;
+ worker& w;
+ const int threads;
+ postThreadLoop(const lambda<bool()>& l, worker& w, const int threads) : l(l), w(w), threads(threads) {
+ }
+ const bool operator()() const {
+ list<future<bool> > r = startPost(w, threads, l);
+ checkPost(r);
+ return true;
+ }
+};
+
+const bool testPostThreadPerf() {
+ gc_scoped_pool pool;
+ const int count = 50;
+ const int threads = 10;
+ worker w(threads);
+
+ const list<value> i = list<value>() + "content" + (list<value>() + "item"
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99")));
+ const value val = list<value>() + (list<value>() + "entry"
+ + (list<value>() + "title" + string("item"))
+ + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ + i);
+
+ const lambda<bool()> pl= curry(lambda<bool(const string, const int, const value)>(postThread), testURI, count, val);
+ const lambda<bool()> ptl = postThreadLoop(pl, w, threads);
+ double t = time(ptl, 0, 1) / (threads * count);
+ cout << "ATOMPub POST thread test " << t << " ms" << endl;
+
+ return true;
+}
+
+#else
+
+const bool postProc(const string& uri, const int count, const value& val) {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ const lambda<bool()> pl = postLoop(uri, val, ch);
+ time(pl, 0, count);
+ return true;
+}
+
+const list<pid_t> startPost(const int procs, const lambda<bool()>& l) {
+ if (procs == 0)
+ return list<pid_t>();
+ pid_t pid = fork();
+ if (pid == 0) {
+ assert(l() == true);
+ exit(0);
+ }
+ return cons(pid, startPost(procs - 1, l));
+}
+
+const bool checkPost(const list<pid_t>& r) {
+ if (isNil(r))
+ return true;
+ int status;
+ waitpid(car(r), &status, 0);
+ assert(status == 0);
+ return checkPost(cdr(r));
+}
+
+struct postForkLoop {
+ const lambda<bool()> l;
+ const int procs;
+ postForkLoop(const lambda<bool()>& l, const int procs) : l(l), procs(procs) {
+ }
+ const bool operator()() const {
+ list<pid_t> r = startPost(procs, l);
+ checkPost(r);
+ return true;
+ }
+};
+
+const bool testPostForkPerf() {
+ gc_scoped_pool pool;
+ const int count = 50;
+ const int procs = 10;
+
+ const list<value> i = list<value>() + "content" + (list<value>() + "item"
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99")));
+ const value val = list<value>() + (list<value>() + "entry"
+ + (list<value>() + "title" + string("item"))
+ + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ + i);
+
+ const lambda<bool()> pl= curry(lambda<bool(const string, const int, const value)>(postProc), testURI, count, val);
+ const lambda<bool()> ptl = postForkLoop(pl, procs);
+ double t = time(ptl, 0, 1) / (procs * count);
+ cout << "ATOMPub POST fork test " << t << " ms" << endl;
+
+ return true;
+}
+
+#endif
+
+const bool testPut() {
+ gc_scoped_pool pool;
+ const list<value> i = list<value>() + "content" + (list<value>() + "item"
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99")));
+ const list<value> a = list<value>() + (list<value>() + "entry"
+ + (list<value>() + "title" + string("item"))
+ + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ + i);
+ http::CURLSession ch("", "", "", "", 0);
+ value rc = content(http::put(a, testURI + "/111", ch));
+ assert(rc == value(true));
+ return true;
+}
+
+const bool testDel() {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ value rc = content(http::del(testURI + "/111", ch));
+ assert(rc == value(true));
+ return true;
+}
+
+const bool testServer() {
+ tuscany::server::testGetDoc();
+#ifdef FOO
+ tuscany::server::testPost();
+ tuscany::server::testPut();
+ tuscany::server::testDel();
+ tuscany::server::testEval();
+#endif
+ tuscany::server::testGetDocPerf();
+ tuscany::server::testGetCompositePerf();
+ tuscany::server::testGetPagePerf();
+ tuscany::server::testGetAppPerf();
+#ifdef FOO
+ tuscany::server::testPostPerf();
+#ifdef WANT_THREADS
+ tuscany::server::testPostThreadPerf();
+#else
+ tuscany::server::testPostForkPerf();
+#endif
+ tuscany::server::testEvalPerf();
+#endif
+ return true;
+}
+
+}
+}
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/composites.py b/sca-cpp/branches/lightweight-sca/hosting/server/composites.py
new file mode 100644
index 0000000000..970bc98a5c
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/composites.py
@@ -0,0 +1,97 @@
+# 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.
+
+# App composites collection implementation
+from time import strftime
+from util import *
+from sys import debug
+
+# Convert an id to a composite id
+def compid(id):
+ return ("apps", car(id), "app.composite")
+
+# Put a composite into the composite db
+def put(id, comp, user, cache, apps):
+ debug('composites.py::put::id', id)
+ debug('composites.py::put::comp', comp)
+
+ # Get the requested app
+ app = apps.get(id);
+ if isNil(app) or app is None:
+ debug('composites.py::put', 'app not found', id)
+ return False
+
+ # Check app author
+ author = cadr(assoc("'author", car(app)))
+ if author != user.get(()):
+ debug('composites.py::put', 'different author', author)
+ return False
+
+ # Update the composite in the composite db
+ compentry = (("'entry", assoc("'title", car(app)), ("'id", car(id)), ("'author", user.get(())), ("'updated", strftime('%b %d, %Y')), assoc("'content", car(comp))),)
+ debug('composites.py::put::compentry', compentry)
+ return cache.put(compid(id), compentry)
+
+# Get a composite from the composite db
+def get(id, user, cache, apps):
+ debug('composites.py::get::id', id)
+ if isNil(id):
+ return (("'feed", ("'title", "Composites"), ("'id", "composites")),)
+
+ # Get the requested app
+ app = apps.get(id)
+ if isNil(app) or app is None:
+ debug('composites.py::get', 'app not found', id)
+
+ # Return a default new composite
+ return (("'entry", ("'title", car(id)), ("'id", car(id)), ("'author", user.get(())), ("'updated", strftime('%b %d, %Y'))),)
+
+ # Get the requested composite
+ comp = cache.get(compid(id));
+ if isNil(comp) or comp is None:
+ debug('composites.py::get', 'composite not found', id)
+
+ # Return a default new composite
+ return (("'entry", ("'title", car(id)), ("'id", car(id)), assoc("'author", car(app)), assoc("'updated", car(app))),)
+
+ # Return the composite
+ def updated(u):
+ return assoc("'updated", car(app)) if isNil(u) or u is None else u
+
+ compentry = (("'entry", assoc("'title", car(app)), ("'id", car(id)), assoc("'author", car(app)), updated(assoc("'updated", car(comp))), assoc("'content", car(comp))),)
+ debug('composites.py::get::compentry', compentry)
+ return compentry
+
+# Delete a composite from the composite db
+def delete(id, user, cache, apps):
+ debug('composites.py::delete::id', id)
+
+ # Get the requested app
+ app = apps.get(id);
+ if isNil(app) or app is None:
+ debug('composites.py::delete', 'app not found', id)
+ return False
+
+ # Check app author
+ author = cadr(assoc("'author", car(app)))
+ if author != user.get(()):
+ debug('composites.py::delete', 'different author', author)
+ return False
+
+ # Delete the composite
+ return cache.delete(compid(id))
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/config-backup b/sca-cpp/branches/lightweight-sca/hosting/server/config-backup
new file mode 100755
index 0000000000..5e09008fb0
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/config-backup
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# 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.
+
+cd ../../
+tar czf ../config-backup.tar.gz hosting/server/*start hosting/server/*stop hosting/server/htdocs/*.js hosting/server/htdocs/public/*.js hosting/server/htdocs/home/*.b64 hosting/server/htdocs/home/*.png
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/dashboards.py b/sca-cpp/branches/lightweight-sca/hosting/server/dashboards.py
new file mode 100644
index 0000000000..d6281d0454
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/dashboards.py
@@ -0,0 +1,105 @@
+# 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.
+
+# Dashboards collection implementation
+from util import *
+from sys import debug
+
+# Convert a particular user id to a dashboard id
+def dashboardid(user):
+ return ("dashboards", user.get(()), "user.apps")
+
+# Get a dashboard from the cache
+def getdashboard(id, cache):
+ debug('dashboards.py::getdashboard::id', id)
+ val = cache.get(id)
+ if isNil(val) or val is None:
+ return ()
+ dashboard = cdddr(car(val))
+ if not isNil(dashboard) and isList(car(cadr(car(dashboard)))):
+ # Expand list of entries
+ edashboard = tuple(map(lambda e: cons("'entry", e), cadr(car(dashboard))))
+ debug('dashboards.py::getdashboard::edashboard', edashboard)
+ return edashboard
+
+ debug('dashboards.py::getdashboard::dashboard', dashboard)
+ return dashboard
+
+# Put a dashboard into the cache
+def putdashboard(id, dashboard, cache):
+ debug('dashboards.py::putdashboard::id', id)
+ debug('dashboards.py::putdashboard::dashboard', dashboard)
+ val = ((("'feed", ("'title", "Your Apps"), ("'id", cadr(id))) + dashboard),)
+ return cache.put(id, val)
+
+# Put an app into the user's dashboard
+def put(id, app, user, cache, apps):
+ debug('dashboards.py::put::id', id)
+ debug('dashboards.py::put::app', app)
+
+ def putapp(id, app, dashboard):
+ if isNil(dashboard):
+ return app
+ if car(id) == cadr(assoc("'id", car(dashboard))):
+ return cons(car(app), cdr(dashboard))
+ return cons(car(dashboard), putapp(id, app, cdr(dashboard)))
+
+ appentry = (("'entry", assoc("'title", car(app)), ("'id", car(id)), ("'author", user.get(())), assoc("'updated", car(app)), assoc("'content", car(app))),)
+ debug('dashboards.py::put::appentry', appentry)
+
+ dashboard = putapp(id, appentry, getdashboard(dashboardid(user), cache))
+ return putdashboard(dashboardid(user), dashboard, cache)
+
+# Get apps from the user's dashboard
+def get(id, user, cache, apps):
+ debug('dashboards.py::get::id', id)
+
+ def findapp(id, dashboard):
+ if isNil(dashboard):
+ return None
+ if car(id) == cadr(assoc("'id", car(dashboard))):
+ return (car(dashboard),)
+ return findapp(id, cdr(dashboard))
+
+ if isNil(id):
+ dashboard = ((("'feed", ("'title", "Your Apps"), ("'id", user.get(()))) + getdashboard(dashboardid(user), cache)),)
+ debug('dashboards.py::get::dashboard', dashboard)
+ return dashboard
+
+ app = findapp(id, getdashboard(dashboardid(user), cache))
+ debug('dashboards.py::get::app', app)
+ return app
+
+# Delete apps from the user's dashboard
+def delete(id, user, cache, apps):
+ debug('dashboards.py::delete::id', id)
+ if isNil(id):
+ return cache.delete(dashboardid(user))
+
+ def deleteapp(id, dashboard):
+ if isNil(dashboard):
+ return ()
+ if car(id) == cadr(assoc("'id", car(dashboard))):
+ return cdr(dashboard)
+ return cons(car(dashboard), deleteapp(id, cdr(dashboard)))
+
+ dashboard = getdashboard(dashboardid(user), cache)
+ deleted = deleteapp(id, dashboard)
+ if deleted == dashboard:
+ return False
+ return putdashboard(dashboardid(user), deleted, cache)
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data-backup b/sca-cpp/branches/lightweight-sca/hosting/server/data-backup
new file mode 100755
index 0000000000..f66e947f84
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data-backup
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# 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.
+
+cd ../../
+tar czf ../data-backup.tar.gz hosting/server/data
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/accounts/admin/user.account b/sca-cpp/branches/lightweight-sca/hosting/server/data/accounts/admin/user.account
new file mode 100644
index 0000000000..4f4a754a92
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/accounts/admin/user.account
@@ -0,0 +1 @@
+((entry (title "Admin") (id "admin")))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/accounts/jane/user.account b/sca-cpp/branches/lightweight-sca/hosting/server/data/accounts/jane/user.account
new file mode 100644
index 0000000000..a3cf7e2c3d
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/accounts/jane/user.account
@@ -0,0 +1 @@
+((entry (title "Jane Doe") (id "jane") (content (account (description "This is Jane") (keys (key (((@name "key1") (@value "value1")) ((@name "key2") (@value "value2")) ((@name "key3") (@value "value3")) ((@name "") (@value "")) ((@name "") (@value "")))))))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/accounts/john/user.account b/sca-cpp/branches/lightweight-sca/hosting/server/data/accounts/john/user.account
new file mode 100644
index 0000000000..9989daa228
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/accounts/john/user.account
@@ -0,0 +1 @@
+((entry (title "John Doe") (id "john") (content (account (description "This is John") (keys (key (((@name "key1") (@value "value1")) ((@name "key2") (@value "value2")) ((@name "key3") (@value "value3")) ((@name "key4") (@value "value4")) ((@name "key5") (@value "value5")))))))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/me360/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/me360/app.composite
new file mode 100644
index 0000000000..95c5f78f7e
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/me360/app.composite
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">me360</title>
+ <id>me360</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="start" promote="start"/>
+ <component name="bzprofile" title="buzz profile" color="blue1">
+ <implementation.python script="nuvem/bzprofile.py"/>
+ <service name="bzprofile"/>
+ <reference target="text4" name="id"/>
+ <reference name="bz" visible="false">
+ <binding.http uri="https://www.googleapis.com/buzz/v1/people"/>
+ </reference>
+ </component>
+ <component x="130" y="30" name="fbprofile" title="facebook profile" color="blue1">
+ <implementation.python script="nuvem/fbprofile.py"/>
+ <service name="fbprofile"/>
+ <reference target="text" name="id"/>
+ <reference name="fb" visible="false">
+ <binding.http uri="https://graph.facebook.com"/>
+ </reference>
+ </component>
+ <component x="90" y="170" name="item" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="fbprofile" name="value"/>
+ <property>fbprofile</property>
+ </component>
+ <component x="90" y="190" name="item2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="twprofile" name="value"/>
+ <property>twitprofile</property>
+ </component>
+ <component x="90" y="210" name="item3" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="bzprofile" name="value"/>
+ <property>buzzprofile</property>
+ </component>
+ <component x="60" y="30" name="list31" title="list" color="yellow1">
+ <implementation.python script="nuvem/triple.py"/>
+ <service name="list3"/>
+ <reference target="item" name="first"/>
+ <reference target="item2" name="second"/>
+ <reference target="item3" name="third"/>
+ </component>
+ <component x="10" y="10" name="start" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference target="list31" name="content"/>
+ </component>
+ <component x="220" y="170" name="text" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>jsdelfino</property>
+ </component>
+ <component x="220" y="200" name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>jsdelfino</property>
+ </component>
+ <component x="220" y="230" name="text4" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>jsdelfino</property>
+ </component>
+ <component name="twprofile" title="twitter profile" color="blue1">
+ <implementation.python script="nuvem/twprofile.py"/>
+ <service name="twprofile"/>
+ <reference target="text2" name="id"/>
+ <reference name="tw" visible="false">
+ <binding.http uri="http://api.twitter.com/1/users/show.json"/>
+ </reference>
+ </component>
+ </composite>
+ </content>
+ <link href="me360"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/me360/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/me360/app.stats
new file mode 100644
index 0000000000..31695e59d7
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/me360/app.stats
@@ -0,0 +1 @@
+((entry (title "Check my public social data") (id "me360") (author "admin@example.com") (updated "Apr 28, 2012") (content (stats (description "Sample app"))))) \ No newline at end of file
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/me360/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/me360/htdocs/app.html
new file mode 100644
index 0000000000..4ba163b6c9
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/me360/htdocs/app.html
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">me360</title>
+ <id>me360</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h2" class="h2" style="position: absolute; top: 0px; left: 2px; ">
+ <H2>Me360</H2>
+ </SPAN>
+ <SPAN id="page:section" class="section" style="position: absolute; top: 27px; width: 100%; left: 2px; ">
+ <SPAN>Facebook</SPAN>
+ </SPAN>
+ <SPAN id="fbprofile" class="table" style="position: absolute; top: 63px; width: 100%; left: 2px; ">
+ <TABLE class="datatable" style="width: 100%;">
+ <TBODY>
+ <TR>
+ <TD>=fbprofile</TD>
+ <TD>...</TD>
+ </TR>
+ <TR>
+ <TD>...</TD>
+ <TD>...</TD>
+ </TR>
+ </TBODY>
+ </TABLE>
+ </SPAN>
+ <SPAN id="page:section" class="section" style="position: absolute; top: 288px; width: 100%; left: 2px; ">
+ <SPAN>Twitter</SPAN>
+ </SPAN>
+ <SPAN id="twitprofile" class="table" style="position: absolute; top: 324px; width: 100%; left: 2px; ">
+ <TABLE class="datatable" style="width: 100%;">
+ <TBODY>
+ <TR>
+ <TD>=twitprofile</TD>
+ <TD>...</TD>
+ </TR>
+ <TR>
+ <TD>...</TD>
+ <TD>...</TD>
+ </TR>
+ </TBODY>
+ </TABLE>
+ </SPAN>
+ <SPAN id="page:section" class="section" style="position: absolute; top: 1368px; width: 100%; left: 2px; ">
+ <SPAN>Buzz</SPAN>
+ </SPAN>
+ <SPAN id="buzzprofile" class="table" style="position: absolute; top: 1404px; width: 100%; left: 2px; ">
+ <TABLE class="datatable" style="width: 100%; ">
+ <TBODY>
+ <TR>
+ <TD>=buzzprofile</TD>
+ <TD>...</TD>
+ </TR>
+ <TR>
+ <TD>...</TD>
+ <TD>...</TD>
+ </TR>
+ </TBODY>
+ </TABLE>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="me360"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme/app.composite
new file mode 100644
index 0000000000..0d25e1b533
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme/app.composite
@@ -0,0 +1,451 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">nearme</title>
+ <id>nearme</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="getlocs" promote="getlocs"/>
+ <service name="location" promote="location"/>
+ <service name="map" promote="map"/>
+ <service name="nearme" promote="nearme"/>
+ <service name="start2" promote="start2"/>
+ <service name="timer" promote="timer"/>
+ <component name="append" title="+" color="yellow1">
+ <implementation.python script="nuvem/append.py"/>
+ <service name="append"/>
+ <reference target="params" name="first"/>
+ <reference target="call2" name="second"/>
+ </component>
+ <component x="130" y="530" name="call" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component name="call2" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name2" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component name="call3" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name4" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component name="call4" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name3" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component name="filedb" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="AppDataFileCache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component x="210" y="120" name="filedb1" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="AppDataFileCache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component name="filedb10" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="AppDataFileCache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component name="filedb11" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="AppDataFileCache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component xmlns="" name="filedb4" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="AppDataFileCache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component xmlns="" name="filedb5" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="AppDataFileCache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component xmlns="" name="filedb6" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="AppDataFileCache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component xmlns="" name="filedb8" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="AppDataFileCache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component xmlns="" name="filedb9" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="AppDataFileCache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component x="190" y="120" name="get1" title="get" color="pink1">
+ <implementation.python script="nuvem/get.py"/>
+ <service name="get"/>
+ <reference target="filedb1" name="collection"/>
+ <reference target="user4" name="id"/>
+ </component>
+ <component name="get10" title="get" color="pink1">
+ <implementation.python script="nuvem/get.py"/>
+ <service name="get"/>
+ <reference target="filedb11" name="collection"/>
+ <reference target="param5" name="id"/>
+ </component>
+ <component xmlns="" name="get3" title="get" color="pink1">
+ <implementation.python script="nuvem/get.py"/>
+ <service name="get"/>
+ <reference target="filedb4" name="collection"/>
+ <reference target="param3" name="id"/>
+ </component>
+ <component xmlns="" name="get4" title="get" color="pink1">
+ <implementation.python script="nuvem/get.py"/>
+ <service name="get"/>
+ <reference target="filedb5" name="collection"/>
+ <reference target="param4" name="id"/>
+ </component>
+ <component xmlns="" name="get5" title="get" color="pink1">
+ <implementation.python script="nuvem/get.py"/>
+ <service name="get"/>
+ <reference target="filedb6" name="collection"/>
+ <reference target="param2" name="id"/>
+ </component>
+ <component xmlns="" name="get7" title="get" color="pink1">
+ <implementation.python script="nuvem/get.py"/>
+ <service name="get"/>
+ <reference target="filedb8" name="collection"/>
+ <reference target="param7" name="id"/>
+ </component>
+ <component xmlns="" name="get8" title="get" color="pink1">
+ <implementation.python script="nuvem/get.py"/>
+ <service name="get"/>
+ <reference target="filedb9" name="collection"/>
+ <reference target="param6" name="id"/>
+ </component>
+ <component name="get9" title="get" color="pink1">
+ <implementation.python script="nuvem/get.py"/>
+ <service name="get"/>
+ <reference target="filedb10" name="collection"/>
+ <reference target="user5" name="id"/>
+ </component>
+ <component x="310" y="270" name="getlocs" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="list4" name="content"/>
+ </component>
+ <component x="80" y="610" name="gmap1" title="map" color="blue1">
+ <implementation.python script="nuvem/gmap.py"/>
+ <service name="gmap"/>
+ <reference target="call" name="locations"/>
+ <reference name="s" visible="false">
+ <binding.http uri="http://maps.google.com/maps/api/staticmap"/>
+ </reference>
+ </component>
+ <component x="110" y="90" name="item" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="user3" name="value"/>
+ <property>me</property>
+ </component>
+ <component x="110" y="390" name="item10" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="url" name="value"/>
+ <property>mapimg</property>
+ </component>
+ <component x="660" y="350" name="item11" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="get9" name="value"/>
+ <property>x</property>
+ </component>
+ <component x="660" y="400" name="item12" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="get10" name="value"/>
+ <property>1</property>
+ </component>
+ <component x="660" y="460" name="item4" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="get3" name="value"/>
+ <property>2</property>
+ </component>
+ <component x="660" y="530" name="item5" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="get4" name="value"/>
+ <property>3</property>
+ </component>
+ <component x="110" y="330" name="item6" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="last4" name="value"/>
+ <property>time3</property>
+ </component>
+ <component x="110" y="260" name="item7" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="last3" name="value"/>
+ <property>time2</property>
+ </component>
+ <component x="100" y="200" name="item8" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="last2" name="value"/>
+ <property>time1</property>
+ </component>
+ <component x="100" y="120" name="item9" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="last" name="value"/>
+ <property>mytime</property>
+ </component>
+ <component name="last" title="last" color="yellow1">
+ <implementation.python script="nuvem/last.py"/>
+ <service name="last"/>
+ <reference target="get1" name="list"/>
+ </component>
+ <component name="last2" title="last" color="yellow1">
+ <implementation.python script="nuvem/last.py"/>
+ <service name="last"/>
+ <reference target="get5" name="list"/>
+ </component>
+ <component x="160" y="220" name="last3" title="last" color="yellow1">
+ <implementation.python script="nuvem/last.py"/>
+ <service name="last"/>
+ <reference target="get8" name="list"/>
+ </component>
+ <component name="last4" title="last" color="yellow1">
+ <implementation.python script="nuvem/last.py"/>
+ <service name="last"/>
+ <reference target="get7" name="list"/>
+ </component>
+ <component name="list1" title="list.." color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item" name="item" clonable="true"/>
+ <reference target="item9" name="item" clonable="true"/>
+ <reference target="item8" name="item" clonable="true"/>
+ <reference target="item7" name="item" clonable="true"/>
+ <reference target="item6" name="item" clonable="true"/>
+ <reference target="item10" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list2" title="list.." color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="text7" name="item" clonable="true"/>
+ <reference target="param10" name="item" clonable="true"/>
+ <reference target="param" name="item" clonable="true"/>
+ <reference target="now" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list4" title="list.." color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item11" name="item" clonable="true"/>
+ <reference target="item12" name="item" clonable="true"/>
+ <reference target="item4" name="item" clonable="true"/>
+ <reference target="item5" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="310" y="80" name="location" title="location" color="green1">
+ <implementation.python script="nuvem/location.py"/>
+ <service name="location" visible="false">
+ <binding.http uri="location"/>
+ </service>
+ <reference target="put" name="content"/>
+ </component>
+ <component x="10" y="460" name="map" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="gmap1" name="content"/>
+ </component>
+ <component name="name" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>getlocs</property>
+ </component>
+ <component name="name2" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>getlocs</property>
+ </component>
+ <component name="name3" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>nearme</property>
+ </component>
+ <component name="name4" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>nearme</property>
+ </component>
+ <component x="10" y="60" name="nearme" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="list1" name="content"/>
+ </component>
+ <component x="500" y="250" name="now" title="now" color="orange1">
+ <implementation.python script="nuvem/now.py"/>
+ <service name="now"/>
+ <reference target="text" name="format"/>
+ </component>
+ <component xmlns="" name="number" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>5000</property>
+ </component>
+ <component x="500" y="220" name="param" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>longitude</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component x="500" y="200" name="param10" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>latitude</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component name="param2" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>friend1</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component name="param3" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>friend2</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component name="param4" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>friend3</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component name="param5" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>friend1</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component name="param6" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>friend2</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component name="param7" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>friend3</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component xmlns="" name="params" title="?params" color="green1">
+ <implementation.python script="nuvem/params.py"/>
+ <service name="params"/>
+ <property name="query" visible="false"/>
+ </component>
+ <component xmlns="" name="put" title="put" color="pink1">
+ <implementation.python script="nuvem/put.py"/>
+ <service name="put"/>
+ <reference target="filedb" name="collection"/>
+ <reference target="user" name="id"/>
+ <reference target="list2" name="value"/>
+ </component>
+ <component x="10" y="10" name="start2" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference target="call4" name="content"/>
+ </component>
+ <component name="text" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>%a %b %d, %I:%M %p</property>
+ </component>
+ <component name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>/components/map</property>
+ </component>
+ <component xmlns="" x="500" y="170" name="text7" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>green</property>
+ </component>
+ <component x="310" y="10" name="timer" title="timer" color="green1">
+ <implementation.python script="nuvem/timer.py"/>
+ <service name="timer" visible="false">
+ <binding.http uri="timer"/>
+ </service>
+ <reference target="number" name="n"/>
+ <reference target="call3" name="content"/>
+ </component>
+ <component name="url" title="url" color="green1">
+ <implementation.python script="nuvem/url.py"/>
+ <service name="url"/>
+ <reference target="text2" name="address"/>
+ <reference target="append" name="args"/>
+ </component>
+ <component xmlns="" name="user" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ <component xmlns="" name="user3" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ <component xmlns="" x="210" y="150" name="user4" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ <component name="user5" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ </composite>
+ </content>
+ <link href="nearme"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme/app.stats
new file mode 100644
index 0000000000..5bc3a2ed3c
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme/app.stats
@@ -0,0 +1 @@
+((entry (title "nearme") (id "nearme") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme/htdocs/app.html
new file mode 100644
index 0000000000..a7ac45d507
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme/htdocs/app.html
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">nearme</title>
+ <id>nearme</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h2" class="h2" style="position: absolute; top: 0px; left: 2px; ">
+ <H2>Nearme</H2>
+ </SPAN>
+ <SPAN id="me" class="h2" style="position: absolute; top: 0px; left: 101px; ">
+ <H2>=me</H2>
+ </SPAN>
+ <SPAN style="position: absolute; top: 0px; left: 182px; " class="text" id="mytime">
+ <SPAN>=mytime</SPAN>
+ </SPAN>
+ <SPAN id="page:section" class="section" style="position: absolute; top: 27px; width: 100%; left: 2px; ">
+ <SPAN>My friends</SPAN>
+ </SPAN>
+ <SPAN style="position: absolute; top: 54px; left: 2px; " class="entry" id="friend1">
+ <INPUT type="text" size="20" value="=friend1" autocapitalize="off"/>
+ </SPAN>
+ <SPAN style="position: absolute; top: 54px; left: 182px; " class="text" id="time1">
+ <SPAN>=time1</SPAN>
+ </SPAN>
+ <SPAN style="position: absolute; top: 81px; left: 2px; " class="entry" id="friend2">
+ <INPUT type="text" size="20" value="=friend2" autocapitalize="off"/>
+ </SPAN>
+ <SPAN style="position: absolute; top: 81px; left: 182px; " class="text" id="time2">
+ <SPAN>=time2</SPAN>
+ </SPAN>
+ <SPAN style="position: absolute; top: 108px; left: 2px; " class="entry" id="friend3">
+ <INPUT type="text" size="20" value="=friend3" autocapitalize="off"/>
+ </SPAN>
+ <SPAN style="position: absolute; top: 108px; left: 182px; " class="text" id="time3">
+ <SPAN>=time3</SPAN>
+ </SPAN>
+ <SPAN style="position: absolute; top: 135px; left: 2px; " class="img" id="mapimg">
+ <IMG src="/public/img.png"/>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="nearme"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme2/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme2/app.composite
new file mode 100644
index 0000000000..cf41a420a5
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme2/app.composite
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">nearme2</title>
+ <id>nearme2</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="location" promote="location"/>
+ <service name="start1" promote="start1"/>
+ <service name="timer" promote="timer"/>
+ <component x="250" y="230" name="append1" title="+" color="yellow1">
+ <implementation.python script="nuvem/append.py"/>
+ <service name="append"/>
+ <reference target="text5" name="first"/>
+ <reference target="get3" name="second"/>
+ </component>
+ <component x="250" y="330" name="append2" title="+" color="yellow1">
+ <implementation.python script="nuvem/append.py"/>
+ <service name="append"/>
+ <reference target="text6" name="first"/>
+ <reference target="get4" name="second"/>
+ </component>
+ <component x="120" y="10" name="filedb2" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component x="410" y="260" name="filedb4" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component x="400" y="370" name="filedb5" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component x="270" y="260" name="get3" title="get" color="pink1">
+ <implementation.python script="nuvem/get.py"/>
+ <service name="get"/>
+ <reference target="filedb4" name="collection"/>
+ <reference target="text2" name="id"/>
+ </component>
+ <component x="270" y="350" name="get4" title="get" color="pink1">
+ <implementation.python script="nuvem/get.py"/>
+ <service name="get"/>
+ <reference target="filedb5" name="collection"/>
+ <reference target="text8" name="id"/>
+ </component>
+ <component x="200" y="230" name="gmap1" title="map" color="blue1">
+ <implementation.python script="nuvem/gmap.py"/>
+ <service name="gmap"/>
+ <reference target="list21" name="locations"/>
+ <reference name="s" visible="false">
+ <binding.http uri="http://maps.google.com/maps/api/staticmap"/>
+ </reference>
+ </component>
+ <component x="150" y="230" name="htinline2" title="inline" color="white1">
+ <implementation.python script="nuvem/htinline.py"/>
+ <service name="htinline"/>
+ <reference target="gmap1" name="value"/>
+ </component>
+ <component x="40" y="150" name="item1" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="user1" name="value"/>
+ <property>me</property>
+ </component>
+ <component x="50" y="210" name="item10" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="htinline2" name="value"/>
+ <property>img</property>
+ </component>
+ <component x="290" y="90" name="item2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="append1" name="value"/>
+ <property>S</property>
+ </component>
+ <component x="290" y="190" name="item3" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="append2" name="value"/>
+ <property>C</property>
+ </component>
+ <component x="190" y="240" name="list21" title="list" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="item2" name="first"/>
+ <reference target="item3" name="second"/>
+ </component>
+ <component x="100" y="110" name="list24" title="list" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="param10" name="first"/>
+ <reference target="param" name="second"/>
+ </component>
+ <component x="10" y="50" name="location" title="location" color="green1">
+ <implementation.python script="nuvem/location.py"/>
+ <service name="location" visible="false">
+ <binding.http uri="location"/>
+ </service>
+ <reference target="put1" name="content"/>
+ </component>
+ <component xmlns="" name="number" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>10000</property>
+ </component>
+ <component x="280" y="90" name="param" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>longitude</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component x="280" y="70" name="param10" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>latitude</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component x="70" y="60" name="put1" title="put" color="pink1">
+ <implementation.python script="nuvem/put.py"/>
+ <service name="put"/>
+ <reference target="filedb2" name="collection"/>
+ <reference target="user" name="id"/>
+ <reference target="list24" name="value"/>
+ </component>
+ <component x="10" y="10" name="start1" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference target="item1" name="content"/>
+ </component>
+ <component x="410" y="290" name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>john</property>
+ </component>
+ <component x="270" y="230" name="text5" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>blue</property>
+ </component>
+ <component x="270" y="320" name="text6" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>pink</property>
+ </component>
+ <component x="410" y="400" name="text8" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>jane</property>
+ </component>
+ <component x="10" y="170" name="timer" title="timer" color="green1">
+ <implementation.python script="nuvem/timer.py"/>
+ <service name="timer" visible="false">
+ <binding.http uri="timer"/>
+ </service>
+ <reference target="number" name="n"/>
+ <reference target="item10" name="content"/>
+ </component>
+ <component xmlns="" x="120" y="30" name="user" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ <component x="80" y="20" name="user1" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ </composite>
+ </content>
+ <link href="nearme2"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme2/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme2/app.stats
new file mode 100644
index 0000000000..c6d99481ae
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme2/app.stats
@@ -0,0 +1 @@
+((entry (title "nearme2") (id "nearme2") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme2/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme2/htdocs/app.html
new file mode 100644
index 0000000000..6e7cb49f94
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/nearme2/htdocs/app.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">nearme2</title>
+ <id>nearme2</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h1" class="h1" style="position: absolute; top: 0px; left: 2px; ">
+ <H1>Hello</H1>
+ </SPAN>
+ <SPAN id="me" class="h1" style="position: absolute; top: 0px; left: 56px; ">
+ <H1>=me</H1>
+ </SPAN>
+ <SPAN id="img" class="img" style="position: absolute; top: 36px; left: 2px; ">
+ <IMG src="/public/img.png"/>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="nearme2"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/new/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/new/app.composite
new file mode 100644
index 0000000000..f8bc48efa3
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/new/app.composite
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">new</title>
+ <id>new</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="comment1" promote="comment1"/>
+ <service name="start1" promote="start1"/>
+ <component x="10" y="0" name="comment1" title="{propval}" color="white">
+ <implementation.python script="nuvem/comment.py"/>
+ <service name="comment" visible="false"/>
+ <property>Change this example to do what you want</property>
+ </component>
+ <component x="80" y="40" name="item1" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="user1" name="value"/>
+ <property>me</property>
+ </component>
+ <component name="list1" title="list.." color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item1" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="10" y="40" name="start1" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference target="list1" name="content"/>
+ </component>
+ <component name="user1" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ </composite>
+ </content>
+ <link href="new"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/new/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/new/app.stats
new file mode 100644
index 0000000000..7c0571bf2b
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/new/app.stats
@@ -0,0 +1 @@
+((entry (title "An empty app template") (id "new") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/new/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/new/htdocs/app.html
new file mode 100644
index 0000000000..58f8f82331
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/new/htdocs/app.html
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">new</title>
+ <id>new</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h1" class="h1" style="position: absolute; top: 0px; left: 0px; ">
+ <H1>Hello</H1>
+ </SPAN>
+ <SPAN id="me" class="h1" style="position: absolute; top: 0px; left: 56px; ">
+ <H1>=me</H1>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="new"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/ourphotos/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/ourphotos/app.composite
new file mode 100644
index 0000000000..57ea520209
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/ourphotos/app.composite
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">ourphotos</title>
+ <id>ourphotos</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="start" promote="start"/>
+ <component name="append" title="+" color="yellow1">
+ <implementation.python script="nuvem/append.py"/>
+ <service name="append"/>
+ <reference target="values" name="first"/>
+ <reference target="values2" name="second"/>
+ </component>
+ <component name="flkalbum" title="flicker album" color="blue1">
+ <implementation.python script="nuvem/flkalbum.py"/>
+ <service name="flkalbum"/>
+ <reference target="text7" name="id"/>
+ <reference name="flk" visible="false">
+ <binding.http uri="http://api.flickr.com/services/feeds/photos_public.gne"/>
+ </reference>
+ </component>
+ <component x="200" y="70" name="htattrs1" title="attrs:" color="white1">
+ <implementation.python script="nuvem/htattrs.py"/>
+ <service name="htattrs"/>
+ <reference target="list12" name="value"/>
+ </component>
+ <component x="140" y="40" name="htimg2" title="img" color="white1">
+ <implementation.python script="nuvem/htimg.py"/>
+ <service name="htimg"/>
+ <reference target="list21" name="value"/>
+ </component>
+ <component x="260" y="70" name="htstyle2" title="style" color="white1">
+ <implementation.python script="nuvem/htstyle.py"/>
+ <service name="htstyle"/>
+ <reference target="item1" name="value"/>
+ </component>
+ <component name="item" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="map2" name="value"/>
+ <property>images</property>
+ </component>
+ <component x="310" y="70" name="item1" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="pixels1" name="value"/>
+ <property>width</property>
+ </component>
+ <component x="240" y="70" name="list12" title="list" color="yellow1">
+ <implementation.python script="nuvem/single.py"/>
+ <service name="list1"/>
+ <reference target="htstyle2" name="value"/>
+ </component>
+ <component x="170" y="40" name="list21" title="list" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="valueof2" name="first"/>
+ <reference target="htattrs1" name="second"/>
+ </component>
+ <component name="map2" title="map" color="yellow1">
+ <implementation.python script="nuvem/map_.py"/>
+ <service name="map"/>
+ <reference target="name5" name="item"/>
+ <reference target="htimg2" name="transform"/>
+ <reference target="shuffle" name="list"/>
+ </component>
+ <component name="name3" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>src</property>
+ </component>
+ <component name="name4" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>m</property>
+ </component>
+ <component name="name5" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>image</property>
+ </component>
+ <component x="420" y="70" name="number1" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>320</property>
+ </component>
+ <component name="picalbum" title="picasa album" color="blue1">
+ <implementation.python script="nuvem/picalbum.py"/>
+ <service name="picalbum"/>
+ <reference target="text5" name="id"/>
+ <reference name="pic" visible="false">
+ <binding.http uri="https://picasaweb.google.com/data/feed/api/user"/>
+ </reference>
+ </component>
+ <component x="280" y="70" name="pixels1" title="pixels" color="white1">
+ <implementation.python script="nuvem/pixels.py"/>
+ <service name="pixels"/>
+ <reference target="number1" name="value"/>
+ </component>
+ <component name="select" title="select" color="yellow1">
+ <implementation.python script="nuvem/select.py"/>
+ <service name="select"/>
+ <reference target="name3" name="path"/>
+ <reference target="picalbum" name="list"/>
+ </component>
+ <component name="select2" title="select" color="yellow1">
+ <implementation.python script="nuvem/select.py"/>
+ <service name="select"/>
+ <reference target="name4" name="path"/>
+ <reference target="flkalbum" name="list"/>
+ </component>
+ <component x="180" y="180" name="shuffle" title="shuffle" color="yellow1">
+ <implementation.python script="nuvem/shuffle_.py"/>
+ <service name="shuffle"/>
+ <reference target="append" name="list"/>
+ </component>
+ <component x="10" y="10" name="start" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference target="item" name="content"/>
+ </component>
+ <component name="text5" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>jsdelfino</property>
+ </component>
+ <component name="text7" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>61049883@N06</property>
+ </component>
+ <component x="470" y="30" name="valueof2" title="valueof" color="orange1">
+ <implementation.python script="nuvem/valueof.py"/>
+ <service name="valueof"/>
+ <property>image</property>
+ </component>
+ <component name="values" title="values" color="yellow1">
+ <implementation.python script="nuvem/values.py"/>
+ <service name="values"/>
+ <reference target="select" name="list"/>
+ </component>
+ <component name="values2" title="values" color="yellow1">
+ <implementation.python script="nuvem/values.py"/>
+ <service name="values"/>
+ <reference target="select2" name="list"/>
+ </component>
+ </composite>
+ </content>
+ <link href="ourphotos"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/ourphotos/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/ourphotos/app.stats
new file mode 100644
index 0000000000..6986fbea1b
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/ourphotos/app.stats
@@ -0,0 +1 @@
+((entry (title "Our photos of an event") (id "ourphotos") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/ourphotos/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/ourphotos/htdocs/app.html
new file mode 100644
index 0000000000..a226d6daaf
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/ourphotos/htdocs/app.html
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">ourphotos</title>
+ <id>ourphotos</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h2" class="h2" style="position: absolute; top: 0px; left: 2px; ">
+ <H2>Our Photos</H2>
+ </SPAN>
+ <SPAN id="images" class="list" style="position: absolute; top: 27px; width: 100%; left: 2px; ">
+ <TABLE class="datatable" style="width: 100%; ">
+ <TBODY>
+ <TR>
+ <TD>=images</TD>
+ </TR>
+ <TR>
+ <TD>...</TD>
+ </TR>
+ </TBODY>
+ </TABLE>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="ourphotos"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/shoppingcart/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/shoppingcart/app.composite
new file mode 100644
index 0000000000..235566c7f2
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/shoppingcart/app.composite
@@ -0,0 +1,603 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">shoppingcart</title>
+ <id>shoppingcart</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="Add to cart" promote="Add to cart"/>
+ <service name="Check out" promote="Check out"/>
+ <service name="Empty" promote="Empty"/>
+ <service name="carthtml" promote="carthtml"/>
+ <service name="catalog" promote="catalog"/>
+ <service name="cataloghtml" promote="cataloghtml"/>
+ <service name="getcart" promote="getcart"/>
+ <service name="order" promote="order"/>
+ <service name="start" promote="start"/>
+ <service name="total" promote="total"/>
+ <component x="290" y="290" name="Add to cart" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="list33" name="content"/>
+ </component>
+ <component x="10" y="590" name="Check out" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="list3" name="content"/>
+ </component>
+ <component x="10" y="450" name="Empty" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="list32" name="content"/>
+ </component>
+ <component name="append" title="+" color="yellow1">
+ <implementation.python script="nuvem/append.py"/>
+ <service name="append"/>
+ <reference target="call2" name="first"/>
+ <reference target="lookup" name="second"/>
+ </component>
+ <component name="call10" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name12" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component name="call11" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name16" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component name="call12" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name13" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component name="call13" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name17" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component name="call14" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name19" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component name="call15" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name20" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="250" y="630" name="call16" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name21" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component name="call17" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name4" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component name="call2" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name5" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component name="call3" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name6" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="370" y="590" name="call4" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name15" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component name="call5" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name8" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="370" y="620" name="call6" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name10" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="250" y="590" name="call7" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name9" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="500" y="690" name="call8" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name11" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="210" y="280" name="call9" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name2" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="10" y="320" name="carthtml" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="item6" name="content"/>
+ </component>
+ <component x="290" y="10" name="catalog" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="list31" name="content"/>
+ </component>
+ <component x="10" y="160" name="cataloghtml" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="item" name="content"/>
+ </component>
+ <component name="delete2" title="delete" color="pink1">
+ <implementation.python script="nuvem/delete.py"/>
+ <service name="delete"/>
+ <reference target="filedb2" name="collection"/>
+ <reference target="user2" name="id"/>
+ </component>
+ <component name="filedb" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component name="filedb2" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component name="filedb3" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component x="130" y="420" name="format1" title="format" color="cyan1">
+ <implementation.python script="nuvem/format_.py"/>
+ <service name="format"/>
+ <reference target="text6" name="pattern"/>
+ <reference target="valueof2" name="values"/>
+ </component>
+ <component x="280" y="350" name="format2" title="format" color="cyan1">
+ <implementation.python script="nuvem/format_.py"/>
+ <service name="format"/>
+ <reference target="text5" name="pattern"/>
+ <reference target="valueof" name="values"/>
+ </component>
+ <component x="300" y="610" name="format3" title="format" color="cyan1">
+ <implementation.python script="nuvem/format_.py"/>
+ <service name="format"/>
+ <reference target="text4" name="pattern"/>
+ <reference target="call8" name="values"/>
+ </component>
+ <component name="get" title="get" color="pink1">
+ <implementation.python script="nuvem/get.py"/>
+ <service name="get"/>
+ <reference target="filedb" name="collection"/>
+ <reference target="user" name="id"/>
+ </component>
+ <component x="470" y="10" name="getcart" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="get" name="content"/>
+ </component>
+ <component x="160" y="250" name="htcheck2" title="checkbox" color="white1">
+ <implementation.python script="nuvem/htcheck.py"/>
+ <service name="htcheck"/>
+ <reference target="list22" name="value"/>
+ </component>
+ <component name="item" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="map" name="value"/>
+ <property>catalog</property>
+ </component>
+ <component x="410" y="170" name="item1" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference name="value" target="total1"/>
+ <property>total</property>
+ </component>
+ <component x="530" y="80" name="item10" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="number4" name="value"/>
+ <property>Kiwi</property>
+ </component>
+ <component x="250" y="530" name="item11" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="delete2" name="value"/>
+ <property>delresult</property>
+ </component>
+ <component name="item12" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="sendgtalk" name="value"/>
+ <property>sendresult</property>
+ </component>
+ <component name="item4" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="call11" name="value"/>
+ <property>message</property>
+ </component>
+ <component name="item5" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text2" name="value"/>
+ <property>message</property>
+ </component>
+ <component name="item6" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="map2" name="value"/>
+ <property>cart</property>
+ </component>
+ <component x="380" y="390" name="item7" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="put" name="value"/>
+ <property>putresult</property>
+ </component>
+ <component x="530" y="20" name="item8" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="number" name="value"/>
+ <property>Mango</property>
+ </component>
+ <component x="540" y="50" name="item9" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="number2" name="value"/>
+ <property>Passion</property>
+ </component>
+ <component x="220" y="250" name="list22" title="list" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="text8" name="first"/>
+ <reference target="format2" name="second"/>
+ </component>
+ <component name="list3" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item4" name="item" clonable="true"/>
+ <reference target="item12" name="item" clonable="true"/>
+ <reference target="call3" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="360" y="20" name="list31" title="list" color="yellow1">
+ <implementation.python script="nuvem/triple.py"/>
+ <service name="list3"/>
+ <reference target="item8" name="first"/>
+ <reference target="item9" name="second"/>
+ <reference target="item10" name="third"/>
+ </component>
+ <component x="50" y="540" name="list32" title="list" color="yellow1">
+ <implementation.python script="nuvem/triple.py"/>
+ <service name="list3"/>
+ <reference target="item11" name="first"/>
+ <reference target="call7" name="second"/>
+ <reference target="call16" name="third"/>
+ </component>
+ <component x="350" y="390" name="list33" title="list" color="yellow1">
+ <implementation.python script="nuvem/triple.py"/>
+ <service name="list3"/>
+ <reference target="item7" name="first"/>
+ <reference target="call4" name="second"/>
+ <reference target="call6" name="third"/>
+ </component>
+ <component name="list4" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item5" name="item" clonable="true"/>
+ <reference target="call5" name="item" clonable="true"/>
+ <reference target="call13" name="item" clonable="true"/>
+ <reference target="call14" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="lookup" title="lookup" color="yellow1">
+ <implementation.python script="nuvem/lookup.py"/>
+ <service name="lookup"/>
+ <reference target="second1" name="name"/>
+ <reference target="call15" name="list"/>
+ </component>
+ <component name="map" title="map" color="yellow1">
+ <implementation.python script="nuvem/map_.py"/>
+ <service name="map"/>
+ <reference target="name" name="item"/>
+ <reference target="htcheck2" name="transform"/>
+ <reference target="call9" name="list"/>
+ </component>
+ <component name="map2" title="map" color="yellow1">
+ <implementation.python script="nuvem/map_.py"/>
+ <service name="map"/>
+ <reference target="name3" name="item"/>
+ <reference target="format1" name="transform"/>
+ <reference target="call10" name="list"/>
+ </component>
+ <component name="name" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>fruit</property>
+ </component>
+ <component name="name10" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>total</property>
+ </component>
+ <component name="name11" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>total</property>
+ </component>
+ <component name="name12" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>getcart</property>
+ </component>
+ <component name="name13" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>order</property>
+ </component>
+ <component name="name15" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>carthtml</property>
+ </component>
+ <component name="name16" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>order</property>
+ </component>
+ <component name="name17" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>carthtml</property>
+ </component>
+ <component name="name19" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>total</property>
+ </component>
+ <component name="name2" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>catalog</property>
+ </component>
+ <component name="name20" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>catalog</property>
+ </component>
+ <component name="name21" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>total</property>
+ </component>
+ <component name="name3" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>fruit</property>
+ </component>
+ <component name="name4" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>getcart</property>
+ </component>
+ <component name="name5" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>getcart</property>
+ </component>
+ <component name="name6" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>emptyCart</property>
+ </component>
+ <component name="name8" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>cataloghtml</property>
+ </component>
+ <component name="name9" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>carthtml</property>
+ </component>
+ <component name="number" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>2.99</property>
+ </component>
+ <component name="number2" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>3.55</property>
+ </component>
+ <component x="650" y="340" name="number3" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>2</property>
+ </component>
+ <component name="number4" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>1.55</property>
+ </component>
+ <component x="300" y="550" name="order" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="format3" name="content"/>
+ </component>
+ <component x="580" y="370" name="param" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>fruit</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component name="put" title="put" color="pink1">
+ <implementation.python script="nuvem/put.py"/>
+ <service name="put"/>
+ <reference target="filedb3" name="collection"/>
+ <reference target="user3" name="id"/>
+ <reference target="append" name="value"/>
+ </component>
+ <component x="650" y="450" name="second1" title="second" color="yellow1">
+ <implementation.python script="nuvem/second.py"/>
+ <service name="second"/>
+ <reference target="split2" name="list"/>
+ </component>
+ <component name="sendgtalk" title="gtalk" color="blue1">
+ <implementation.cpp path="lib/chat" library="libchat-sender2"/>
+ <service name="sendgtalk"/>
+ <reference target="text" name="jid"/>
+ <reference target="text7" name="pass"/>
+ <reference target="text3" name="to"/>
+ <reference target="call12" name="msg"/>
+ </component>
+ <component x="580" y="480" name="split2" title="split" color="cyan1">
+ <implementation.python script="nuvem/split.py"/>
+ <service name="split"/>
+ <reference target="text1" name="separator"/>
+ <reference target="param" name="string"/>
+ </component>
+ <component x="10" y="10" name="start" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference target="list4" name="content"/>
+ </component>
+ <component x="650" y="360" name="sum1" title="sum" color="cyan1">
+ <implementation.python script="nuvem/sum_.py"/>
+ <service name="sum"/>
+ <reference target="values" name="l"/>
+ </component>
+ <component name="text" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>xmppsca.1@gmail.com</property>
+ </component>
+ <component x="580" y="330" name="text1" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property> - </property>
+ </component>
+ <component name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>Welcome to my online store</property>
+ </component>
+ <component name="text3" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>jsdelfino@gmail.com</property>
+ </component>
+ <component x="500" y="660" name="text4" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>Your order has been processed. Your total: ${1}</property>
+ </component>
+ <component x="450" y="280" name="text5" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>${1} - {0}</property>
+ </component>
+ <component x="220" y="550" name="text6" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>${1} - {0}</property>
+ </component>
+ <component name="text7" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>xmpp4sca</property>
+ </component>
+ <component x="280" y="320" name="text8" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>fruit</property>
+ </component>
+ <component x="330" y="120" name="total" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="item1" name="content"/>
+ </component>
+ <component name="total1" x="600" y="130" title="round" color="cyan1">
+ <implementation.python script="nuvem/round_.py"/>
+ <service name="round"/>
+ <reference target="number3" name="n"/>
+ <reference target="sum1" name="x"/>
+ </component>
+ <component name="user" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ <component name="user2" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ <component name="user3" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ <component x="440" y="310" name="valueof" title="valueof" color="orange1">
+ <implementation.python script="nuvem/valueof.py"/>
+ <service name="valueof"/>
+ <property>fruit</property>
+ </component>
+ <component x="210" y="580" name="valueof2" title="valueof" color="orange1">
+ <implementation.python script="nuvem/valueof.py"/>
+ <service name="valueof"/>
+ <property>fruit</property>
+ </component>
+ <component x="790" y="320" name="values" title="values" color="yellow1">
+ <implementation.python script="nuvem/values.py"/>
+ <service name="values"/>
+ <reference target="call17" name="list"/>
+ </component>
+ </composite>
+ </content>
+ <link href="shoppingcart"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/shoppingcart/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/shoppingcart/app.stats
new file mode 100644
index 0000000000..b4c696fbe1
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/shoppingcart/app.stats
@@ -0,0 +1 @@
+((entry (title "My online store") (id "shoppingcart") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/shoppingcart/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/shoppingcart/htdocs/app.html
new file mode 100644
index 0000000000..dbca542ac9
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/shoppingcart/htdocs/app.html
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">shoppingcart</title>
+ <id>shoppingcart</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h2" class="h2" style="position: absolute; top: 0px; left: 2px; ">
+ <H2>Shopping Cart</H2>
+ </SPAN>
+ <SPAN id="message" class="text" style="position: absolute; top: 36px; left: 2px; ">
+ <SPAN>Welcome</SPAN>
+ </SPAN>
+ <SPAN id="page:section" class="section" style="position: absolute; top: 63px; width: 100%; left: 2px; ">
+ <SPAN>Catalog</SPAN>
+ </SPAN>
+ <SPAN id="page:button" class="button" style="position: absolute; top: 63px; left: 146px; ">
+ <INPUT type="button" value="Add to cart" class="graybutton"/>
+ </SPAN>
+ <SPAN id="catalog" class="list" style="position: absolute; top: 99px; width: 100%; left: 2px; ">
+ <TABLE class="datatable" style="width: 100%; ">
+ <TBODY>
+ <TR>
+ <TD>=catalog</TD>
+ </TR>
+ <TR>
+ <TD>...</TD>
+ </TR>
+ </TBODY>
+ </TABLE>
+ </SPAN>
+ <SPAN id="page:section" class="section" style="position: absolute; top: 180px; width: 100%; left: 2px; ">
+ <SPAN>Your cart:</SPAN>
+ </SPAN>
+ <SPAN id="page:text" class="text" style="position: absolute; top: 180px; left: 83px; ">
+ <SPAN>$</SPAN>
+ </SPAN>
+ <SPAN id="total" class="text" style="position: absolute; top: 180px; left: 92px; ">
+ <SPAN>=total</SPAN>
+ </SPAN>
+ <SPAN id="page:button" class="button" style="position: absolute; top: 180px; left: 146px; ">
+ <INPUT type="button" value="Check out" class="graybutton"/>
+ </SPAN>
+ <SPAN id="page:button" class="button" style="position: absolute; top: 180px; left: 245px; ">
+ <INPUT type="button" value="Empty" class="graybutton"/>
+ </SPAN>
+ <SPAN id="cart" class="list" style="position: absolute; top: 216px; width: 100%; left: 2px; ">
+ <TABLE class="datatable" style="width: 100%; ">
+ <TBODY>
+ <TR>
+ <TD>=cart</TD>
+ </TR>
+ <TR>
+ <TD>...</TD>
+ </TR>
+ </TBODY>
+ </TABLE>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="shoppingcart"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/slice/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/slice/app.composite
new file mode 100644
index 0000000000..b36b561a84
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/slice/app.composite
@@ -0,0 +1,511 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">slice</title>
+ <id>slice</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="animation1" promote="animation1"/>
+ <service name="bounce" promote="bounce"/>
+ <service name="feather" promote="feather"/>
+ <service name="gnu" promote="gnu"/>
+ <service name="score" promote="score"/>
+ <service name="sprite" promote="sprite"/>
+ <service name="start" promote="start"/>
+ <component x="350" y="120" name="add1" title="+" color="cyan1">
+ <implementation.python script="nuvem/add.py"/>
+ <service name="add">
+ <documentation>+</documentation>
+ </service>
+ <reference target="number10" name="value1"/>
+ <reference target="get1" name="value2"/>
+ </component>
+ <component x="10" y="90" name="animation1" title="animation" color="green1">
+ <implementation.python script="nuvem/animation.py"/>
+ <service name="animation" visible="false">
+ <binding.http uri="animation"/>
+ </service>
+ <reference target="number6" name="n"/>
+ <reference target="true2" name="loop"/>
+ <reference target="map1" name="content"/>
+ </component>
+ <component x="360" y="10" name="bounce" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="list1" name="content"/>
+ </component>
+ <component x="170" y="150" name="call1" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name5" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="820" y="360" name="call2" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name9" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="750" y="210" name="call3" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name4" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="750" y="330" name="call4" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name10" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="200" y="80" name="call5" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name11" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="10" y="360" name="feather" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="list22" name="content"/>
+ </component>
+ <component x="240" y="100" name="filedb1" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component x="270" y="150" name="filedb2" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component x="890" y="350" name="filedb3" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component x="1100" y="190" name="filedb4" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component x="710" y="160" name="frames1" title="frames" color="white1">
+ <implementation.python script="nuvem/frames.py"/>
+ <service name="frames"/>
+ <reference target="number1" name="msec"/>
+ <reference target="number12" name="loop"/>
+ <reference target="call3" name="content"/>
+ </component>
+ <component x="380" y="140" name="get1" title="get" color="pink1">
+ <implementation.python script="nuvem/get.py"/>
+ <service name="get"/>
+ <reference target="filedb2" name="collection"/>
+ <reference target="user2" name="id"/>
+ </component>
+ <component x="860" y="360" name="get2" title="get" color="pink1">
+ <implementation.python script="nuvem/get.py"/>
+ <service name="get"/>
+ <reference target="filedb3" name="collection"/>
+ <reference target="user4" name="id"/>
+ </component>
+ <component x="10" y="550" name="gnu" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="list23" name="content"/>
+ </component>
+ <component x="360" y="160" name="htstyle2" title="style" color="white1">
+ <implementation.python script="nuvem/htstyle.py"/>
+ <service name="htstyle"/>
+ <reference target="frames1" name="value"/>
+ </component>
+ <component x="950" y="180" name="item1" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="put1" name="value"/>
+ <property>r</property>
+ </component>
+ <component x="210" y="40" name="item2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="user3" name="value"/>
+ <property>me</property>
+ </component>
+ <component x="930" y="400" name="item3" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="get2" name="value"/>
+ <property>score</property>
+ </component>
+ <component x="1050" y="210" name="item4" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="put2" name="value"/>
+ <property>r</property>
+ </component>
+ <component name="list1" title="list.." color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="list28" name="item" clonable="true"/>
+ <reference target="list21" name="item" clonable="true"/>
+ <reference target="list29" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="120" y="160" name="list11" title="list" color="yellow1">
+ <implementation.python script="nuvem/single.py"/>
+ <service name="list1"/>
+ <reference target="list27" name="value"/>
+ </component>
+ <component x="620" y="110" name="list14" title="list" color="yellow1">
+ <implementation.python script="nuvem/single.py"/>
+ <service name="list1"/>
+ <reference target="htstyle2" name="value"/>
+ </component>
+ <component name="list2" title="list.." color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="name6" name="item" clonable="true"/>
+ <reference target="name7" name="item" clonable="true"/>
+ <reference target="name2" name="item" clonable="true"/>
+ <reference target="name8" name="item" clonable="true"/>
+ <reference target="name3" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="670" y="130" name="list21" title="list" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="number5" name="first"/>
+ <reference target="transform1" name="second"/>
+ </component>
+ <component x="780" y="200" name="list22" title="list" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="item1" name="first"/>
+ <reference target="call2" name="second"/>
+ </component>
+ <component x="1030" y="210" name="list23" title="list" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="item4" name="first"/>
+ <reference target="call4" name="second"/>
+ </component>
+ <component x="60" y="10" name="list24" title="list" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="item2" name="first"/>
+ <reference target="call5" name="second"/>
+ </component>
+ <component x="140" y="210" name="list27" title="list" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="call1" name="first"/>
+ <reference target="list14" name="second"/>
+ </component>
+ <component x="110" y="270" name="list28" title="list" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="number20" name="first"/>
+ <reference target="transform2" name="second"/>
+ </component>
+ <component x="670" y="250" name="list29" title="list" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="number24" name="first"/>
+ <reference target="transform3" name="second"/>
+ </component>
+ <component x="80" y="140" name="map1" title="map" color="yellow1">
+ <implementation.python script="nuvem/map_.py"/>
+ <service name="map"/>
+ <reference target="name1" name="item"/>
+ <reference target="list11" name="transform"/>
+ <reference target="range1" name="list"/>
+ </component>
+ <component x="110" y="140" name="name1" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>i</property>
+ </component>
+ <component x="780" y="330" name="name10" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>score</property>
+ </component>
+ <component x="230" y="80" name="name11" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>score</property>
+ </component>
+ <component x="840" y="70" name="name2" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>feather2</property>
+ </component>
+ <component x="850" y="120" name="name3" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>feather3</property>
+ </component>
+ <component x="780" y="220" name="name4" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>bounce</property>
+ </component>
+ <component x="200" y="160" name="name5" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>sprite</property>
+ </component>
+ <component x="400" y="90" name="name6" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>feather1</property>
+ </component>
+ <component x="390" y="180" name="name7" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>gnu1</property>
+ </component>
+ <component x="840" y="90" name="name8" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>gnu2</property>
+ </component>
+ <component x="840" y="360" name="name9" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>score</property>
+ </component>
+ <component x="770" y="170" name="number1" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>3000</property>
+ </component>
+ <component x="380" y="110" name="number10" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>1</property>
+ </component>
+ <component x="710" y="240" name="number11" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>200</property>
+ </component>
+ <component x="280" y="230" name="number12" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>10</property>
+ </component>
+ <component x="1120" y="250" name="number13" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>0</property>
+ </component>
+ <component x="930" y="170" name="number2" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>100</property>
+ </component>
+ <component x="820" y="230" name="number20" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>0</property>
+ </component>
+ <component x="940" y="80" name="number22" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>0</property>
+ </component>
+ <component x="950" y="110" name="number23" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>0</property>
+ </component>
+ <component x="890" y="220" name="number24" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>100</property>
+ </component>
+ <component x="940" y="250" name="number25" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>240</property>
+ </component>
+ <component x="940" y="280" name="number26" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>0</property>
+ </component>
+ <component x="940" y="310" name="number27" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>720</property>
+ </component>
+ <component x="670" y="210" name="number3" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>-400</property>
+ </component>
+ <component x="920" y="230" name="number4" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>360</property>
+ </component>
+ <component x="700" y="130" name="number5" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>50</property>
+ </component>
+ <component x="80" y="150" name="number6" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>4000</property>
+ </component>
+ <component x="150" y="300" name="number7" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>0</property>
+ </component>
+ <component x="150" y="330" name="number8" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>20</property>
+ </component>
+ <component x="580" y="40" name="number9" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>-200</property>
+ </component>
+ <component x="880" y="260" name="put1" title="put" color="pink1">
+ <implementation.python script="nuvem/put.py"/>
+ <service name="put"/>
+ <reference target="filedb1" name="collection"/>
+ <reference target="user1" name="id"/>
+ <reference target="add1" name="value"/>
+ </component>
+ <component x="1080" y="210" name="put2" title="put" color="pink1">
+ <implementation.python script="nuvem/put.py"/>
+ <service name="put"/>
+ <reference target="filedb4" name="collection"/>
+ <reference target="user5" name="id"/>
+ <reference target="number13" name="value"/>
+ </component>
+ <component x="720" y="60" name="random1" title="rand" color="cyan1">
+ <implementation.python script="nuvem/random_.py"/>
+ <service name="random"/>
+ <reference target="list2" name="range"/>
+ </component>
+ <component x="540" y="40" name="random2" title="rand" color="cyan1">
+ <implementation.python script="nuvem/random_.py"/>
+ <service name="random"/>
+ <reference target="number9" name="range"/>
+ </component>
+ <component x="670" y="240" name="random3" title="rand" color="cyan1">
+ <implementation.python script="nuvem/random_.py"/>
+ <service name="random"/>
+ <reference target="number11" name="range"/>
+ </component>
+ <component x="120" y="300" name="range1" title="range" color="yellow1">
+ <implementation.python script="nuvem/range_.py"/>
+ <service name="range"/>
+ <reference target="number7" name="first"/>
+ <reference target="number8" name="last"/>
+ </component>
+ <component x="180" y="10" name="score" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="item3" name="content"/>
+ </component>
+ <component x="360" y="400" name="sprite" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="random1" name="content"/>
+ </component>
+ <component x="10" y="10" name="start" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference target="list24" name="content"/>
+ </component>
+ <component x="550" y="190" name="subtract1" title="-" color="cyan1">
+ <implementation.python script="nuvem/subtract.py"/>
+ <service name="subtract">
+ <documentation>-</documentation>
+ </service>
+ <reference target="number3" name="value1"/>
+ <reference target="random3" name="value2"/>
+ </component>
+ <component x="700" y="160" name="transform1" title="transform" color="white1">
+ <implementation.python script="nuvem/transform.py"/>
+ <service name="transform"/>
+ <reference target="number2" name="x"/>
+ <reference target="subtract1" name="y"/>
+ <reference target="number4" name="d"/>
+ </component>
+ <component x="820" y="250" name="transform2" title="transform" color="white1">
+ <implementation.python script="nuvem/transform.py"/>
+ <service name="transform"/>
+ <reference target="random2" name="x"/>
+ <reference target="number22" name="y"/>
+ <reference target="number23" name="d"/>
+ </component>
+ <component x="890" y="250" name="transform3" title="transform" color="white1">
+ <implementation.python script="nuvem/transform.py"/>
+ <service name="transform"/>
+ <reference target="number25" name="x"/>
+ <reference target="number26" name="y"/>
+ <reference target="number27" name="d"/>
+ </component>
+ <component x="80" y="110" name="true2" title="true" color="orange1">
+ <implementation.python script="nuvem/true_.py"/>
+ <service name="true"/>
+ </component>
+ <component x="240" y="130" name="user1" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ <component x="390" y="140" name="user2" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ <component x="110" y="40" name="user3" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ <component x="890" y="390" name="user4" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ <component x="1110" y="210" name="user5" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ </composite>
+ </content>
+ <link href="slice"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/slice/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/slice/app.stats
new file mode 100644
index 0000000000..bebfcbbaf9
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/slice/app.stats
@@ -0,0 +1 @@
+((entry (title "Slice") (id "slice") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/slice/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/slice/htdocs/app.html
new file mode 100644
index 0000000000..c02f2fa399
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/slice/htdocs/app.html
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">slice</title>
+ <id>slice</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h2" class="h2" style="position: absolute; top: 0px; left: 2px; ">
+ <H2>Hello</H2>
+ </SPAN>
+ <SPAN id="me" class="h2" style="position: absolute; top: 0px; left: 47px; ">
+ <H2>=me</H2>
+ </SPAN>
+ <SPAN id="page:h2" class="h2" style="position: absolute; top: 0px; left: 227px; ">
+ <H2>Score:</H2>
+ </SPAN>
+ <SPAN id="score" class="h2" style="position: absolute; top: 0px; left: 281px; ">
+ <H2>0</H2>
+ </SPAN>
+ <SPAN id="feather2" class="link" style="position: absolute; top: 486px; left: 2px; ">
+ <A href="link:feather">
+ <SPAN>
+ <IMG src="http://www.apache.org/images/feather-small.gif"/>
+ </SPAN>
+ </A>
+ </SPAN>
+ <SPAN id="gnu1" class="link" style="position: absolute; top: 549px; left: 2px; ">
+ <A href="link:gnu">
+ <SPAN>
+ <IMG src="http://www.gnu.org/graphics/lgplv3-147x51.png"/>
+ </SPAN>
+ </A>
+ </SPAN>
+ <SPAN id="feather1" class="link" style="position: absolute; top: 612px; left: 2px; ">
+ <A href="link:feather">
+ <SPAN>
+ <IMG src="http://www.apache.org/images/feather-small.gif"/>
+ </SPAN>
+ </A>
+ </SPAN>
+ <SPAN id="gnu2" class="link" style="position: absolute; top: 666px; left: 2px; ">
+ <A href="link:gnu">
+ <SPAN>
+ <IMG src="http://www.gnu.org/graphics/lgplv3-147x51.png"/>
+ </SPAN>
+ </A>
+ </SPAN>
+ <SPAN id="feather3" class="link" style="position: absolute; top: 729px; left: 2px; ">
+ <A href="link:feather">
+ <SPAN>
+ <IMG src="http://www.apache.org/images/feather-small.gif"/>
+ </SPAN>
+ </A>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="slice"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/test/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/test/app.composite
new file mode 100644
index 0000000000..7a4344df4d
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/test/app.composite
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">test</title>
+ <id>test</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="comment1" promote="comment1"/>
+ <service name="start1" promote="start1"/>
+ <component x="10" y="10" name="comment1" title="{propval}" color="white">
+ <implementation.python script="nuvem/comment.py"/>
+ <service name="comment" visible="false"/>
+ <property>Change this example to do what you want</property>
+ </component>
+ <component x="80" y="40" name="item1" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="user1" name="value"/>
+ <property>me</property>
+ </component>
+ <component x="70" y="70" name="item2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="now1" name="value"/>
+ <property>time</property>
+ </component>
+ <component x="50" y="40" name="list21" title="list" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="item1" name="first"/>
+ <reference target="item2" name="second"/>
+ </component>
+ <component x="120" y="70" name="now1" title="now" color="orange1">
+ <implementation.python script="nuvem/now.py"/>
+ <service name="now"/>
+ <reference name="format"/>
+ </component>
+ <component x="10" y="50" name="start1" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference target="list21" name="content"/>
+ </component>
+ <component name="user1" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ </composite>
+ </content>
+ <link href="test"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/test/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/test/app.stats
new file mode 100644
index 0000000000..8c9b3792ed
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/test/app.stats
@@ -0,0 +1 @@
+((entry (title "An empty test app") (id "test") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/test/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/test/htdocs/app.html
new file mode 100644
index 0000000000..81ab3d3e46
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/test/htdocs/app.html
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">test</title>
+ <id>test</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h1" class="h1" style="position: absolute; top: 0px; left: 0px; ">
+ <H1>Hello</H1>
+ </SPAN>
+ <SPAN id="me" class="h1" style="position: absolute; top: 0px; left: 74px; ">
+ <H1>=me</H1>
+ </SPAN>
+ <SPAN id="page:text" class="text" style="position: absolute; top: 36px; left: 2px; ">
+ <SPAN>The time is:</SPAN>
+ </SPAN>
+ <SPAN id="time" class="text" style="position: absolute; top: 36px; left: 74px; ">
+ <SPAN>=time</SPAN>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="test"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testanimation/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testanimation/app.composite
new file mode 100644
index 0000000000..5dd4c61a53
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testanimation/app.composite
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testanimation</title>
+ <id>testanimation</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="animation1" promote="animation1"/>
+ <service name="start1" promote="start1"/>
+ <component x="10" y="60" name="animation1" title="animation" color="green1">
+ <implementation.python script="nuvem/animation.py"/>
+ <service name="animation" visible="false">
+ <binding.http uri="animation"/>
+ </service>
+ <reference target="number4" name="n"/>
+ <reference target="number6" name="loop"/>
+ <reference target="map1" name="content"/>
+ </component>
+ <component x="220" y="180" name="htattrs2" title="attrs:" color="white1">
+ <implementation.python script="nuvem/htattrs.py"/>
+ <service name="htattrs"/>
+ <reference target="htstyle2" name="value"/>
+ </component>
+ <component x="240" y="120" name="htstyle2" title="style" color="white1">
+ <implementation.python script="nuvem/htstyle.py"/>
+ <service name="htstyle"/>
+ <reference target="list21" name="value"/>
+ </component>
+ <component x="160" y="180" name="item1" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="htattrs2" name="value"/>
+ <property>testdynimg</property>
+ </component>
+ <component x="80" y="10" name="item2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text1" name="value"/>
+ <property>testdynimg</property>
+ </component>
+ <component x="320" y="170" name="item4" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="pixels2" name="value"/>
+ <property>width</property>
+ </component>
+ <component x="120" y="180" name="list11" title="list" color="yellow1">
+ <implementation.python script="nuvem/single.py"/>
+ <service name="list1"/>
+ <reference target="item1" name="value"/>
+ </component>
+ <component x="290" y="180" name="list21" title="list" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="item4" name="first"/>
+ <reference target="transform1" name="second"/>
+ </component>
+ <component x="100" y="150" name="map1" title="map" color="yellow1">
+ <implementation.python script="nuvem/map_.py"/>
+ <service name="map"/>
+ <reference target="name1" name="item"/>
+ <reference target="list11" name="transform"/>
+ <reference target="range1" name="list"/>
+ </component>
+ <component x="400" y="190" name="multiply1" title="*" color="cyan1">
+ <implementation.python script="nuvem/multiply.py"/>
+ <service name="multiply">
+ <documentation>*</documentation>
+ </service>
+ <reference target="valueof1" name="value1"/>
+ <reference target="number3" name="value2"/>
+ </component>
+ <component x="380" y="290" name="multiply2" title="*" color="cyan1">
+ <implementation.python script="nuvem/multiply.py"/>
+ <service name="multiply">
+ <documentation>*</documentation>
+ </service>
+ <reference target="valueof2" name="value1"/>
+ <reference target="number5" name="value2"/>
+ </component>
+ <component x="150" y="110" name="name1" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>t</property>
+ </component>
+ <component x="140" y="110" name="number1" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>0</property>
+ </component>
+ <component x="150" y="140" name="number2" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>121</property>
+ </component>
+ <component x="690" y="290" name="number3" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>3</property>
+ </component>
+ <component x="100" y="90" name="number4" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>20</property>
+ </component>
+ <component x="680" y="340" name="number5" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>6</property>
+ </component>
+ <component x="110" y="120" name="number6" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>5</property>
+ </component>
+ <component x="370" y="180" name="pixels2" title="pixels" color="white1">
+ <implementation.python script="nuvem/pixels.py"/>
+ <service name="pixels"/>
+ <reference target="multiply1" name="value"/>
+ </component>
+ <component x="150" y="400" name="range1" title="range" color="yellow1">
+ <implementation.python script="nuvem/range_.py"/>
+ <service name="range"/>
+ <reference target="number1" name="first"/>
+ <reference target="number2" name="last"/>
+ </component>
+ <component x="10" y="10" name="start1" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference target="item2" name="content"/>
+ </component>
+ <component x="150" y="10" name="text1" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>http://tuscany.apache.org/images/TuscanyLogo.jpg</property>
+ </component>
+ <component x="300" y="240" name="transform1" title="transform" color="white1">
+ <implementation.python script="nuvem/transform.py"/>
+ <service name="transform"/>
+ <reference name="x"/>
+ <reference name="y"/>
+ <reference target="multiply2" name="d"/>
+ </component>
+ <component x="680" y="260" name="valueof1" title="valueof" color="orange1">
+ <implementation.python script="nuvem/valueof.py"/>
+ <service name="valueof"/>
+ <property>t</property>
+ </component>
+ <component x="680" y="310" name="valueof2" title="valueof" color="orange1">
+ <implementation.python script="nuvem/valueof.py"/>
+ <service name="valueof"/>
+ <property>t</property>
+ </component>
+ </composite>
+ </content>
+ <link href="testanimation"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testanimation/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testanimation/app.stats
new file mode 100644
index 0000000000..0b6f8bda73
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testanimation/app.stats
@@ -0,0 +1 @@
+((entry (title "Test animation components") (id "testanimation") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testanimation/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testanimation/htdocs/app.html
new file mode 100644
index 0000000000..02094d84c7
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testanimation/htdocs/app.html
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testanimation</title>
+ <id>testanimation</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h2" class="h2" style="position: absolute; top: 0px; left: 2px; ">
+ <H2>Test animation component</H2>
+ </SPAN>
+ <SPAN id="testdynimg" class="img" style="position: absolute; top: 36px; left: 11px; ">
+ <IMG src="/public/img.png"/>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="testanimation"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testdb/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testdb/app.composite
new file mode 100644
index 0000000000..e2af18e24b
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testdb/app.composite
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testdb</title>
+ <id>testdb</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="delete" promote="delete"/>
+ <service name="get" promote="get"/>
+ <service name="put" promote="put"/>
+ <component x="150" y="10" name="delete" title="delete" color="pink1">
+ <implementation.python script="nuvem/delete.py"/>
+ <service name="delete"/>
+ <reference target="filedb2" name="collection"/>
+ <reference target="list3" name="id"/>
+ </component>
+ <component name="filedb" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component name="filedb2" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component name="filedb3" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component x="20" y="120" name="get" title="get" color="pink1">
+ <implementation.python script="nuvem/get.py"/>
+ <service name="get"/>
+ <reference target="filedb3" name="collection"/>
+ <reference target="list2" name="id"/>
+ </component>
+ <component name="list" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="text" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list2" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="text3" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list3" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="text4" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="13" y="1" name="put" title="put" color="pink1">
+ <implementation.python script="nuvem/put.py"/>
+ <service name="put"/>
+ <reference target="filedb" name="collection"/>
+ <reference target="list" name="id"/>
+ <reference target="text2" name="value"/>
+ </component>
+ <component name="text" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>testkey</property>
+ </component>
+ <component name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>testvalue</property>
+ </component>
+ <component name="text3" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>testkey</property>
+ </component>
+ <component name="text4" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>testkey</property>
+ </component>
+ </composite>
+ </content>
+ <link href="testdb"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testdb/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testdb/app.stats
new file mode 100644
index 0000000000..e33dc221a5
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testdb/app.stats
@@ -0,0 +1 @@
+((entry (title "Test database components") (id "testdb") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testdb/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testdb/htdocs/app.html
new file mode 100644
index 0000000000..a9e77b1012
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testdb/htdocs/app.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testdb</title>
+ <id>testdb</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h1" class="h1" style="position: absolute; top: 0px; left: 2px; ">
+ <H1>Test db components</H1>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="testdb"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testevents/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testevents/app.composite
new file mode 100644
index 0000000000..3d6e2eb687
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testevents/app.composite
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testevents</title>
+ <id>testevents</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="Cancel" promote="Cancel"/>
+ <service name="OK" promote="OK"/>
+ <service name="call" promote="call"/>
+ <service name="call2" promote="call2"/>
+ <service name="call3" promote="call3"/>
+ <service name="compabc" promote="compabc"/>
+ <service name="compxyz" promote="compxyz"/>
+ <service name="location" promote="location"/>
+ <service name="start" promote="start"/>
+ <service name="timer3" promote="timer3"/>
+ <component x="190" y="10" name="Cancel" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="prop2" name="content"/>
+ </component>
+ <component x="190" y="60" name="OK" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="list" name="content"/>
+ </component>
+ <component name="abc" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>abc</property>
+ </component>
+ <component x="190" y="150" name="call" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name2" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="20" y="180" name="call2" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="190" y="190" name="call3" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="text5" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="10" y="230" name="compabc" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="abc" name="content"/>
+ </component>
+ <component x="20" y="270" name="compxyz" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="text12" name="content"/>
+ </component>
+ <component name="item2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text4" name="value"/>
+ <property>status</property>
+ </component>
+ <component name="item3" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text" name="value"/>
+ <property>status</property>
+ </component>
+ <component name="item4" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text2" name="value"/>
+ <property>status</property>
+ </component>
+ <component name="item5" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="param" name="value"/>
+ <property>testtext</property>
+ </component>
+ <component name="item6" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="params2" name="value"/>
+ <property>location</property>
+ </component>
+ <component name="list" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item5" name="item" clonable="true"/>
+ <reference target="item4" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="10" y="130" name="location" title="location" color="green1">
+ <implementation.python script="nuvem/location.py"/>
+ <service name="location" visible="false">
+ <binding.http uri="location"/>
+ </service>
+ <reference target="item6" name="content"/>
+ </component>
+ <component name="name" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>compxyz</property>
+ </component>
+ <component name="name2" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>https://testhttp.example.com:8453/components/property</property>
+ </component>
+ <component name="number" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>3000</property>
+ </component>
+ <component name="param" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>testfield</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component name="params2" title="?params" color="green1">
+ <implementation.python script="nuvem/params.py"/>
+ <service name="params"/>
+ <property name="query" visible="false"/>
+ </component>
+ <component name="prop2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text3" name="value"/>
+ <property>status</property>
+ </component>
+ <component x="15" y="3" name="start" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference target="item3" name="content"/>
+ </component>
+ <component name="text" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>page opens</property>
+ </component>
+ <component name="text12" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>xyz</property>
+ </component>
+ <component name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>ok button clicked</property>
+ </component>
+ <component name="text3" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>cancel button clicked</property>
+ </component>
+ <component name="text4" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>timer fired</property>
+ </component>
+ <component name="text5" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>https://testhttp.example.com:8453/components/property</property>
+ </component>
+ <component x="13" y="58" name="timer3" title="timer" color="green1">
+ <implementation.python script="nuvem/timer.py"/>
+ <service name="timer" visible="false">
+ <binding.http uri="timer"/>
+ </service>
+ <reference target="number" name="n"/>
+ <reference target="item2" name="content"/>
+ </component>
+ </composite>
+ </content>
+ <link href="testevents"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testevents/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testevents/app.stats
new file mode 100644
index 0000000000..9c14040cd0
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testevents/app.stats
@@ -0,0 +1 @@
+((entry (title "Test event components") (id "testevents") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testevents/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testevents/htdocs/app.html
new file mode 100644
index 0000000000..3178459f47
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testevents/htdocs/app.html
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testevents</title>
+ <id>testevents</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h1" class="h1" style="position: absolute; top: 0px; left: 2px; ">
+ <H1>Test events</H1>
+ </SPAN>
+ <SPAN id="testfield" class="entry" style="position: absolute; top: 54px; left: 11px; ">
+ <INPUT type="text" value="=testfield" size="10" autocapitalize="off"/>
+ </SPAN>
+ <SPAN id="page:text" class="text" style="position: absolute; top: 90px; left: 11px; ">
+ <SPAN>Status:</SPAN>
+ </SPAN>
+ <SPAN id="status" class="text" style="position: absolute; top: 90px; left: 92px; ">
+ <SPAN>=status</SPAN>
+ </SPAN>
+ <SPAN id="page:text" class="text" style="position: absolute; top: 117px; left: 11px; ">
+ <SPAN>Field value:</SPAN>
+ </SPAN>
+ <SPAN id="testtext" class="text" style="position: absolute; top: 117px; left: 92px; ">
+ <SPAN>=testtext</SPAN>
+ </SPAN>
+ <SPAN id="page:text" class="text" style="position: absolute; top: 144px; left: 11px; ">
+ <SPAN>Longitude:</SPAN>
+ </SPAN>
+ <SPAN id="longitude" class="text" style="position: absolute; top: 144px; left: 92px; ">
+ <SPAN>=longitude</SPAN>
+ </SPAN>
+ <SPAN id="page:text" class="text" style="position: absolute; top: 171px; left: 11px; ">
+ <SPAN>Latitude:</SPAN>
+ </SPAN>
+ <SPAN id="latitude" class="text" style="position: absolute; top: 171px; left: 92px; ">
+ <SPAN>=latitude</SPAN>
+ </SPAN>
+ <SPAN id="page:button" class="button" style="position: absolute; top: 207px; left: 2px; ">
+ <INPUT type="button" value="OK" class="graybutton"/>
+ </SPAN>
+ <SPAN id="page:button" class="button" style="position: absolute; top: 207px; left: 47px; ">
+ <INPUT type="button" value="Cancel" class="graybutton"/>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="testevents"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testhttp/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testhttp/app.composite
new file mode 100644
index 0000000000..aa78b576d0
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testhttp/app.composite
@@ -0,0 +1,287 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testhttp</title>
+ <id>testhttp</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="call" promote="call"/>
+ <service name="get" promote="get"/>
+ <service name="get2" promote="get2"/>
+ <service name="get3" promote="get3"/>
+ <service name="get4" promote="get4"/>
+ <service name="get5" promote="get5"/>
+ <service name="get6" promote="get6"/>
+ <service name="item" promote="property"/>
+ <service name="parse" promote="parse"/>
+ <component x="20" y="180" name="call" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference target="name" name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component name="first" title="first" color="yellow1">
+ <implementation.python script="nuvem/first.py"/>
+ <service name="first"/>
+ <reference target="rest" name="list"/>
+ </component>
+ <component x="750" y="320" name="format1" title="format" color="cyan1">
+ <implementation.python script="nuvem/format_.py"/>
+ <service name="format"/>
+ <reference target="text12" name="pattern"/>
+ <reference target="list2" name="values"/>
+ </component>
+ <component x="20" y="10" name="get" title="get" color="green1">
+ <implementation.cpp path="lib/http" library="libhttpget"/>
+ <service name="get"/>
+ <property name="timeout" visible="false"/>
+ <reference target="text" name="url"/>
+ </component>
+ <component x="20" y="60" name="get2" title="get" color="green1">
+ <implementation.cpp path="lib/http" library="libhttpget"/>
+ <service name="get"/>
+ <property name="timeout" visible="false"/>
+ <reference target="text2" name="url"/>
+ </component>
+ <component x="20" y="100" name="get3" title="get" color="green1">
+ <implementation.cpp path="lib/http" library="libhttpget"/>
+ <service name="get"/>
+ <property name="timeout" visible="false"/>
+ <reference target="text3" name="url"/>
+ </component>
+ <component x="310" y="10" name="get4" title="get" color="green1">
+ <implementation.cpp path="lib/http" library="libhttpget"/>
+ <service name="get"/>
+ <property name="timeout" visible="false"/>
+ <reference target="text4" name="url"/>
+ </component>
+ <component x="200" y="10" name="get5" title="get" color="green1">
+ <implementation.cpp path="lib/http" library="libhttpget"/>
+ <service name="get"/>
+ <property name="timeout" visible="false"/>
+ <reference target="text5" name="url"/>
+ </component>
+ <component x="20" y="140" name="get6" title="get" color="green1">
+ <implementation.cpp path="lib/http" library="libhttpget"/>
+ <service name="get"/>
+ <property name="timeout" visible="false"/>
+ <reference target="text6" name="url"/>
+ </component>
+ <component name="get7" title="get" color="green1">
+ <implementation.cpp path="lib/http" library="libhttpget"/>
+ <service name="get"/>
+ <property name="timeout" visible="false"/>
+ <reference target="text7" name="url"/>
+ </component>
+ <component name="item2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="user" name="value"/>
+ <property>user</property>
+ </component>
+ <component name="item3" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="params" name="value"/>
+ <property>name</property>
+ </component>
+ <component name="join" title="join" color="cyan1">
+ <implementation.python script="nuvem/join.py"/>
+ <service name="join"/>
+ <reference target="text9" name="separator"/>
+ <reference target="first" name="list"/>
+ </component>
+ <component x="570" y="350" name="keychain1" title="keychain" color="green1">
+ <implementation.python script="nuvem/keychain.py"/>
+ <service name="keychain"/>
+ <reference target="name1" name="name"/>
+ <reference name="account" target="Accounts" visible="false"/>
+ </component>
+ <component x="710" y="290" name="keychain2" title="keychain" color="green1">
+ <implementation.python script="nuvem/keychain.py"/>
+ <service name="keychain"/>
+ <reference target="name2" name="name"/>
+ <reference name="account" target="Accounts" visible="false"/>
+ </component>
+ <component x="720" y="310" name="keychain3" title="keychain" color="green1">
+ <implementation.python script="nuvem/keychain.py"/>
+ <service name="keychain"/>
+ <reference target="name3" name="name"/>
+ <reference name="account" target="Accounts" visible="false"/>
+ </component>
+ <component name="list" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item2" name="item" clonable="true"/>
+ <reference target="item3" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list1" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="keychain1" name="item" clonable="true"/>
+ <reference target="text10" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list2" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="text11" name="item" clonable="true"/>
+ <reference target="text13" name="item" clonable="true"/>
+ <reference target="text14" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list4" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="format1" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="name" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>https://testhttp.example.com:8453/components/property</property>
+ </component>
+ <component x="630" y="350" name="name1" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>twilliosid</property>
+ </component>
+ <component x="780" y="280" name="name2" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>twilliosid</property>
+ </component>
+ <component x="780" y="320" name="name3" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>twilliotoken</property>
+ </component>
+ <component name="params" title="?params" color="green1">
+ <implementation.python script="nuvem/params.py"/>
+ <service name="params"/>
+ <property name="query" visible="false"/>
+ </component>
+ <component x="340" y="180" name="parse" title="parse" color="cyan1">
+ <implementation.python script="nuvem/parse.py"/>
+ <service name="parse"/>
+ <reference target="text8" name="regexp"/>
+ <reference target="join" name="string"/>
+ </component>
+ <component x="20" y="220" name="property" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="list" name="value"/>
+ <property>test</property>
+ </component>
+ <component name="rest" title="rest" color="yellow1">
+ <implementation.python script="nuvem/rest.py"/>
+ <service name="rest"/>
+ <reference target="get7" name="list"/>
+ </component>
+ <component name="text" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>http://www.google.com</property>
+ </component>
+ <component x="530" y="320" name="text1" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>https://api.twilio.com/2010-04-01/Accounts/</property>
+ </component>
+ <component x="570" y="390" name="text10" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>SMS/Messages</property>
+ </component>
+ <component x="580" y="480" name="text11" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>+14155992671</property>
+ </component>
+ <component x="550" y="450" name="text12" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>From={0}&amp;To={1}&amp;Body={2}</property>
+ </component>
+ <component x="700" y="340" name="text13" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>+16508632924</property>
+ </component>
+ <component x="690" y="370" name="text14" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>This is a text message</property>
+ </component>
+ <component x="710" y="290" name="text15" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>application/x-www-form-urlencoded</property>
+ </component>
+ <component name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>http://maps.googleapis.com/maps/api/directions/json?origin=Boston,MA&amp;destination=Concord,MA&amp;waypoints=Charlestown,MA|Lexington,MA&amp;sensor=false</property>
+ </component>
+ <component name="text3" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>http://www.weather.gov/forecasts/xml/sample_products/browser_interface/ndfdXMLclient.php?whichClient=NDFDgen&amp;lat=38.99&amp;lon=-77.01&amp;listLatLon=&amp;lat1=&amp;lon1=&amp;lat2=&amp;lon2=&amp;resolutionSub=&amp;listLat1=&amp;listLon1=&amp;listLat2=&amp;listLon2=&amp;resolutionList=&amp;endPoint1Lat=&amp;endPoint1Lon=&amp;endPoint2Lat=&amp;endPoint2Lon=&amp;listEndPoint1Lat=&amp;listEndPoint1Lon=&amp;listEndPoint2Lat=&amp;listEndPoint2Lon=&amp;zipCodeList=&amp;listZipCodeList=&amp;centerPointLat=&amp;centerPointLon=&amp;distanceLat=&amp;distanceLon=&amp;resolutionSquare=&amp;listCenterPointLat=&amp;listCenterPointLon=&amp;listDistanceLat=&amp;listDistanceLon=&amp;listResolutionSquare=&amp;citiesLevel=&amp;listCitiesLevel=&amp;sector=&amp;gmlListLatLon=&amp;featureType=&amp;requestedTime=&amp;startTime=&amp;endTime=&amp;compType=&amp;propertyName=&amp;product=time-series&amp;begin=2004-01-01T00%3A00%3A00&amp;end=2015-03-10T00%3A00%3A00&amp;maxt=maxt&amp;Submit=Submit</property>
+ </component>
+ <component name="text4" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>http://feedproxy.google.com/TechCrunch</property>
+ </component>
+ <component name="text5" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>cnn.com</property>
+ </component>
+ <component name="text6" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>https://chart.googleapis.com/chart?cht=p3&amp;chs=250x100&amp;chd=60,40&amp;chl=Hello|World</property>
+ </component>
+ <component name="text7" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>cnn.com</property>
+ </component>
+ <component name="text8" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>(CNN)</property>
+ </component>
+ <component name="text9" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property name="property"/>
+ </component>
+ <component name="user" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+ </composite>
+ </content>
+ <link href="testhttp"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testhttp/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testhttp/app.stats
new file mode 100644
index 0000000000..f55f07105b
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testhttp/app.stats
@@ -0,0 +1 @@
+((entry (title "Test HTTP components") (id "testhttp") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testhttp/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testhttp/htdocs/app.html
new file mode 100644
index 0000000000..bf306c3c37
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testhttp/htdocs/app.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testhttp</title>
+ <id>testhttp</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h1" class="h1" style="position: absolute; top: 0px; left: 2px; ">
+ <H1>Test HTTP components</H1>
+ </SPAN>
+ <SPAN id="iframe" class="iframe" style="position: absolute; top: 234px; left: 11px; ">
+ <A href="/public/iframe.html">
+ <SPAN class="fakeframe">
+ <SPAN>frame ...</SPAN>
+ </SPAN>
+ </A>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="testhttp"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testlogic/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testlogic/app.composite
new file mode 100644
index 0000000000..d838773839
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testlogic/app.composite
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testlogic</title>
+ <id>testlogic</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="cos" promote="cos"/>
+ <service name="eval" promote="eval"/>
+ <service name="eval2" promote="eval2"/>
+ <service name="exec" promote="exec"/>
+ <service name="exec2" promote="exec2"/>
+ <service name="if" promote="if"/>
+ <service name="random1" promote="random1"/>
+ <service name="randoms1" promote="randoms1"/>
+ <service name="randoms2" promote="randoms2"/>
+ <service name="sin" promote="sin"/>
+ <component x="20" y="170" name="cos" title="cos" color="cyan1">
+ <implementation.python script="nuvem/cos_.py"/>
+ <service name="cos"/>
+ <reference target="number7" name="x"/>
+ </component>
+ <component x="150" y="10" name="eval" title="expr" color="cyan1">
+ <implementation.python script="nuvem/eval_.py"/>
+ <service name="eval"/>
+ <reference target="text3" name="py"/>
+ <reference name="ref"/>
+ </component>
+ <component x="170" y="70" name="eval2" title="expr" color="cyan1">
+ <implementation.python script="nuvem/eval_.py"/>
+ <service name="eval"/>
+ <reference target="text4" name="py"/>
+ <reference target="number3" name="ref"/>
+ </component>
+ <component x="150" y="210" name="exec" title="script" color="cyan1">
+ <implementation.python script="nuvem/exec_.py"/>
+ <service name="exec"/>
+ <reference target="get" name="py"/>
+ <reference target="number4" name="ref"/>
+ </component>
+ <component x="150" y="140" name="exec2" title="script" color="cyan1">
+ <implementation.python script="nuvem/exec_.py"/>
+ <service name="exec"/>
+ <reference target="text6" name="py"/>
+ <reference target="number5" name="ref"/>
+ </component>
+ <component name="get" title="get" color="green1">
+ <implementation.cpp path="lib/http" library="libhttpget"/>
+ <service name="get"/>
+ <property name="timeout" visible="false"/>
+ <reference target="text5" name="url"/>
+ </component>
+ <component name="greater" title="gt" color="cyan1">
+ <implementation.python script="nuvem/greater.py"/>
+ <service name="greater"/>
+ <reference target="number2" name="value1"/>
+ <reference target="number" name="value2"/>
+ </component>
+ <component x="19" y="9" name="if" title="if" color="cyan1">
+ <implementation.python script="nuvem/if_.py"/>
+ <service name="if"/>
+ <reference target="greater" name="condition"/>
+ <reference target="text" name="then"/>
+ <reference target="text2" name="else"/>
+ </component>
+ <component name="number" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>5</property>
+ </component>
+ <component x="390" y="10" name="number1" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>3</property>
+ </component>
+ <component x="480" y="90" name="number10" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>5</property>
+ </component>
+ <component x="530" y="120" name="number11" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>0</property>
+ </component>
+ <component x="520" y="140" name="number12" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>100</property>
+ </component>
+ <component name="number2" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>3</property>
+ </component>
+ <component name="number3" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>5</property>
+ </component>
+ <component name="number4" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>5</property>
+ </component>
+ <component name="number5" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>5</property>
+ </component>
+ <component name="number6" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>0.5</property>
+ </component>
+ <component name="number7" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>0.5</property>
+ </component>
+ <component x="490" y="0" name="number8" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>5</property>
+ </component>
+ <component x="480" y="40" name="number9" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>3</property>
+ </component>
+ <component x="310" y="10" name="random1" title="rand" color="cyan1">
+ <implementation.python script="nuvem/random_.py"/>
+ <service name="random"/>
+ <reference target="number1" name="range"/>
+ </component>
+ <component x="390" y="10" name="randoms1" title="rands" color="cyan1">
+ <implementation.python script="nuvem/randoms.py"/>
+ <service name="randoms"/>
+ <reference target="number8" name="n"/>
+ <reference target="number9" name="range"/>
+ </component>
+ <component x="390" y="100" name="randoms2" title="rands" color="cyan1">
+ <implementation.python script="nuvem/randoms.py"/>
+ <service name="randoms"/>
+ <reference target="number10" name="n"/>
+ <reference target="range1" name="range"/>
+ </component>
+ <component x="480" y="120" name="range1" title="range" color="yellow1">
+ <implementation.python script="nuvem/range_.py"/>
+ <service name="range"/>
+ <reference target="number11" name="first"/>
+ <reference target="number12" name="last"/>
+ </component>
+ <component x="20" y="130" name="sin" title="sin" color="cyan1">
+ <implementation.python script="nuvem/sin_.py"/>
+ <service name="sin"/>
+ <reference target="number6" name="x"/>
+ </component>
+ <component name="text" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>greater than 5</property>
+ </component>
+ <component name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>not greater than 5</property>
+ </component>
+ <component name="text3" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>3.14116 * 5 * 5</property>
+ </component>
+ <component name="text4" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>3.14116 * ref.get(r) * ref.get(r)</property>
+ </component>
+ <component name="text5" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>http://people.apache.org/~jsdelfino/tuscany/test/surface.py</property>
+ </component>
+ <component name="text6" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>val = 3.14116 * ref.get(r) * ref.get(r)</property>
+ </component>
+ </composite>
+ </content>
+ <link href="testlogic"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testlogic/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testlogic/app.stats
new file mode 100644
index 0000000000..018a42a91f
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testlogic/app.stats
@@ -0,0 +1 @@
+((entry (title "Test logic components") (id "testlogic") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testlogic/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testlogic/htdocs/app.html
new file mode 100644
index 0000000000..1e02755d80
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testlogic/htdocs/app.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testlogic</title>
+ <id>testlogic</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h2" class="h2" style="position: absolute; top: 0px; left: 2px; ">
+ <H2>Test logic components</H2>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="testlogic"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsearch/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsearch/app.composite
new file mode 100644
index 0000000000..6c2ba82131
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsearch/app.composite
@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testsearch</title>
+ <id>testsearch</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="bingsearch" promote="bingsearch"/>
+ <service name="gaddress1" promote="gaddress1"/>
+ <service name="get" promote="get"/>
+ <service name="ggeopos1" promote="ggeopos1"/>
+ <service name="googlemap" promote="googlemap"/>
+ <service name="googlemap2" promote="googlemap2"/>
+ <service name="googlesearch" promote="googlesearch"/>
+ <service name="weather" promote="weather"/>
+ <service name="weather2" promote="weather2"/>
+ <service name="yahoosearch" promote="yahoosearch"/>
+ <component x="330" y="10" name="bingsearch" title="bing" color="pink1">
+ <implementation.python script="nuvem/bsearch.py"/>
+ <service name="bingsearch"/>
+ <reference target="text10" name="query"/>
+ <reference name="s" visible="false">
+ <binding.http uri="http://www.bing.com/search"/>
+ </reference>
+ </component>
+ <component x="330" y="50" name="gaddress1" title="address" color="pink1">
+ <implementation.python script="nuvem/gaddress.py"/>
+ <service name="gaddress"/>
+ <reference target="text1" name="address"/>
+ <reference name="s" visible="false">
+ <binding.http uri="http://maps.googleapis.com/maps/api/geocode/json"/>
+ </reference>
+ </component>
+ <component x="20" y="250" name="get" title="get" color="green1">
+ <implementation.cpp path="lib/http" library="libhttpget"/>
+ <service name="get"/>
+ <property name="timeout" visible="false"/>
+ <reference target="text3" name="url"/>
+ </component>
+ <component x="490" y="10" name="ggeopos1" title="geo position" color="pink1">
+ <implementation.python script="nuvem/ggeopos.py"/>
+ <service name="ggeopos"/>
+ <reference target="number1" name="latitude"/>
+ <reference target="number4" name="longitude"/>
+ <reference name="s" visible="false">
+ <binding.http uri="http://maps.googleapis.com/maps/api/geocode/json"/>
+ </reference>
+ </component>
+ <component x="310" y="100" name="googlemap" title="google map" color="pink1">
+ <implementation.python script="nuvem/gmap.py"/>
+ <service name="googlemap"/>
+ <reference target="list2" name="locations"/>
+ <reference name="s" visible="false">
+ <binding.http uri="http://maps.google.com/maps/api/staticmap"/>
+ </reference>
+ </component>
+ <component x="15" y="96" name="googlemap2" title="google map" color="pink1">
+ <implementation.python script="nuvem/gmap.py"/>
+ <service name="googlemap"/>
+ <reference target="list3" name="locations"/>
+ <reference name="s" visible="false">
+ <binding.http uri="http://maps.google.com/maps/api/staticmap"/>
+ </reference>
+ </component>
+ <component x="20" y="10" name="googlesearch" title="google" color="pink1">
+ <implementation.python script="nuvem/gsearch.py"/>
+ <service name="googlesearch"/>
+ <reference target="text" name="query"/>
+ <reference name="s" visible="false">
+ <binding.http uri="http://ajax.googleapis.com/ajax/services/search/web"/>
+ </reference>
+ </component>
+ <component name="item" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="list" name="value"/>
+ <property>A</property>
+ </component>
+ <component name="item2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="list24" name="value"/>
+ <property>A</property>
+ </component>
+ <component name="item3" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="list25" name="value"/>
+ <property>B</property>
+ </component>
+ <component name="list" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="text4" name="item" clonable="true"/>
+ <reference target="number2" name="item" clonable="true"/>
+ <reference target="number3" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list2" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list24" title="list2" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="text7" name="name"/>
+ <reference target="text5" name="value"/>
+ </component>
+ <component name="list25" title="list2" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="text8" name="name"/>
+ <reference target="text6" name="value"/>
+ </component>
+ <component name="list3" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item2" name="item" clonable="true"/>
+ <reference target="item3" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="number" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>94070</property>
+ </component>
+ <component x="730" y="80" name="number1" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>37.507156</property>
+ </component>
+ <component name="number2" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>37.507156</property>
+ </component>
+ <component name="number3" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>-122.260526</property>
+ </component>
+ <component x="730" y="120" name="number4" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>-122.260526</property>
+ </component>
+ <component name="text" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>apache tuscany</property>
+ </component>
+ <component x="710" y="20" name="text1" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>San Carlos, CA</property>
+ </component>
+ <component name="text10" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>apache tuscany</property>
+ </component>
+ <component name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>94070</property>
+ </component>
+ <component name="text3" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>http://maps.google.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&amp;zoom=14&amp;size=512x512&amp;maptype=roadmap%20&amp;markers=color:blue|label:S|40.702147,-74.015794&amp;markers=color:green|label:G|40.711614,-74.012318%20&amp;markers=color:red|color:red|label:C|40.718217,-73.998284&amp;sensor=false</property>
+ </component>
+ <component name="text4" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>green</property>
+ </component>
+ <component name="text5" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>San Francisco, CA</property>
+ </component>
+ <component name="text6" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>San Carlos, CA</property>
+ </component>
+ <component name="text7" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>yellow</property>
+ </component>
+ <component name="text8" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>green</property>
+ </component>
+ <component name="text9" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>apache tuscany</property>
+ </component>
+ <component x="18" y="49" name="weather" title="weather" color="pink1">
+ <implementation.python script="nuvem/gweather.py"/>
+ <service name="weather"/>
+ <reference target="number" name="zip"/>
+ <reference name="ws" visible="false">
+ <binding.http uri="http://www.google.com/ig/api"/>
+ </reference>
+ </component>
+ <component x="190" y="51" name="weather2" title="weather" color="pink1">
+ <implementation.python script="nuvem/gweather.py"/>
+ <service name="weather"/>
+ <reference target="text2" name="zip"/>
+ <reference name="ws" visible="false">
+ <binding.http uri="http://www.google.com/ig/api"/>
+ </reference>
+ </component>
+ <component x="180" y="10" name="yahoosearch" title="yahoo" color="pink1">
+ <implementation.python script="nuvem/ysearch.py"/>
+ <service name="yahoosearch"/>
+ <reference target="text9" name="query"/>
+ <reference name="s" visible="false">
+ <binding.http uri="http://search.yahooapis.com/WebSearchService/V1/webSearch"/>
+ </reference>
+ </component>
+ </composite>
+ </content>
+ <link href="testsearch"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsearch/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsearch/app.stats
new file mode 100644
index 0000000000..23679affa8
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsearch/app.stats
@@ -0,0 +1 @@
+((entry (title "Test search components") (id "testsearch") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsearch/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsearch/htdocs/app.html
new file mode 100644
index 0000000000..ff52414ec8
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsearch/htdocs/app.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testsearch</title>
+ <id>testsearch</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h1" class="h1" style="position: absolute; top: 0px; left: 2px; ">
+ <H1>Test search components</H1>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="testsearch"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsms/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsms/app.composite
new file mode 100644
index 0000000000..ad36e93e7f
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsms/app.composite
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testsms</title>
+ <id>testsms</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="item" promote="property"/>
+ <service name="twsms1" promote="twsms1"/>
+ <component x="180" y="30" name="keychain1" title="keychain" color="green1">
+ <implementation.python script="nuvem/keychain.py"/>
+ <service name="keychain"/>
+ <reference target="name1" name="name"/>
+ <reference name="account" target="Accounts" visible="false"/>
+ </component>
+ <component x="190" y="70" name="keychain3" title="keychain" color="green1">
+ <implementation.python script="nuvem/keychain.py"/>
+ <service name="keychain"/>
+ <reference target="name3" name="name"/>
+ <reference name="account" target="Accounts" visible="false"/>
+ </component>
+ <component x="190" y="100" name="keychain4" title="keychain" color="green1">
+ <implementation.python script="nuvem/keychain.py"/>
+ <service name="keychain"/>
+ <reference target="name5" name="name"/>
+ <reference name="account" target="Accounts" visible="false"/>
+ </component>
+ <component x="180" y="140" name="keychain5" title="keychain" color="green1">
+ <implementation.python script="nuvem/keychain.py"/>
+ <service name="keychain"/>
+ <reference target="name4" name="name"/>
+ <reference name="account" target="Accounts" visible="false"/>
+ </component>
+ <component name="list2" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="text14" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="630" y="350" name="name1" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>twiliosid</property>
+ </component>
+ <component x="780" y="320" name="name3" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>twiliotoken</property>
+ </component>
+ <component x="250" y="140" name="name4" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>tophone</property>
+ </component>
+ <component x="520" y="270" name="name5" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>fromphone</property>
+ </component>
+ <component x="180" y="170" name="text1" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>Hello Again!</property>
+ </component>
+ <component x="550" y="450" name="text12" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>From={0}&amp;To={1}&amp;Body={2}</property>
+ </component>
+ <component x="250" y="340" name="text14" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>Hello there</property>
+ </component>
+ <component x="20" y="10" name="twsms1" title="sms" color="blue1">
+ <implementation.python script="nuvem/twsms.py"/>
+ <service name="twsms"/>
+ <reference target="keychain1" name="sid"/>
+ <reference target="keychain3" name="token"/>
+ <reference target="keychain4" name="from"/>
+ <reference target="keychain5" name="to"/>
+ <reference target="text1" name="msg"/>
+ <reference name="s" wiredByImpl="true" visible="false"/>
+ </component>
+ </composite>
+ </content>
+ <link href="testsms"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsms/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsms/app.stats
new file mode 100644
index 0000000000..f55f07105b
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsms/app.stats
@@ -0,0 +1 @@
+((entry (title "Test HTTP components") (id "testhttp") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsms/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsms/htdocs/app.html
new file mode 100644
index 0000000000..78f52015fc
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsms/htdocs/app.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testsms</title>
+ <id>testsms</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h1" class="h1" style="position: absolute; top: 0px; left: 2px; ">
+ <H1>Test SMS API</H1>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="testsms"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsocial/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsocial/app.composite
new file mode 100644
index 0000000000..69a9ec6396
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsocial/app.composite
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testsocial</title>
+ <id>testsocial</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="sendgtalk" promote="sendgtalk"/>
+ <service name="start" promote="start"/>
+ <component name="fbprofile" title="facebook profile" color="blue1">
+ <implementation.python script="nuvem/fbprofile.py"/>
+ <service name="fbprofile"/>
+ <reference target="text" name="id"/>
+ <reference name="fb" visible="false">
+ <binding.http uri="https://graph.facebook.com"/>
+ </reference>
+ </component>
+ <component name="format" title="format" color="cyan1">
+ <implementation.python script="nuvem/format_.py"/>
+ <service name="format"/>
+ <reference target="text7" name="pattern"/>
+ <reference target="list" name="values"/>
+ </component>
+ <component name="item" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="twprofile" name="value"/>
+ <property>twitprofile</property>
+ </component>
+ <component name="item2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="fbprofile" name="value"/>
+ <property>name</property>
+ </component>
+ <component name="item3" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="twtimeline" name="value"/>
+ <property>twittimeline</property>
+ </component>
+ <component name="item4" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="twfriends" name="value"/>
+ <property>twitfriends</property>
+ </component>
+ <component name="item5" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="twfollowers" name="value"/>
+ <property>twitfollowers</property>
+ </component>
+ <component name="list" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="now" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list3" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item2" name="item" clonable="true"/>
+ <reference target="item" name="item" clonable="true"/>
+ <reference target="item3" name="item" clonable="true"/>
+ <reference target="item4" name="item" clonable="true"/>
+ <reference target="item5" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="now" title="now" color="orange1">
+ <implementation.python script="nuvem/now.py"/>
+ <service name="now"/>
+ </component>
+ <component x="20" y="210" name="sendgtalk" title="gtalk" color="blue1">
+ <implementation.cpp path="lib/chat" library="libchat-sender2"/>
+ <service name="sendgtalk"/>
+ <reference target="text8" name="jid"/>
+ <reference target="text9" name="pass"/>
+ <reference target="text6" name="to"/>
+ <reference target="format" name="msg"/>
+ </component>
+ <component x="10" y="10" name="start" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference target="list3" name="content"/>
+ </component>
+ <component name="text" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>100001053301307</property>
+ </component>
+ <component name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>jsdelfino</property>
+ </component>
+ <component name="text3" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>jsdelfino</property>
+ </component>
+ <component name="text4" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>jsdelfino</property>
+ </component>
+ <component name="text5" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>jsdelfino</property>
+ </component>
+ <component name="text6" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>xmppsca.2@gmail.com</property>
+ </component>
+ <component name="text7" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>Hello, the time is {0}</property>
+ </component>
+ <component name="text8" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>xmppsca.1@gmail.com</property>
+ </component>
+ <component name="text9" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>xmpp4sca</property>
+ </component>
+ <component name="twfollowers" title="twitter followers" color="blue1">
+ <implementation.python script="nuvem/twfollowers.py"/>
+ <service name="twfollowers"/>
+ <reference target="text5" name="id"/>
+ <reference name="tw" visible="false">
+ <binding.http uri="http://api.twitter.com/1/statuses/followers.json"/>
+ </reference>
+ </component>
+ <component name="twfriends" title="twitter friends" color="blue1">
+ <implementation.python script="nuvem/twfriends.py"/>
+ <service name="twfriends"/>
+ <reference target="text4" name="id"/>
+ <reference name="tw" visible="false">
+ <binding.http uri="http://api.twitter.com/1/statuses/friends.json"/>
+ </reference>
+ </component>
+ <component name="twprofile" title="twitter profile" color="blue1">
+ <implementation.python script="nuvem/twprofile.py"/>
+ <service name="twprofile"/>
+ <reference target="text3" name="id"/>
+ <reference name="tw" visible="false">
+ <binding.http uri="http://api.twitter.com/1/users/show.json"/>
+ </reference>
+ </component>
+ <component name="twtimeline" title="twitter timeline" color="blue1">
+ <implementation.python script="nuvem/twtimeline.py"/>
+ <service name="twtimeline"/>
+ <reference target="text2" name="id"/>
+ <reference name="tw" visible="false">
+ <binding.http uri="http://api.twitter.com/1/statuses/user_timeline.json"/>
+ </reference>
+ </component>
+ </composite>
+ </content>
+ <link href="testsocial"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsocial/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsocial/app.stats
new file mode 100644
index 0000000000..e386c0528c
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsocial/app.stats
@@ -0,0 +1 @@
+((entry (title "Test social components") (id "testsocial") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsocial/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsocial/htdocs/app.html
new file mode 100644
index 0000000000..7c76d53162
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testsocial/htdocs/app.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testsocial</title>
+ <id>testsocial</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h1" class="h1" style="position: absolute; top: 0px; left: 2px; ">
+ <H1>Test social components</H1>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="testsocial"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testtext/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testtext/app.composite
new file mode 100644
index 0000000000..2ae776527b
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testtext/app.composite
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testtext</title>
+ <id>testtext</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="contains" promote="contains"/>
+ <service name="format" promote="format"/>
+ <service name="format2" promote="format2"/>
+ <service name="join" promote="join"/>
+ <service name="lowercase" promote="lowercase"/>
+ <service name="parse" promote="parse"/>
+ <service name="replace" promote="replace"/>
+ <service name="split" promote="split"/>
+ <service name="uppercase" promote="uppercase"/>
+ <component x="19" y="7" name="contains" title="contains" color="cyan1">
+ <implementation.python script="nuvem/contains.py"/>
+ <service name="contains"/>
+ <reference target="text10" name="search"/>
+ <reference target="text9" name="string"/>
+ </component>
+ <component x="150" y="110" name="format" title="format" color="cyan1">
+ <implementation.python script="nuvem/format_.py"/>
+ <service name="format"/>
+ <reference target="text13" name="pattern"/>
+ <reference target="list" name="values"/>
+ </component>
+ <component x="310" y="130" name="format2" title="format" color="cyan1">
+ <implementation.python script="nuvem/format_.py"/>
+ <service name="format"/>
+ <reference target="text14" name="pattern"/>
+ <reference target="list3" name="values"/>
+ </component>
+ <component name="item" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text17" name="value"/>
+ <property>a</property>
+ </component>
+ <component name="item2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text18" name="value"/>
+ <property>b</property>
+ </component>
+ <component x="300" y="10" name="join" title="join" color="cyan1">
+ <implementation.python script="nuvem/join.py"/>
+ <service name="join"/>
+ <reference target="text6" name="separator"/>
+ <reference target="list2" name="list"/>
+ </component>
+ <component name="list" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="text15" name="item" clonable="true"/>
+ <reference target="text16" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list2" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="text7" name="item" clonable="true"/>
+ <reference target="text8" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list3" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item" name="item" clonable="true"/>
+ <reference target="item2" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="20" y="226" name="lowercase" title="lower" color="cyan1">
+ <implementation.python script="nuvem/lowercase.py"/>
+ <service name="lowercase"/>
+ <reference target="text2" name="string"/>
+ </component>
+ <component x="150" y="230" name="parse" title="parse" color="cyan1">
+ <implementation.python script="nuvem/parse.py"/>
+ <service name="parse"/>
+ <reference target="text19" name="regexp"/>
+ <reference target="text20" name="string"/>
+ </component>
+ <component x="150" y="10" name="replace" title="replace" color="cyan1">
+ <implementation.python script="nuvem/replace.py"/>
+ <service name="replace"/>
+ <reference target="text4" name="from"/>
+ <reference target="text5" name="to"/>
+ <reference target="text3" name="string"/>
+ </component>
+ <component x="23" y="89" name="split" title="split" color="cyan1">
+ <implementation.python script="nuvem/split.py"/>
+ <service name="split"/>
+ <reference target="text11" name="separator"/>
+ <reference target="text12" name="string"/>
+ </component>
+ <component name="text" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>abc</property>
+ </component>
+ <component name="text10" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>cd</property>
+ </component>
+ <component name="text11" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>x</property>
+ </component>
+ <component name="text12" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>abcxdefxghi</property>
+ </component>
+ <component name="text13" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>The {0} brown {1}</property>
+ </component>
+ <component name="text14" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>The {a} brown {b}</property>
+ </component>
+ <component name="text15" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>quick</property>
+ </component>
+ <component name="text16" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>fox</property>
+ </component>
+ <component name="text17" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>quick</property>
+ </component>
+ <component name="text18" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>fox</property>
+ </component>
+ <component name="text19" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>city (.*) state (.*)</property>
+ </component>
+ <component name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>ABC</property>
+ </component>
+ <component name="text20" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>city San Francisco state CA</property>
+ </component>
+ <component name="text3" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>abcxdefxghi</property>
+ </component>
+ <component name="text4" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>x</property>
+ </component>
+ <component name="text5" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>y</property>
+ </component>
+ <component name="text6" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>x</property>
+ </component>
+ <component name="text7" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>abc</property>
+ </component>
+ <component name="text8" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>def</property>
+ </component>
+ <component name="text9" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>abcdef</property>
+ </component>
+ <component x="20" y="172" name="uppercase" title="upper" color="cyan1">
+ <implementation.python script="nuvem/uppercase.py"/>
+ <service name="uppercase"/>
+ <reference target="text" name="string"/>
+ </component>
+ </composite>
+ </content>
+ <link href="testtext"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testtext/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testtext/app.stats
new file mode 100644
index 0000000000..4b06f1dbba
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testtext/app.stats
@@ -0,0 +1 @@
+((entry (title "Test text processing components") (id "testtext") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testtext/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testtext/htdocs/app.html
new file mode 100644
index 0000000000..e74618df2c
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testtext/htdocs/app.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testtext</title>
+ <id>testtext</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h2" class="h2" style="position: absolute; top: 0px; left: 2px; ">
+ <H2>Test text processing components</H2>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="testtext"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testurl/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testurl/app.composite
new file mode 100644
index 0000000000..caa976386a
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testurl/app.composite
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testurl</title>
+ <id>testurl</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="app1" promote="app1"/>
+ <service name="email" promote="email"/>
+ <service name="host" promote="host"/>
+ <service name="keychain1" promote="keychain1"/>
+ <service name="keychain2" promote="keychain2"/>
+ <service name="params" promote="params"/>
+ <service name="path" promote="path"/>
+ <service name="realm" promote="realm"/>
+ <service name="url" promote="url"/>
+ <service name="user" promote="user"/>
+ <component x="260" y="100" name="app1" title="app" color="green1">
+ <implementation.python script="nuvem/app.py"/>
+ <service name="app"/>
+ <property name="app" visible="false"/>
+ </component>
+ <component x="17" y="223" name="email" title="email" color="green1">
+ <implementation.python script="nuvem/email.py"/>
+ <service name="email"/>
+ <property name="email"/>
+ </component>
+ <component x="20" y="10" name="host" title="host" color="green1">
+ <implementation.python script="nuvem/host.py"/>
+ <service name="host"/>
+ <property name="host"/>
+ </component>
+ <component name="item" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text4" name="value"/>
+ <property>parmx</property>
+ </component>
+ <component name="item2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text5" name="value"/>
+ <property>parmy</property>
+ </component>
+ <component name="item3" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="number" name="value"/>
+ <property>parmn</property>
+ </component>
+ <component x="260" y="50" name="keychain1" title="keychain" color="green1">
+ <implementation.python script="nuvem/keychain.py"/>
+ <service name="keychain"/>
+ <reference target="text1" name="name"/>
+ <reference name="account" target="Accounts" visible="false"/>
+ </component>
+ <component x="260" y="10" name="keychain2" title="keychain" color="green1">
+ <implementation.python script="nuvem/keychain.py"/>
+ <service name="keychain"/>
+ <reference target="name1" name="name"/>
+ <reference name="account" target="Accounts" visible="false"/>
+ </component>
+ <component name="list" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="text2" name="item" clonable="true"/>
+ <reference target="text3" name="item" clonable="true"/>
+ <reference target="item" name="item" clonable="true"/>
+ <reference target="item2" name="item" clonable="true"/>
+ <reference target="item3" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="400" y="10" name="name1" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>key2</property>
+ </component>
+ <component name="number" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>123</property>
+ </component>
+ <component x="16" y="91" name="params" title="?params" color="green1">
+ <implementation.python script="nuvem/params.py"/>
+ <service name="params"/>
+ <property name="params"/>
+ </component>
+ <component x="20" y="50" name="path" title="path" color="green1">
+ <implementation.python script="nuvem/path.py"/>
+ <service name="path"/>
+ <property name="path"/>
+ </component>
+ <component x="14" y="177" name="realm" title="realm" color="green1">
+ <implementation.python script="nuvem/realm.py"/>
+ <service name="realm"/>
+ <property name="realm"/>
+ </component>
+ <component name="text" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>http://example.com/</property>
+ </component>
+ <component x="400" y="10" name="text1" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>key2</property>
+ </component>
+ <component name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>test</property>
+ </component>
+ <component name="text3" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>path</property>
+ </component>
+ <component name="text4" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>xx</property>
+ </component>
+ <component name="text5" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>yy</property>
+ </component>
+ <component x="90" y="10" name="url" title="url" color="green1">
+ <implementation.python script="nuvem/url.py"/>
+ <service name="url"/>
+ <reference target="text" name="address"/>
+ <reference target="list" name="args"/>
+ </component>
+ <component x="16" y="134" name="user" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user"/>
+ </component>
+ </composite>
+ </content>
+ <link href="testurl"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testurl/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testurl/app.stats
new file mode 100644
index 0000000000..5683bd4a2a
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testurl/app.stats
@@ -0,0 +1 @@
+((entry (title "Test URL components") (id "testurl") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testurl/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testurl/htdocs/app.html
new file mode 100644
index 0000000000..4c2534a325
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testurl/htdocs/app.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testurl</title>
+ <id>testurl</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h2" class="h2" style="position: absolute; top: 0px; left: 2px; ">
+ <H2>Test url components</H2>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="testurl"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testvalues/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testvalues/app.composite
new file mode 100644
index 0000000000..74fff1f91f
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testvalues/app.composite
@@ -0,0 +1,498 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testvalues</title>
+ <id>testvalues</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="empty" promote="empty"/>
+ <service name="false" promote="false"/>
+ <service name="first" promote="first"/>
+ <service name="itemnb" promote="itemnb"/>
+ <service name="list8" promote="list8"/>
+ <service name="list9" promote="list9"/>
+ <service name="name" promote="name"/>
+ <service name="nothing" promote="nothing"/>
+ <service name="reduce2" promote="reduce2"/>
+ <service name="rest" promote="rest"/>
+ <service name="second" promote="second"/>
+ <service name="shuffle" promote="shuffle"/>
+ <service name="start" promote="start"/>
+ <service name="true" promote="true"/>
+ <service name="values" promote="values"/>
+ <service name="values2" promote="values2"/>
+ <component name="add" title="+" color="cyan1">
+ <implementation.python script="nuvem/add.py"/>
+ <service name="add">
+ <documentation>+</documentation>
+ </service>
+ <reference target="valueof2" name="value1"/>
+ <reference target="valueof3" name="value2"/>
+ </component>
+ <component x="17" y="269" name="empty" title="empty" color="yellow1">
+ <implementation.python script="nuvem/empty.py"/>
+ <service name="empty"/>
+ </component>
+ <component x="21" y="170" name="false" title="false" color="orange1">
+ <implementation.python script="nuvem/false_.py"/>
+ <service name="false"/>
+ </component>
+ <component x="110" y="10" name="first" title="first" color="yellow1">
+ <implementation.python script="nuvem/first.py"/>
+ <service name="first"/>
+ <reference target="list7" name="list"/>
+ </component>
+ <component name="item" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text3" name="value"/>
+ <property>a</property>
+ </component>
+ <component name="item10" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="list6" name="value"/>
+ <property>a</property>
+ </component>
+ <component name="item11" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text7" name="value"/>
+ <property>entry</property>
+ </component>
+ <component name="item12" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="list10" name="value"/>
+ <property>entry</property>
+ </component>
+ <component name="item13" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text9" name="value"/>
+ <property>test</property>
+ </component>
+ <component name="item14" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text10" name="value"/>
+ <property>d</property>
+ </component>
+ <component name="item15" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text11" name="value"/>
+ <property>x</property>
+ </component>
+ <component name="item2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text4" name="value"/>
+ <property>d</property>
+ </component>
+ <component name="item3" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text5" name="value"/>
+ <property>ccc</property>
+ </component>
+ <component name="item4" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text2" name="value"/>
+ <property>b</property>
+ </component>
+ <component name="item5" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text8" name="value"/>
+ <property>c</property>
+ </component>
+ <component name="item6" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="number11" name="value"/>
+ <property>c</property>
+ </component>
+ <component name="item7" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text6" name="value"/>
+ <property>b</property>
+ </component>
+ <component name="item8" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="list4" name="value"/>
+ <property>a</property>
+ </component>
+ <component name="item9" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="list5" name="value"/>
+ <property>x</property>
+ </component>
+ <component x="110" y="100" name="itemnb" title="item #" color="yellow1">
+ <implementation.python script="nuvem/itemnb.py"/>
+ <service name="itemnb"/>
+ <reference target="number8" name="index"/>
+ <reference target="map" name="list"/>
+ </component>
+ <component name="list" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="number" name="item" clonable="true"/>
+ <reference target="number7" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list10" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item13" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list2" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item" name="item" clonable="true"/>
+ <reference target="item2" name="item" clonable="true"/>
+ <reference target="item14" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list3" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item10" name="item" clonable="true"/>
+ <reference target="item9" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list4" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item7" name="item" clonable="true"/>
+ <reference target="item6" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list5" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item8" name="item" clonable="true"/>
+ <reference target="item5" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list6" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item3" name="item" clonable="true"/>
+ <reference target="item4" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list7" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="number2" name="item" clonable="true"/>
+ <reference target="number3" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="357" y="208" name="list8" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item11" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="268" y="279" name="list9" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item12" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="lookup" title="lookup" color="yellow1">
+ <implementation.python script="nuvem/lookup.py"/>
+ <service name="lookup"/>
+ <reference target="name3" name="name"/>
+ <reference target="list2" name="list"/>
+ </component>
+ <component name="map" title="map" color="yellow1">
+ <implementation.python script="nuvem/map_.py"/>
+ <service name="map"/>
+ <reference target="name2" name="item"/>
+ <reference target="multiply" name="transform"/>
+ <reference target="reverse" name="list"/>
+ </component>
+ <component name="multiply" title="*" color="cyan1">
+ <implementation.python script="nuvem/multiply.py"/>
+ <service name="multiply">
+ <documentation>*</documentation>
+ </service>
+ <reference target="valueof" name="value1"/>
+ <reference target="number6" name="value2"/>
+ </component>
+ <component x="21" y="70" name="name" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>abc</property>
+ </component>
+ <component name="name2" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>nb</property>
+ </component>
+ <component name="name3" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>d</property>
+ </component>
+ <component name="name6" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>sum</property>
+ </component>
+ <component name="name7" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>i</property>
+ </component>
+ <component name="name8" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>a.b</property>
+ </component>
+ <component x="19" y="219" name="nothing" title="nothing" color="orange1">
+ <implementation.python script="nuvem/nothing.py"/>
+ <service name="nothing"/>
+ </component>
+ <component name="number" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>12</property>
+ </component>
+ <component name="number10" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>10</property>
+ </component>
+ <component name="number11" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>123</property>
+ </component>
+ <component name="number12" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>0</property>
+ </component>
+ <component name="number13" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>10</property>
+ </component>
+ <component name="number14" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>0</property>
+ </component>
+ <component name="number2" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>123</property>
+ </component>
+ <component name="number3" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>456</property>
+ </component>
+ <component name="number4" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>0</property>
+ </component>
+ <component name="number5" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>10</property>
+ </component>
+ <component name="number6" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>2</property>
+ </component>
+ <component name="number7" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>34</property>
+ </component>
+ <component name="number8" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>3</property>
+ </component>
+ <component name="number9" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>0</property>
+ </component>
+ <component name="range" title="range" color="yellow1">
+ <implementation.python script="nuvem/range_.py"/>
+ <service name="range"/>
+ <reference target="number4" name="first"/>
+ <reference target="number5" name="last"/>
+ </component>
+ <component name="range2" title="range" color="yellow1">
+ <implementation.python script="nuvem/range_.py"/>
+ <service name="range"/>
+ <reference target="number9" name="first"/>
+ <reference target="number10" name="last"/>
+ </component>
+ <component name="range3" title="range" color="yellow1">
+ <implementation.python script="nuvem/range_.py"/>
+ <service name="range"/>
+ <reference target="number12" name="first"/>
+ <reference target="number13" name="last"/>
+ </component>
+ <component x="360" y="10" name="reduce2" title="reduce" color="yellow1">
+ <implementation.python script="nuvem/reduce_.py"/>
+ <service name="reduce"/>
+ <reference target="name6" name="item"/>
+ <reference target="name7" name="accum"/>
+ <reference target="add" name="transform"/>
+ <reference target="number14" name="init"/>
+ <reference target="range2" name="list"/>
+ </component>
+ <component x="240" y="10" name="rest" title="rest" color="yellow1">
+ <implementation.python script="nuvem/rest.py"/>
+ <service name="rest"/>
+ <reference target="list" name="list"/>
+ </component>
+ <component name="reverse" title="reverse" color="yellow1">
+ <implementation.python script="nuvem/reverse.py"/>
+ <service name="reverse"/>
+ <reference target="range" name="list"/>
+ </component>
+ <component x="830" y="170" name="second" title="second" color="yellow1">
+ <implementation.python script="nuvem/second.py"/>
+ <service name="second"/>
+ <reference target="item15" name="list"/>
+ </component>
+ <component name="select" title="select" color="yellow1">
+ <implementation.python script="nuvem/select.py"/>
+ <service name="select"/>
+ <reference target="name8" name="path"/>
+ <reference target="list3" name="list"/>
+ </component>
+ <component x="110" y="290" name="shuffle" title="shuffle" color="yellow1">
+ <implementation.python script="nuvem/shuffle_.py"/>
+ <service name="shuffle"/>
+ <reference target="range3" name="list"/>
+ </component>
+ <component x="15" y="11" name="start" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference target="text" name="content"/>
+ </component>
+ <component name="text" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>xyz</property>
+ </component>
+ <component name="text10" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>xyz</property>
+ </component>
+ <component name="text11" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>y</property>
+ </component>
+ <component name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>bbb</property>
+ </component>
+ <component name="text3" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>abc</property>
+ </component>
+ <component name="text4" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>def</property>
+ </component>
+ <component name="text5" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>ccc</property>
+ </component>
+ <component name="text6" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>BBB</property>
+ </component>
+ <component name="text7" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>hello</property>
+ </component>
+ <component name="text8" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>CCC</property>
+ </component>
+ <component name="text9" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>abc</property>
+ </component>
+ <component x="23" y="120" name="true" title="true" color="orange1">
+ <implementation.python script="nuvem/true_.py"/>
+ <service name="true"/>
+ </component>
+ <component name="valueof" title="valueof" color="orange1">
+ <implementation.python script="nuvem/valueof.py"/>
+ <service name="valueof"/>
+ <property>nb</property>
+ </component>
+ <component name="valueof2" title="valueof" color="orange1">
+ <implementation.python script="nuvem/valueof.py"/>
+ <service name="valueof"/>
+ <property>sum</property>
+ </component>
+ <component name="valueof3" title="valueof" color="orange1">
+ <implementation.python script="nuvem/valueof.py"/>
+ <service name="valueof"/>
+ <property>i</property>
+ </component>
+ <component x="830" y="10" name="values" title="values" color="yellow1">
+ <implementation.python script="nuvem/values.py"/>
+ <service name="values"/>
+ <reference target="lookup" name="list"/>
+ </component>
+ <component x="530" y="10" name="values2" title="values" color="yellow1">
+ <implementation.python script="nuvem/values.py"/>
+ <service name="values"/>
+ <reference target="select" name="list"/>
+ </component>
+ </composite>
+ </content>
+ <link href="testvalues"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testvalues/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testvalues/app.stats
new file mode 100644
index 0000000000..88f63235f8
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testvalues/app.stats
@@ -0,0 +1 @@
+((entry (title "Test values and lists") (id "testvalues") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testvalues/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testvalues/htdocs/app.html
new file mode 100644
index 0000000000..80f6f622f9
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testvalues/htdocs/app.html
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testvalues</title>
+ <id>testvalues</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h2" class="h2" style="position: absolute; top: 0px; left: 2px; ">
+ <H2>Test values and lists</H2>
+ </SPAN>
+ <SPAN id="value" class="text" style="position: absolute; top: 36px; left: 29px; ">
+ <SPAN>=value</SPAN>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="testvalues"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets/app.composite
new file mode 100644
index 0000000000..d334b152bd
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets/app.composite
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testwidgets</title>
+ <id>testwidgets</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="start" promote="start"/>
+ <component x="170" y="330" name="htattrs1" title="html attrs:" color="cyan1">
+ <implementation.python script="nuvem/htattrs.py"/>
+ <service name="htattrs"/>
+ <reference target="list2" name="value"/>
+ </component>
+ <component name="item" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text9" name="value"/>
+ <property>testpath2</property>
+ </component>
+ <component x="100" y="340" name="item1" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="htattrs1" name="value"/>
+ <property>testattrs</property>
+ </component>
+ <component name="item10" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text" name="value"/>
+ <property>testh1</property>
+ </component>
+ <component x="270" y="370" name="item11" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text10" name="value"/>
+ <property>onclick</property>
+ </component>
+ <component x="280" y="330" name="item12" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text1" name="value"/>
+ <property>value</property>
+ </component>
+ <component name="item2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="item" name="value"/>
+ <property>testpath1</property>
+ </component>
+ <component name="item3" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text6" name="value"/>
+ <property>testimg</property>
+ </component>
+ <component name="item4" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text8" name="value"/>
+ <property>testtext</property>
+ </component>
+ <component name="item5" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text4" name="value"/>
+ <property>testlink</property>
+ </component>
+ <component name="item6" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text5" name="value"/>
+ <property>testcheckbox</property>
+ </component>
+ <component name="item7" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text3" name="value"/>
+ <property>testentry</property>
+ </component>
+ <component name="item8" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text2" name="value"/>
+ <property>testbutton</property>
+ </component>
+ <component name="item9" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text7" name="value"/>
+ <property>testsection</property>
+ </component>
+ <component name="list" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item10" name="item" clonable="true"/>
+ <reference target="item9" name="item" clonable="true"/>
+ <reference target="item8" name="item" clonable="true"/>
+ <reference target="item7" name="item" clonable="true"/>
+ <reference target="item6" name="item" clonable="true"/>
+ <reference target="item5" name="item" clonable="true"/>
+ <reference target="item4" name="item" clonable="true"/>
+ <reference target="item3" name="item" clonable="true"/>
+ <reference target="item2" name="item" clonable="true"/>
+ <reference target="item1" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list2" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item12" name="item" clonable="true"/>
+ <reference target="item11" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="17" y="3" name="start" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference target="list" name="content"/>
+ </component>
+ <component name="text" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>test header 1</property>
+ </component>
+ <component x="320" y="340" name="text1" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>test html attrs</property>
+ </component>
+ <component x="370" y="370" name="text10" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>alert('hey')</property>
+ </component>
+ <component name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>test button</property>
+ </component>
+ <component name="text3" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>test entry field</property>
+ </component>
+ <component name="text4" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>http://tuscany.apache.org</property>
+ </component>
+ <component name="text5" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>test checkbox</property>
+ </component>
+ <component name="text6" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>http://tuscany.apache.org/images/TuscanyLogo.jpg</property>
+ </component>
+ <component name="text7" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>test section</property>
+ </component>
+ <component name="text8" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>test text</property>
+ </component>
+ <component name="text9" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>test path</property>
+ </component>
+ </composite>
+ </content>
+ <link href="testwidgets"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets/app.stats
new file mode 100644
index 0000000000..f9a11815a5
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets/app.stats
@@ -0,0 +1 @@
+((entry (title "Test widgets") (id "testwidgets") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets/htdocs/app.html
new file mode 100644
index 0000000000..857b6bfad3
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets/htdocs/app.html
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testwidgets</title>
+ <id>testwidgets</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="testh1" class="h1" style="position: absolute; top: 9px; left: 11px; ">
+ <H1>=testh1</H1>
+ </SPAN>
+ <SPAN id="testsection" class="section" style="position: absolute; top: 45px; width: 100%; left: 11px; ">
+ <SPAN>=testsection</SPAN>
+ </SPAN>
+ <SPAN id="testimg" class="img" style="position: absolute; top: 90px; left: 263px; ">
+ <IMG src="/public/img.png"/>
+ </SPAN>
+ <SPAN id="testbutton" class="button" style="position: absolute; top: 99px; left: 11px; ">
+ <INPUT type="button" value="=testbutton" class="graybutton"/>
+ </SPAN>
+ <SPAN id="testentry" class="entry" style="position: absolute; top: 144px; left: 11px; ">
+ <INPUT type="text" value="=testentry" size="20" autocapitalize="off"/>
+ </SPAN>
+ <SPAN id="testcheckbox" class="checkbox" style="position: absolute; top: 180px; left: 11px; ">
+ <INPUT type="checkbox" value="=testcheckbox"/>
+ <SPAN>=testcheckbox</SPAN>
+ </SPAN>
+ <SPAN id="testlink" class="link" style="position: absolute; top: 216px; left: 11px; ">
+ <A href="=testlink">
+ <SPAN>=testlink</SPAN>
+ </A>
+ </SPAN>
+ <SPAN id="testattrs" class="text" style="position: absolute; top: 216px; left: 272px; ">
+ <SPAN>=testattrs</SPAN>
+ </SPAN>
+ <SPAN id="testtext" class="text" style="position: absolute; top: 243px; left: 11px; ">
+ <SPAN>=testtext</SPAN>
+ </SPAN>
+ <SPAN id="testpath1.testpath2" class="text" style="position: absolute; top: 270px; left: 11px; ">
+ <SPAN>=testpath1.testpath2</SPAN>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="testwidgets"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets2/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets2/app.composite
new file mode 100644
index 0000000000..200da5e6fb
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets2/app.composite
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testwidgets2</title>
+ <id>testwidgets2</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="start" promote="start"/>
+ <component x="100" y="310" name="item" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text5" name="value"/>
+ <property>testframe</property>
+ </component>
+ <component x="100" y="290" name="item1" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text1" name="value"/>
+ <property>testselect</property>
+ </component>
+ <component name="item2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="list3" name="value"/>
+ <property>testlink</property>
+ </component>
+ <component name="item3" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text2" name="value"/>
+ <property>testhtml</property>
+ </component>
+ <component name="item4" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text" name="value"/>
+ <property>testlist1</property>
+ </component>
+ <component name="item5" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="list4" name="value"/>
+ <property>testlist2</property>
+ </component>
+ <component name="item6" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="number3" name="value"/>
+ <property>a</property>
+ </component>
+ <component name="item7" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="number4" name="value"/>
+ <property>b</property>
+ </component>
+ <component name="list" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item4" name="item" clonable="true"/>
+ <reference target="item5" name="item" clonable="true"/>
+ <reference target="item3" name="item" clonable="true"/>
+ <reference target="item2" name="item" clonable="true"/>
+ <reference target="item1" name="item" clonable="true"/>
+ <reference target="item" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list3" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="text3" name="item" clonable="true"/>
+ <reference target="text4" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list4" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item6" name="item" clonable="true"/>
+ <reference target="item7" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="number3" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>1</property>
+ </component>
+ <component name="number4" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>2</property>
+ </component>
+ <component x="13" y="8" name="start" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference target="list" name="content"/>
+ </component>
+ <component name="text" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>test value</property>
+ </component>
+ <component x="170" y="280" name="text1" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>test select</property>
+ </component>
+ <component name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>&lt;b&gt;test bold text&lt;/b&gt;</property>
+ </component>
+ <component name="text3" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>http://www.apache.org/</property>
+ </component>
+ <component name="text4" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>Apache</property>
+ </component>
+ <component name="text5" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>http://www.cnn.com</property>
+ </component>
+ <component x="760" y="170" name="text9" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>dynamic checkbox</property>
+ </component>
+ </composite>
+ </content>
+ <link href="testwidgets2"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets2/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets2/app.stats
new file mode 100644
index 0000000000..e375415f6f
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets2/app.stats
@@ -0,0 +1 @@
+((entry (title "Test more widgets") (id "testwidgets2") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets2/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets2/htdocs/app.html
new file mode 100644
index 0000000000..06274d38b0
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets2/htdocs/app.html
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testwidgets2</title>
+ <id>testwidgets2</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h2" class="h2" style="position: absolute; top: 0px; left: 2px; ">
+ <H2>Test widget components</H2>
+ </SPAN>
+ <SPAN id="testlist1" class="table" style="position: absolute; top: 36px; width: 100%; left: 20px; ">
+ <TABLE class="datatable" style="width: 100%; ">
+ <TBODY>
+ <TR>
+ <TD>=testlist1</TD>
+ <TD>...</TD>
+ </TR>
+ <TR>
+ <TD>...</TD>
+ <TD>...</TD>
+ </TR>
+ </TBODY>
+ </TABLE>
+ </SPAN>
+ <SPAN id="testlist2" class="table" style="position: absolute; top: 90px; width: 100%; left: 20px; ">
+ <TABLE class="datatable" style="width: 100%; ">
+ <TBODY>
+ <TR>
+ <TD>=testlist2</TD>
+ <TD>...</TD>
+ </TR>
+ <TR>
+ <TD>...</TD>
+ <TD>...</TD>
+ </TR>
+ </TBODY>
+ </TABLE>
+ </SPAN>
+ <SPAN id="b" class="table" style="position: absolute; top: 171px; width: 100%; left: 20px; ">
+ <TABLE class="datatable" style="width: 100%; ">
+ <TBODY>
+ <TR>
+ <TD>=b</TD>
+ <TD>...</TD>
+ </TR>
+ <TR>
+ <TD>...</TD>
+ <TD>...</TD>
+ </TR>
+ </TBODY>
+ </TABLE>
+ </SPAN>
+ <SPAN id="testhtml" class="text" style="position: absolute; top: 234px; left: 20px; ">
+ <SPAN>=testhtml</SPAN>
+ </SPAN>
+ <SPAN id="testselect" class="select" style="position: absolute; top: 234px; left: 155px; ">
+ <SELECT>
+ <OPTION>=testselect</OPTION>
+ </SELECT>
+ </SPAN>
+ <SPAN id="testlink" class="link" style="position: absolute; top: 270px; left: 20px; ">
+ <A href="=testlink">
+ <SPAN>=testlink</SPAN>
+ </A>
+ </SPAN>
+ <SPAN id="testframe" class="iframe" style="position: absolute; top: 306px; left: 20px; ">
+ <A href="/public/iframe.html">
+ <SPAN class="fakeframe">
+ <SPAN>frame ...</SPAN>
+ </SPAN>
+ </A>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="testwidgets2"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets3/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets3/app.composite
new file mode 100644
index 0000000000..5e5739c3ff
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets3/app.composite
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testwidgets3</title>
+ <id>testwidgets3</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="start" promote="start"/>
+ <component x="260" y="220" name="htattrs1" title="html attrs:" color="cyan1">
+ <implementation.python script="nuvem/htattrs.py"/>
+ <service name="htattrs"/>
+ <reference target="list1" name="value"/>
+ </component>
+ <component x="190" y="80" name="htbutton1" title="html button" color="cyan1">
+ <implementation.python script="nuvem/htbutton.py"/>
+ <service name="htbutton"/>
+ <reference target="text8" name="value"/>
+ </component>
+ <component x="210" y="180" name="htcheck1" title="html checkbox" color="cyan1">
+ <implementation.python script="nuvem/htcheck.py"/>
+ <service name="htcheck"/>
+ <reference target="text9" name="value"/>
+ </component>
+ <component x="180" y="10" name="htimg1" title="html img" color="cyan1">
+ <implementation.python script="nuvem/htimg.py"/>
+ <service name="htimg"/>
+ <reference target="text1" name="value"/>
+ </component>
+ <component x="190" y="230" name="htimg2" title="html img" color="cyan1">
+ <implementation.python script="nuvem/htimg.py"/>
+ <service name="htimg"/>
+ <reference target="htattrs1" name="value"/>
+ </component>
+ <component x="180" y="50" name="htlink1" title="html link" color="cyan1">
+ <implementation.python script="nuvem/htlink.py"/>
+ <service name="htlink"/>
+ <reference target="list21" name="value"/>
+ </component>
+ <component x="400" y="330" name="htstyle1" title="html style" color="cyan1">
+ <implementation.python script="nuvem/htstyle.py"/>
+ <service name="htstyle"/>
+ <reference target="list2" name="value"/>
+ </component>
+ <component x="100" y="10" name="item1" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="htimg1" name="value"/>
+ <property>testdynimg</property>
+ </component>
+ <component x="100" y="170" name="item10" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="htcheck1" name="value"/>
+ <property>testdyncheckbox</property>
+ </component>
+ <component x="110" y="230" name="item2" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="htimg2" name="value"/>
+ <property>teststyledimg</property>
+ </component>
+ <component x="400" y="300" name="item3" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text3" name="value"/>
+ <property>onclick</property>
+ </component>
+ <component x="510" y="290" name="item4" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text4" name="value"/>
+ <property>width</property>
+ </component>
+ <component x="510" y="320" name="item5" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text5" name="value"/>
+ <property>height</property>
+ </component>
+ <component x="400" y="220" name="item6" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text10" name="value"/>
+ <property>id</property>
+ </component>
+ <component x="400" y="260" name="item7" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="text2" name="value"/>
+ <property>src</property>
+ </component>
+ <component x="90" y="50" name="item8" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="htlink1" name="value"/>
+ <property>testdynlink</property>
+ </component>
+ <component x="90" y="120" name="item9" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference target="htbutton1" name="value"/>
+ <property>testdynbutton</property>
+ </component>
+ <component name="list" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item1" name="item" clonable="true"/>
+ <reference target="item8" name="item" clonable="true"/>
+ <reference target="item9" name="item" clonable="true"/>
+ <reference target="item10" name="item" clonable="true"/>
+ <reference target="item2" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list1" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item6" name="item" clonable="true"/>
+ <reference target="item7" name="item" clonable="true"/>
+ <reference target="item3" name="item" clonable="true"/>
+ <reference target="htstyle1" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component name="list2" title="list" color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="item4" name="item" clonable="true"/>
+ <reference target="item5" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="240" y="50" name="list21" title="list2" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="text6" name="name"/>
+ <reference target="text7" name="value"/>
+ </component>
+ <component x="20" y="10" name="start" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference target="list" name="content"/>
+ </component>
+ <component x="240" y="10" name="text1" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>http://tuscany.apache.org/images/TuscanyLogo.jpg</property>
+ </component>
+ <component x="430" y="220" name="text10" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>testimg</property>
+ </component>
+ <component x="440" y="260" name="text2" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>http://tuscany.apache.org/images/TuscanyLogo.jpg</property>
+ </component>
+ <component x="430" y="250" name="text3" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>alert('hey')</property>
+ </component>
+ <component x="560" y="280" name="text4" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>320px</property>
+ </component>
+ <component x="560" y="320" name="text5" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>60px</property>
+ </component>
+ <component x="280" y="50" name="text6" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>http://www.apache.org/</property>
+ </component>
+ <component x="280" y="80" name="text7" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>Apache</property>
+ </component>
+ <component x="270" y="80" name="text8" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>dynamic button</property>
+ </component>
+ <component x="300" y="180" name="text9" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>dynamic checkbox</property>
+ </component>
+ </composite>
+ </content>
+ <link href="testwidgets3"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets3/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets3/app.stats
new file mode 100644
index 0000000000..d08847ca3d
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets3/app.stats
@@ -0,0 +1 @@
+((entry (title "Test HTML generator components") (id "testwidgets3") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets3/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets3/htdocs/app.html
new file mode 100644
index 0000000000..94018e994c
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/testwidgets3/htdocs/app.html
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">testwidgets3</title>
+ <id>testwidgets3</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h2" class="h2" style="position: absolute; top: 0px; left: 2px; ">
+ <H2>Test widget components</H2>
+ </SPAN>
+ <SPAN id="testdynimg" class="text" style="position: absolute; top: 36px; left: 2px; ">
+ <SPAN>=testdynimg</SPAN>
+ </SPAN>
+ <SPAN id="testdynlink" class="text" style="position: absolute; top: 135px; left: 2px; ">
+ <SPAN>=testdynlink</SPAN>
+ </SPAN>
+ <SPAN id="testdynbutton" class="text" style="position: absolute; top: 171px; left: 2px; ">
+ <SPAN>=testdynbutton</SPAN>
+ </SPAN>
+ <SPAN id="testdyncheckbox" class="text" style="position: absolute; top: 207px; left: 2px; ">
+ <SPAN>=testdyncheckbox</SPAN>
+ </SPAN>
+ <SPAN id="teststyledimg" class="text" style="position: absolute; top: 243px; left: 2px; ">
+ <SPAN>=teststyledimg</SPAN>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="testwidgets3"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/twsms/app.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/twsms/app.composite
new file mode 100644
index 0000000000..e8b2e27584
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/twsms/app.composite
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">twsms</title>
+ <id>twsms</id>
+ <content type="application/xml">
+ <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="app" targetNamespace="http://app">
+ <service name="item" promote="property"/>
+ <service name="send" promote="send"/>
+ <component x="280" y="260" name="format2" title="format" color="cyan1">
+ <implementation.python script="nuvem/format_.py"/>
+ <service name="format"/>
+ <reference target="text12" name="pattern"/>
+ <reference target="list31" name="values"/>
+ </component>
+ <component x="100" y="10" name="format4" title="format" color="cyan1">
+ <implementation.python script="nuvem/format_.py"/>
+ <service name="format"/>
+ <reference target="text1" name="pattern"/>
+ <reference target="list6" name="values"/>
+ </component>
+ <component x="180" y="330" name="list11" title="list" color="yellow1">
+ <implementation.python script="nuvem/single.py"/>
+ <service name="list1"/>
+ <reference target="format2" name="value"/>
+ </component>
+ <component x="110" y="180" name="list21" title="list" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference target="text15" name="first"/>
+ <reference target="list11" name="second"/>
+ </component>
+ <component x="410" y="310" name="list31" title="list" color="yellow1">
+ <implementation.python script="nuvem/triple.py"/>
+ <service name="list3"/>
+ <reference target="param4" name="first"/>
+ <reference target="param5" name="second"/>
+ <reference target="param6" name="third"/>
+ </component>
+ <component name="list6" title="list.." color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference target="param1" name="item" clonable="true"/>
+ <reference target="param3" name="item" clonable="true"/>
+ <reference target="param2" name="item" clonable="true"/>
+ <reference target="text10" name="item" clonable="true"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="480" y="200" name="param1" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>sid</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component x="480" y="250" name="param2" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>sid</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component x="490" y="220" name="param3" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>token</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component x="430" y="310" name="param4" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>from</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component x="430" y="330" name="param5" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>to</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component x="440" y="370" name="param6" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>msg</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component x="80" y="10" name="post1" title="post" color="green1">
+ <implementation.cpp path="lib/http" library="libhttppost"/>
+ <service name="post"/>
+ <property name="timeout" visible="false"/>
+ <reference target="format4" name="url"/>
+ <reference target="list21" name="content"/>
+ </component>
+ <component x="10" y="10" name="send" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference target="post1" name="content"/>
+ </component>
+ <component x="430" y="80" name="text1" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>https://{0}:{1}@api.twilio.com/2010-04-01/Accounts/{2}/SMS/Messages</property>
+ </component>
+ <component x="490" y="270" name="text10" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>SMS/Messages</property>
+ </component>
+ <component x="410" y="280" name="text12" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>From={0}&amp;To={1}&amp;Body={2}</property>
+ </component>
+ <component x="180" y="300" name="text15" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>application/x-www-form-urlencoded</property>
+ </component>
+ </composite>
+ </content>
+ <link href="twsms"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/twsms/app.stats b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/twsms/app.stats
new file mode 100644
index 0000000000..4a0584174c
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/twsms/app.stats
@@ -0,0 +1 @@
+((entry (title "SMS send service") (id "twsms") (author "admin@example.com") (updated "Jan 01, 2012") (content (stats (description "Sample app")))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/twsms/htdocs/app.html b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/twsms/htdocs/app.html
new file mode 100644
index 0000000000..66addc1a1a
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/apps/twsms/htdocs/app.html
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">twsms</title>
+ <id>twsms</id>
+ <content type="application/xml">
+ <DIV id="page">
+ <SPAN id="page:h1" class="h1" style="position: absolute; top: 0px; left: 2px; ">
+ <H1>SMS Send Service</H1>
+ </SPAN>
+ <SPAN id="page:text" class="text" style="position: absolute; top: 36px; left: 2px; ">
+ <SPAN>To send an SMS use a URL like this:</SPAN>
+ </SPAN>
+ <SPAN id="page:text" class="text" style="position: absolute; top: 63px; left: 2px; ">
+ <SPAN>http://twsms..../?sid=...&amp;token=...&amp;from=...</SPAN>
+ </SPAN>
+ <SPAN id="page:text" class="text" style="position: absolute; top: 81px; left: 2px; ">
+ <SPAN>&amp;to=...&amp;msg=...</SPAN>
+ </SPAN>
+ </DIV>
+ </content>
+ <link href="twsms"/>
+</entry>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/jane@example.com/user.apps b/sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/jane@example.com/user.apps
new file mode 100644
index 0000000000..6126c4b88c
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/jane@example.com/user.apps
@@ -0,0 +1 @@
+((feed (title "Your Apps") (id "jane@example.com") (entry (title "An empty test app") (id "test"))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/jane@localhost/user.apps b/sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/jane@localhost/user.apps
new file mode 100644
index 0000000000..c62dbfb6b8
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/jane@localhost/user.apps
@@ -0,0 +1 @@
+((feed (title "Your Apps") (id "jane@localhost") (entry (title "An empty test app") (id "test"))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/john@example.com/user.apps b/sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/john@example.com/user.apps
new file mode 100644
index 0000000000..bc4d3f64fa
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/john@example.com/user.apps
@@ -0,0 +1 @@
+((feed (title "Your Apps") (id "john@example.com") (entry (title "An empty test app") (id "test"))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/john@localhost/user.apps b/sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/john@localhost/user.apps
new file mode 100644
index 0000000000..ee20c1c2c5
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/dashboards/john@localhost/user.apps
@@ -0,0 +1 @@
+((feed (title "Your Apps") (id "john@localhost") (entry (title "An empty test app") (id "test"))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/animation/palette.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/animation/palette.composite
new file mode 100644
index 0000000000..75cbf497b6
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/animation/palette.composite
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="palette" targetNamespace="http://palette">
+ <service name="frames" promote="frames"/>
+ <service name="htattrs" promote="htattrs"/>
+ <service name="htbutton" promote="htbutton"/>
+ <service name="htcheck" promote="htcheck"/>
+ <service name="htimg" promote="htimg"/>
+ <service name="htinline" promote="htinline"/>
+ <service name="htlink" promote="htlink"/>
+ <service name="htstyle" promote="htstyle"/>
+ <service name="left" promote="left"/>
+ <service name="pixels" promote="pixels"/>
+ <service name="top" promote="top"/>
+ <service name="transform" promote="transform"/>
+ <service name="transition" promote="transition"/>
+ <component x="170" y="160" name="frames" title="frames" color="white1">
+ <implementation.python script="nuvem/frames.py"/>
+ <service name="frames"/>
+ <reference name="msec"/>
+ <reference name="loop"/>
+ <reference name="content"/>
+ </component>
+ <component x="140" y="60" name="htattrs" title="attrs:" color="white1">
+ <implementation.python script="nuvem/htattrs.py"/>
+ <service name="htattrs"/>
+ <reference name="value"/>
+ </component>
+ <component x="130" y="10" name="htbutton" title="button" color="white1">
+ <implementation.python script="nuvem/htbutton.py"/>
+ <service name="htbutton"/>
+ <reference name="value"/>
+ </component>
+ <component x="250" y="10" name="htcheck" title="checkbox" color="white1">
+ <implementation.python script="nuvem/htcheck.py"/>
+ <service name="htcheck"/>
+ <reference name="value"/>
+ </component>
+ <component x="80" y="10" name="htimg" title="img" color="white1">
+ <implementation.python script="nuvem/htimg.py"/>
+ <service name="htimg"/>
+ <reference name="value"/>
+ </component>
+ <component x="80" y="60" name="htinline" title="inline" color="white1">
+ <implementation.python script="nuvem/htinline.py"/>
+ <service name="htinline"/>
+ <reference name="value"/>
+ </component>
+ <component x="200" y="10" name="htlink" title="link" color="white1">
+ <implementation.python script="nuvem/htlink.py"/>
+ <service name="htlink"/>
+ <reference name="value"/>
+ </component>
+ <component x="200" y="60" name="htstyle" title="style" color="white1">
+ <implementation.python script="nuvem/htstyle.py"/>
+ <service name="htstyle"/>
+ <reference name="value"/>
+ </component>
+ <component x="230" y="110" name="left" title="left" color="white1">
+ <implementation.python script="nuvem/left.py"/>
+ <service name="left"/>
+ <reference name="value"/>
+ </component>
+ <component x="260" y="60" name="pixels" title="pixels" color="white1">
+ <implementation.python script="nuvem/pixels.py"/>
+ <service name="pixels"/>
+ <reference name="value"/>
+ </component>
+ <component x="170" y="110" name="top" title="top" color="white1">
+ <implementation.python script="nuvem/top.py"/>
+ <service name="top"/>
+ <reference name="value"/>
+ </component>
+ <component x="80" y="160" name="transform" title="transform" color="white1">
+ <implementation.python script="nuvem/transform.py"/>
+ <service name="transform"/>
+ <reference name="x"/>
+ <reference name="y"/>
+ <reference name="d"/>
+ </component>
+ <component x="80" y="110" name="transition" title="transition" color="white1">
+ <implementation.python script="nuvem/transition.py"/>
+ <service name="transition"/>
+ <reference name="value"/>
+ </component>
+</composite>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/control/palette.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/control/palette.composite
new file mode 100644
index 0000000000..f89cae2c5d
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/control/palette.composite
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="palette" targetNamespace="http://palette">
+ <service name="animation" promote="animation"/>
+ <service name="call" promote="call"/>
+ <service name="location" promote="location"/>
+ <service name="schedule" promote="schedule"/>
+ <service name="service" promote="service"/>
+ <service name="start" promote="start"/>
+ <service name="stop" promote="stop"/>
+ <service name="timer" promote="timer"/>
+ <component x="160" y="60" name="animation" title="animation" color="green1">
+ <implementation.python script="nuvem/animation.py"/>
+ <service name="animation" visible="false">
+ <binding.http uri="animation"/>
+ </service>
+ <reference name="n"/>
+ <reference name="loop"/>
+ <reference name="content"/>
+ </component>
+ <component x="190" y="10" name="call" title="call" color="green1">
+ <implementation.python script="nuvem/call.py"/>
+ <service name="call"/>
+ <reference name="name"/>
+ <reference name="proxy" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="80" y="60" name="location" title="location" color="green1">
+ <implementation.python script="nuvem/location.py"/>
+ <service name="location" visible="false">
+ <binding.http uri="location"/>
+ </service>
+ <reference name="content"/>
+ </component>
+ <component x="240" y="60" name="schedule" title="schedule" color="green1">
+ <implementation.python script="nuvem/schedule.py"/>
+ <service name="schedule" visible="false">
+ <binding.http uri="schedule"/>
+ </service>
+ <reference name="n"/>
+ <reference name="content"/>
+ </component>
+ <component x="240" y="10" name="service" title="{compname}" color="green1">
+ <implementation.python script="nuvem/service.py"/>
+ <service name="service" visible="false"/>
+ <reference name="content"/>
+ </component>
+ <component x="80" y="10" name="start" title="start" color="green1">
+ <implementation.python script="nuvem/start.py"/>
+ <service name="start" visible="false">
+ <binding.http uri="start"/>
+ </service>
+ <reference name="content"/>
+ </component>
+ <component x="130" y="10" name="stop" title="stop" color="green1">
+ <implementation.python script="nuvem/stop.py"/>
+ <service name="stop" visible="false">
+ <binding.http uri="stop"/>
+ </service>
+ <reference name="content"/>
+ </component>
+ <component x="80" y="110" name="timer" title="timer" color="green1">
+ <implementation.python script="nuvem/timer.py"/>
+ <service name="timer" visible="false">
+ <binding.http uri="timer"/>
+ </service>
+ <reference name="n"/>
+ <reference name="content"/>
+ </component>
+</composite>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/database/palette.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/database/palette.composite
new file mode 100644
index 0000000000..926fb3fa14
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/database/palette.composite
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="palette" targetNamespace="http://palette">
+ <service name="delete" promote="delete"/>
+ <service name="filedb" promote="filedb"/>
+ <service name="get" promote="get"/>
+ <service name="nosqldb" promote="nosqldb"/>
+ <service name="post" promote="post"/>
+ <service name="put" promote="put"/>
+ <service name="sqldb" promote="sqldb"/>
+ <component x="270" y="60" name="delete" title="delete" color="pink1">
+ <implementation.python script="nuvem/delete.py"/>
+ <service name="delete"/>
+ <reference name="collection"/>
+ <reference name="id"/>
+ </component>
+ <component x="80" y="10" name="filedb" title="file" color="pink1">
+ <implementation.python script="nuvem/filedb.py"/>
+ <service name="filedb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component x="80" y="60" name="get" title="get" color="pink1">
+ <implementation.python script="nuvem/get.py"/>
+ <service name="get"/>
+ <reference name="collection"/>
+ <reference name="id"/>
+ </component>
+ <component x="140" y="10" name="nosqldb" title="index **" color="pink1">
+ <implementation.python script="nuvem/nosqldb.py"/>
+ <service name="nosqldb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component x="200" y="60" name="post" title="post" color="pink1">
+ <implementation.python script="nuvem/post.py"/>
+ <service name="post"/>
+ <reference name="collection"/>
+ <reference name="id"/>
+ <reference name="value"/>
+ </component>
+ <component x="140" y="60" name="put" title="put" color="pink1">
+ <implementation.python script="nuvem/put.py"/>
+ <service name="put"/>
+ <reference name="collection"/>
+ <reference name="id"/>
+ <reference name="value"/>
+ </component>
+ <component x="210" y="10" name="sqldb" title="sql **" color="pink1">
+ <implementation.python script="nuvem/sqldb.py"/>
+ <service name="sqldb"/>
+ <reference name="db" target="Cache" visible="false"/>
+ <property name="host" visible="false"/>
+ </component>
+</composite>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/http/palette.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/http/palette.composite
new file mode 100644
index 0000000000..f4d0c2bdf5
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/http/palette.composite
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="palette" targetNamespace="http://palette">
+ <service name="app" promote="app"/>
+ <service name="delete" promote="delete"/>
+ <service name="email" promote="email"/>
+ <service name="get" promote="get"/>
+ <service name="host" promote="host"/>
+ <service name="keychain" promote="keychain"/>
+ <service name="param" promote="param"/>
+ <service name="params" promote="params"/>
+ <service name="patch" promote="patch"/>
+ <service name="path" promote="path"/>
+ <service name="post" promote="post"/>
+ <service name="put" promote="put"/>
+ <service name="url" promote="url"/>
+ <service name="user" promote="user"/>
+ <component x="80" y="10" name="app" title="app" color="green1">
+ <implementation.python script="nuvem/app.py"/>
+ <service name="app"/>
+ <property name="app" visible="false"/>
+ </component>
+ <component x="80" y="220" name="delete" title="delete" color="green1">
+ <implementation.cpp path="lib/http" library="libhttpdelete"/>
+ <service name="delete"/>
+ <property name="timeout" visible="false"/>
+ <reference name="url"/>
+ </component>
+ <component x="140" y="110" name="email" title="email" color="green1">
+ <implementation.python script="nuvem/email.py"/>
+ <service name="email"/>
+ <property name="email" visible="false"/>
+ </component>
+ <component x="80" y="170" name="get" title="get" color="green1">
+ <implementation.cpp path="lib/http" library="libhttpget"/>
+ <service name="get"/>
+ <property name="timeout" visible="false"/>
+ <reference name="url"/>
+ </component>
+ <component x="130" y="10" name="host" title="host" color="green1">
+ <implementation.python script="nuvem/host.py"/>
+ <service name="host"/>
+ <property name="host" visible="false"/>
+ </component>
+ <component x="210" y="110" name="keychain" title="keychain" color="green1">
+ <implementation.python script="nuvem/keychain.py"/>
+ <service name="keychain"/>
+ <reference name="name"/>
+ <reference name="account" target="Accounts" visible="false"/>
+ </component>
+ <component x="150" y="60" name="param" title="?param" color="green1">
+ <implementation.python script="nuvem/param.py"/>
+ <service name="param"/>
+ <property>x</property>
+ <property name="query" visible="false"/>
+ </component>
+ <component x="80" y="60" name="params" title="?params" color="green1">
+ <implementation.python script="nuvem/params.py"/>
+ <service name="params"/>
+ <property name="query" visible="false"/>
+ </component>
+ <component x="260" y="170" name="patch" title="patch" color="green1">
+ <implementation.cpp path="lib/http" library="libhttppatch"/>
+ <service name="patch"/>
+ <property name="timeout" visible="false"/>
+ <reference name="url"/>
+ <reference name="content"/>
+ </component>
+ <component x="190" y="10" name="path" title="path" color="green1">
+ <implementation.python script="nuvem/path.py"/>
+ <service name="path"/>
+ <property name="path" visible="false"/>
+ </component>
+ <component x="200" y="170" name="post" title="post" color="green1">
+ <implementation.cpp path="lib/http" library="libhttppost"/>
+ <service name="post"/>
+ <property name="timeout" visible="false"/>
+ <reference name="url"/>
+ <reference name="content"/>
+ </component>
+ <component x="140" y="170" name="put" title="put" color="green1">
+ <implementation.cpp path="lib/http" library="libhttpput"/>
+ <service name="put"/>
+ <property name="timeout" visible="false"/>
+ <reference name="url"/>
+ <reference name="content"/>
+ </component>
+ <component x="250" y="10" name="url" title="url" color="green1">
+ <implementation.python script="nuvem/url.py"/>
+ <service name="url"/>
+ <reference name="address"/>
+ <reference name="args"/>
+ </component>
+ <component x="80" y="110" name="user" title="user" color="green1">
+ <implementation.python script="nuvem/user.py"/>
+ <service name="user"/>
+ <property name="user" visible="false"/>
+ </component>
+</composite>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/lists/palette.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/lists/palette.composite
new file mode 100644
index 0000000000..2f4051d7b9
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/lists/palette.composite
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="palette" targetNamespace="http://palette">
+ <service name="append" promote="append"/>
+ <service name="empty" promote="empty"/>
+ <service name="first" promote="first"/>
+ <service name="insert" promote="insert"/>
+ <service name="itemnb" promote="itemnb"/>
+ <service name="last" promote="last"/>
+ <service name="list" promote="list"/>
+ <service name="list1" promote="list1"/>
+ <service name="list2" promote="list2"/>
+ <service name="list3" promote="list3"/>
+ <service name="lookup" promote="lookup"/>
+ <service name="names" promote="names"/>
+ <service name="range" promote="range"/>
+ <service name="rest" promote="rest"/>
+ <service name="second" promote="second"/>
+ <service name="select" promote="select"/>
+ <service name="values" promote="values"/>
+ <component x="140" y="70" name="append" title="+" color="yellow1">
+ <implementation.python script="nuvem/append.py"/>
+ <service name="append"/>
+ <reference name="first"/>
+ <reference name="second"/>
+ </component>
+ <component x="80" y="70" name="empty" title="empty" color="yellow1">
+ <implementation.python script="nuvem/empty.py"/>
+ <service name="empty"/>
+ </component>
+ <component x="80" y="130" name="first" title="first" color="yellow1">
+ <implementation.python script="nuvem/first.py"/>
+ <service name="first"/>
+ <reference name="list"/>
+ </component>
+ <component x="200" y="70" name="insert" title="insert" color="yellow1">
+ <implementation.python script="nuvem/insert.py"/>
+ <service name="insert"/>
+ <reference name="value"/>
+ <reference name="list"/>
+ </component>
+ <component x="80" y="180" name="itemnb" title="item #" color="yellow1">
+ <implementation.python script="nuvem/itemnb.py"/>
+ <service name="itemnb"/>
+ <reference name="index"/>
+ <reference name="list"/>
+ </component>
+ <component x="200" y="130" name="last" title="last" color="yellow1">
+ <implementation.python script="nuvem/last.py"/>
+ <service name="last"/>
+ <reference name="list"/>
+ </component>
+ <component x="80" y="10" name="list" title="list.." color="yellow1">
+ <implementation.python script="nuvem/list_.py"/>
+ <service name="list"/>
+ <reference name="item" clonable="true"/>
+ </component>
+ <component x="140" y="10" name="list1" title="list" color="yellow1">
+ <implementation.python script="nuvem/single.py"/>
+ <service name="list1"/>
+ <reference name="value"/>
+ </component>
+ <component x="200" y="10" name="list2" title="list" color="yellow1">
+ <implementation.python script="nuvem/pair.py"/>
+ <service name="list2"/>
+ <reference name="first"/>
+ <reference name="second"/>
+ </component>
+ <component x="260" y="10" name="list3" title="list" color="yellow1">
+ <implementation.python script="nuvem/triple.py"/>
+ <service name="list3"/>
+ <reference name="first"/>
+ <reference name="second"/>
+ <reference name="third"/>
+ </component>
+ <component x="160" y="180" name="lookup" title="lookup" color="yellow1">
+ <implementation.python script="nuvem/lookup.py"/>
+ <service name="lookup"/>
+ <reference name="name"/>
+ <reference name="list"/>
+ </component>
+ <component x="80" y="250" name="names" title="names" color="yellow1">
+ <implementation.python script="nuvem/names.py"/>
+ <service name="names"/>
+ <reference name="list"/>
+ </component>
+ <component x="240" y="250" name="range" title="range" color="yellow1">
+ <implementation.python script="nuvem/range_.py"/>
+ <service name="range"/>
+ <reference name="first"/>
+ <reference name="last"/>
+ </component>
+ <component x="140" y="130" name="rest" title="rest" color="yellow1">
+ <implementation.python script="nuvem/rest.py"/>
+ <service name="rest"/>
+ <reference name="list"/>
+ </component>
+ <component x="250" y="130" name="second" title="second" color="yellow1">
+ <implementation.python script="nuvem/second.py"/>
+ <service name="second"/>
+ <reference name="list"/>
+ </component>
+ <component x="240" y="180" name="select" title="select" color="yellow1">
+ <implementation.python script="nuvem/select.py"/>
+ <service name="select"/>
+ <reference name="path"/>
+ <reference name="list"/>
+ </component>
+ <component x="160" y="250" name="values" title="values" color="yellow1">
+ <implementation.python script="nuvem/values.py"/>
+ <service name="values"/>
+ <reference name="list"/>
+ </component>
+</composite>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/logic/palette.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/logic/palette.composite
new file mode 100644
index 0000000000..4d84272fd5
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/logic/palette.composite
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="palette" targetNamespace="http://palette">
+ <service name="and" promote="and"/>
+ <service name="equals" promote="equals"/>
+ <service name="greater" promote="greater"/>
+ <service name="if" promote="if"/>
+ <service name="lesser" promote="lesser"/>
+ <service name="not" promote="not"/>
+ <service name="or" promote="or"/>
+ <component x="140" y="10" name="and" title="and" color="green1">
+ <implementation.python script="nuvem/and_.py"/>
+ <service name="and"/>
+ <reference name="value1"/>
+ <reference name="value2"/>
+ </component>
+ <component x="80" y="100" name="equals" title="=" color="green1">
+ <implementation.python script="nuvem/equals.py"/>
+ <service name="equals"/>
+ <reference name="value1"/>
+ <reference name="value2"/>
+ </component>
+ <component x="200" y="100" name="greater" title="gt" color="green1">
+ <implementation.python script="nuvem/greater.py"/>
+ <service name="greater"/>
+ <reference name="value1"/>
+ <reference name="value2"/>
+ </component>
+ <component x="80" y="10" name="if" title="if" color="green1">
+ <implementation.python script="nuvem/if_.py"/>
+ <service name="if"/>
+ <reference name="condition"/>
+ <reference name="then"/>
+ <reference name="else"/>
+ </component>
+ <component x="140" y="100" name="lesser" title="lt" color="green1">
+ <implementation.python script="nuvem/lesser.py"/>
+ <service name="lesser"/>
+ <reference name="value1"/>
+ <reference name="value2"/>
+ </component>
+ <component x="260" y="10" name="not" title="not" color="green1">
+ <implementation.python script="nuvem/not_.py"/>
+ <service name="not"/>
+ <reference name="value"/>
+ </component>
+ <component x="200" y="10" name="or" title="or" color="green1">
+ <implementation.python script="nuvem/or_.py"/>
+ <service name="or"/>
+ <reference name="value1"/>
+ <reference name="value2"/>
+ </component>
+</composite>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/math/palette.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/math/palette.composite
new file mode 100644
index 0000000000..7dc4e88f2f
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/math/palette.composite
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="palette" targetNamespace="http://palette">
+ <service name="add" promote="add"/>
+ <service name="ceil" promote="ceil"/>
+ <service name="cos" promote="cos"/>
+ <service name="distance" promote="distance"/>
+ <service name="divide" promote="divide"/>
+ <service name="floor" promote="floor"/>
+ <service name="max" promote="max"/>
+ <service name="min" promote="min"/>
+ <service name="mod" promote="mod"/>
+ <service name="multiply" promote="multiply"/>
+ <service name="pi" promote="pi"/>
+ <service name="random" promote="random"/>
+ <service name="randoms" promote="randoms"/>
+ <service name="round" promote="round"/>
+ <service name="sin" promote="sin"/>
+ <service name="subtract" promote="subtract"/>
+ <service name="sum" promote="sum"/>
+ <component x="80" y="10" name="add" title="+" color="cyan1">
+ <implementation.python script="nuvem/add.py"/>
+ <service name="add">
+ <documentation>+</documentation>
+ </service>
+ <reference name="value1"/>
+ <reference name="value2"/>
+ </component>
+ <component x="270" y="130" name="ceil" title="ceil" color="cyan1">
+ <implementation.python script="nuvem/ceil_.py"/>
+ <service name="ceil"/>
+ <reference name="x"/>
+ </component>
+ <component x="210" y="190" name="cos" title="cos" color="cyan1">
+ <implementation.python script="nuvem/cos_.py"/>
+ <service name="cos"/>
+ <reference name="x"/>
+ </component>
+ <component x="80" y="240" name="distance" title="distance **" color="cyan1">
+ <implementation.python script="nuvem/distance.py"/>
+ <service name="distance"/>
+ <reference name="location1"/>
+ <reference name="location2"/>
+ </component>
+ <component x="270" y="10" name="divide" title="/" color="cyan1">
+ <implementation.python script="nuvem/divide.py"/>
+ <service name="divide">
+ <documentation>/</documentation>
+ </service>
+ <reference name="value1"/>
+ <reference name="value2"/>
+ </component>
+ <component x="210" y="130" name="floor" title="floor" color="cyan1">
+ <implementation.python script="nuvem/floor_.py"/>
+ <service name="floor"/>
+ <reference name="x"/>
+ </component>
+ <component x="150" y="80" name="max" title="max" color="cyan1">
+ <implementation.python script="nuvem/max_.py"/>
+ <service name="max"/>
+ <reference name="l"/>
+ </component>
+ <component x="210" y="80" name="min" title="min" color="cyan1">
+ <implementation.python script="nuvem/min_.py"/>
+ <service name="min"/>
+ <reference name="l"/>
+ </component>
+ <component x="80" y="130" name="mod" title="mod" color="cyan1">
+ <implementation.python script="nuvem/mod.py"/>
+ <service name="mod"/>
+ <reference name="n"/>
+ <reference name="x"/>
+ </component>
+ <component x="210" y="10" name="multiply" title="*" color="cyan1">
+ <implementation.python script="nuvem/multiply.py"/>
+ <service name="multiply">
+ <documentation>*</documentation>
+ </service>
+ <reference name="value1"/>
+ <reference name="value2"/>
+ </component>
+ <component x="80" y="190" name="pi" title="pi" color="cyan1">
+ <implementation.python script="nuvem/pi_.py"/>
+ <service name="pi"/>
+ </component>
+ <component x="170" y="240" name="random" title="rand" color="cyan1">
+ <implementation.python script="nuvem/random_.py"/>
+ <service name="random"/>
+ <reference name="range"/>
+ </component>
+ <component x="230" y="240" name="randoms" title="rands" color="cyan1">
+ <implementation.python script="nuvem/randoms.py"/>
+ <service name="randoms"/>
+ <reference name="n"/>
+ <reference name="range"/>
+ </component>
+ <component x="150" y="130" name="round" title="round" color="cyan1">
+ <implementation.python script="nuvem/round_.py"/>
+ <service name="round"/>
+ <reference name="n"/>
+ <reference name="x"/>
+ </component>
+ <component x="150" y="190" name="sin" title="sin" color="cyan1">
+ <implementation.python script="nuvem/sin_.py"/>
+ <service name="sin"/>
+ <reference name="x"/>
+ </component>
+ <component x="150" y="10" name="subtract" title="-" color="cyan1">
+ <implementation.python script="nuvem/subtract.py"/>
+ <service name="subtract">
+ <documentation>-</documentation>
+ </service>
+ <reference name="value1"/>
+ <reference name="value2"/>
+ </component>
+ <component x="80" y="80" name="sum" title="sum" color="cyan1">
+ <implementation.python script="nuvem/sum_.py"/>
+ <service name="sum"/>
+ <reference name="l"/>
+ </component>
+</composite>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/python/palette.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/python/palette.composite
new file mode 100644
index 0000000000..2cc03ae365
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/python/palette.composite
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="palette" targetNamespace="http://palette">
+ <service name="eval" promote="eval"/>
+ <service name="exec" promote="exec"/>
+ <component x="80" y="10" name="eval" title="expr" color="green1">
+ <implementation.python script="nuvem/eval_.py"/>
+ <service name="eval"/>
+ <reference name="py"/>
+ <reference name="ref"/>
+ </component>
+ <component x="150" y="10" name="exec" title="script" color="green1">
+ <implementation.python script="nuvem/exec_.py"/>
+ <service name="exec"/>
+ <reference name="py"/>
+ <reference name="ref"/>
+ </component>
+</composite>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/search/palette.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/search/palette.composite
new file mode 100644
index 0000000000..db58cdcd08
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/search/palette.composite
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="palette" targetNamespace="http://palette">
+ <service name="bsearch" promote="bsearch"/>
+ <service name="gaddress" promote="gaddress"/>
+ <service name="ggeopos" promote="ggeopos"/>
+ <service name="gimages" promote="gimages"/>
+ <service name="gmap" promote="gmap"/>
+ <service name="gsearch" promote="gsearch"/>
+ <service name="gweather" promote="gweather"/>
+ <service name="traffic" promote="traffic"/>
+ <service name="ysearch" promote="ysearch"/>
+ <component x="240" y="10" name="bsearch" title="bing" color="blue1">
+ <implementation.python script="nuvem/bsearch.py"/>
+ <service name="bsearch"/>
+ <reference name="query"/>
+ <reference name="s" visible="false">
+ <binding.http uri="http://www.bing.com/search"/>
+ </reference>
+ </component>
+ <component x="140" y="60" name="gaddress" title="address" color="blue1">
+ <implementation.python script="nuvem/gaddress.py"/>
+ <service name="gaddress"/>
+ <reference name="address"/>
+ <reference name="s" visible="false">
+ <binding.http uri="http://maps.googleapis.com/maps/api/geocode/json"/>
+ </reference>
+ </component>
+ <component x="220" y="60" name="ggeopos" title="geo position" color="blue1">
+ <implementation.python script="nuvem/ggeopos.py"/>
+ <service name="ggeopos"/>
+ <reference name="latitude"/>
+ <reference name="longitude"/>
+ <reference name="s" visible="false">
+ <binding.http uri="http://maps.googleapis.com/maps/api/geocode/json"/>
+ </reference>
+ </component>
+ <component x="80" y="120" name="gimages" title="images" color="blue1">
+ <implementation.python script="nuvem/gimages.py"/>
+ <service name="gimages"/>
+ <reference name="query"/>
+ <reference name="s" visible="false">
+ <binding.http uri="https://ajax.googleapis.com/ajax/services/search/images"/>
+ </reference>
+ </component>
+ <component x="80" y="60" name="gmap" title="map" color="blue1">
+ <implementation.python script="nuvem/gmap.py"/>
+ <service name="gmap"/>
+ <reference name="locations"/>
+ <reference name="s" visible="false">
+ <binding.http uri="http://maps.google.com/maps/api/staticmap"/>
+ </reference>
+ </component>
+ <component x="80" y="10" name="gsearch" title="google" color="blue1">
+ <implementation.python script="nuvem/gsearch.py"/>
+ <service name="gsearch"/>
+ <reference name="query"/>
+ <reference name="s" visible="false">
+ <binding.http uri="http://ajax.googleapis.com/ajax/services/search/web"/>
+ </reference>
+ </component>
+ <component x="150" y="120" name="gweather" title="weather" color="blue1">
+ <implementation.python script="nuvem/gweather.py"/>
+ <service name="gweather"/>
+ <reference name="zip"/>
+ <reference name="ws" visible="false">
+ <binding.http uri="http://www.google.com/ig/api"/>
+ </reference>
+ </component>
+ <component x="230" y="120" name="traffic" title="traffic **" color="blue1">
+ <implementation.python script="nuvem/traffic.py"/>
+ <service name="traffic"/>
+ <reference name="location"/>
+ </component>
+ <component x="160" y="10" name="ysearch" title="yahoo" color="blue1">
+ <implementation.python script="nuvem/ysearch.py"/>
+ <service name="ysearch"/>
+ <reference name="query"/>
+ <reference name="s" visible="false">
+ <binding.http uri="http://search.yahooapis.com/WebSearchService/V1/webSearch"/>
+ </reference>
+ </component>
+</composite>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/social/palette.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/social/palette.composite
new file mode 100644
index 0000000000..5e02303857
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/social/palette.composite
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="palette" targetNamespace="http://palette">
+ <service name="bzprofile" promote="bzprofile"/>
+ <service name="fbalbums" promote="fbalbums"/>
+ <service name="fbfriends" promote="fbfriends"/>
+ <service name="fbgroups" promote="fbgroups"/>
+ <service name="fbprofile" promote="fbprofile"/>
+ <service name="flkalbum" promote="flkalbum"/>
+ <service name="picalbum" promote="picalbum"/>
+ <service name="twfollowers" promote="twfollowers"/>
+ <service name="twfriends" promote="twfriends"/>
+ <service name="twprofile" promote="twprofile"/>
+ <service name="twtimeline" promote="twtimeline"/>
+ <component x="80" y="260" name="bzprofile" title="buzz profile" color="blue1">
+ <implementation.python script="nuvem/bzprofile.py"/>
+ <service name="bzprofile"/>
+ <reference name="id"/>
+ <reference name="bz" visible="false">
+ <binding.http uri="https://www.googleapis.com/buzz/v1/people"/>
+ </reference>
+ </component>
+ <component x="190" y="60" name="fbalbums" title="facebook albums" color="blue1">
+ <implementation.python script="nuvem/fbalbums.py"/>
+ <service name="fbalbums"/>
+ <reference name="id"/>
+ <reference name="fb" visible="false">
+ <binding.http uri="https://graph.facebook.com"/>
+ </reference>
+ </component>
+ <component x="190" y="10" name="fbfriends" title="facebook friends" color="blue1">
+ <implementation.python script="nuvem/fbfriends.py"/>
+ <service name="fbfriends"/>
+ <reference name="id"/>
+ <reference name="fb" visible="false">
+ <binding.http uri="https://graph.facebook.com"/>
+ </reference>
+ </component>
+ <component x="80" y="60" name="fbgroups" title="facebook groups" color="blue1">
+ <implementation.python script="nuvem/fbgroups.py"/>
+ <service name="fbgroups"/>
+ <reference name="id"/>
+ <reference name="fb" visible="false">
+ <binding.http uri="https://graph.facebook.com"/>
+ </reference>
+ </component>
+ <component x="80" y="10" name="fbprofile" title="facebook profile" color="blue1">
+ <implementation.python script="nuvem/fbprofile.py"/>
+ <service name="fbprofile"/>
+ <reference name="id"/>
+ <reference name="fb" visible="false">
+ <binding.http uri="https://graph.facebook.com"/>
+ </reference>
+ </component>
+ <component x="80" y="210" name="flkalbum" title="flicker album" color="blue1">
+ <implementation.python script="nuvem/flkalbum.py"/>
+ <service name="flkalbum"/>
+ <reference name="id"/>
+ <reference name="flk" visible="false">
+ <binding.http uri="http://api.flickr.com/services/feeds/photos_public.gne"/>
+ </reference>
+ </component>
+ <component x="190" y="210" name="picalbum" title="picasa album" color="blue1">
+ <implementation.python script="nuvem/picalbum.py"/>
+ <service name="picalbum"/>
+ <reference name="id"/>
+ <reference name="pic" visible="false">
+ <binding.http uri="https://picasaweb.google.com/data/feed/api/user"/>
+ </reference>
+ </component>
+ <component x="80" y="160" name="twfollowers" title="twitter followers" color="blue1">
+ <implementation.python script="nuvem/twfollowers.py"/>
+ <service name="twfollowers"/>
+ <reference name="id"/>
+ <reference name="tw" visible="false">
+ <binding.http uri="http://api.twitter.com/1/statuses/followers.json"/>
+ </reference>
+ </component>
+ <component x="190" y="160" name="twfriends" title="twitter friends" color="blue1">
+ <implementation.python script="nuvem/twfriends.py"/>
+ <service name="twfriends"/>
+ <reference name="id"/>
+ <reference name="tw" visible="false">
+ <binding.http uri="http://api.twitter.com/1/statuses/friends.json"/>
+ </reference>
+ </component>
+ <component x="80" y="110" name="twprofile" title="twitter profile" color="blue1">
+ <implementation.python script="nuvem/twprofile.py"/>
+ <service name="twprofile"/>
+ <reference name="id"/>
+ <reference name="tw" visible="false">
+ <binding.http uri="http://api.twitter.com/1/users/show.json"/>
+ </reference>
+ </component>
+ <component x="190" y="110" name="twtimeline" title="twitter timeline" color="blue1">
+ <implementation.python script="nuvem/twtimeline.py"/>
+ <service name="twtimeline"/>
+ <reference name="id"/>
+ <reference name="tw" visible="false">
+ <binding.http uri="http://api.twitter.com/1/statuses/user_timeline.json"/>
+ </reference>
+ </component>
+</composite>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/talk/palette.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/talk/palette.composite
new file mode 100644
index 0000000000..90a48291ca
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/talk/palette.composite
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="palette" targetNamespace="http://palette">
+ <service name="sendemail" promote="sendemail"/>
+ <service name="sendgtalk" promote="sendgtalk"/>
+ <service name="twsms" promote="twsms"/>
+ <service name="voicecall" promote="voicecall"/>
+ <component x="150" y="10" name="sendemail" title="email **" color="blue1">
+ <implementation.python script="nuvem/sendemail.py"/>
+ <service name="sendemail"/>
+ <reference name="from"/>
+ <reference name="to"/>
+ <reference name="msg"/>
+ </component>
+ <component x="80" y="10" name="sendgtalk" title="gtalk" color="blue1">
+ <implementation.cpp path="lib/chat" library="libchat-sender2"/>
+ <service name="sendgtalk"/>
+ <reference name="jid"/>
+ <reference name="pass"/>
+ <reference name="to"/>
+ <reference name="msg"/>
+ </component>
+ <component x="230" y="10" name="twsms" title="sms" color="blue1">
+ <implementation.python script="nuvem/twsms.py"/>
+ <service name="twsms"/>
+ <reference name="sid"/>
+ <reference name="token"/>
+ <reference name="from"/>
+ <reference name="to"/>
+ <reference name="msg"/>
+ <reference name="s" wiredByImpl="true" visible="false"/>
+ </component>
+ <component x="80" y="120" name="voicecall" title="voice **" color="blue1">
+ <implementation.python script="nuvem/voicecall.py"/>
+ <service name="voicecall"/>
+ <reference name="to"/>
+ </component>
+</composite>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/text/palette.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/text/palette.composite
new file mode 100644
index 0000000000..6b9214f6e4
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/text/palette.composite
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="palette" targetNamespace="http://palette">
+ <service name="contains" promote="contains"/>
+ <service name="format" promote="format"/>
+ <service name="join" promote="join"/>
+ <service name="lowercase" promote="lowercase"/>
+ <service name="parse" promote="parse"/>
+ <service name="replace" promote="replace"/>
+ <service name="split" promote="split"/>
+ <service name="uppercase" promote="uppercase"/>
+ <component x="80" y="10" name="contains" title="contains" color="cyan1">
+ <implementation.python script="nuvem/contains.py"/>
+ <service name="contains"/>
+ <reference name="search"/>
+ <reference name="string"/>
+ </component>
+ <component x="80" y="90" name="format" title="format" color="cyan1">
+ <implementation.python script="nuvem/format_.py"/>
+ <service name="format"/>
+ <reference name="pattern"/>
+ <reference name="values"/>
+ </component>
+ <component x="280" y="10" name="join" title="join" color="cyan1">
+ <implementation.python script="nuvem/join.py"/>
+ <service name="join"/>
+ <reference name="separator"/>
+ <reference name="list"/>
+ </component>
+ <component x="210" y="90" name="lowercase" title="lower" color="cyan1">
+ <implementation.python script="nuvem/lowercase.py"/>
+ <service name="lowercase"/>
+ <reference name="string"/>
+ </component>
+ <component x="150" y="90" name="parse" title="parse" color="cyan1">
+ <implementation.python script="nuvem/parse.py"/>
+ <service name="parse"/>
+ <reference name="regexp"/>
+ <reference name="string"/>
+ </component>
+ <component x="150" y="10" name="replace" title="replace" color="cyan1">
+ <implementation.python script="nuvem/replace.py"/>
+ <service name="replace"/>
+ <reference name="from"/>
+ <reference name="to"/>
+ <reference name="string"/>
+ </component>
+ <component x="220" y="10" name="split" title="split" color="cyan1">
+ <implementation.python script="nuvem/split.py"/>
+ <service name="split"/>
+ <reference name="separator"/>
+ <reference name="string"/>
+ </component>
+ <component x="270" y="90" name="uppercase" title="upper" color="cyan1">
+ <implementation.python script="nuvem/uppercase.py"/>
+ <service name="uppercase"/>
+ <reference name="string"/>
+ </component>
+</composite>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/transform/palette.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/transform/palette.composite
new file mode 100644
index 0000000000..566278c44b
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/transform/palette.composite
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="palette" targetNamespace="http://palette">
+ <service name="filter" promote="filter"/>
+ <service name="map" promote="map"/>
+ <service name="reduce" promote="reduce"/>
+ <service name="reverse" promote="reverse"/>
+ <service name="shuffle" promote="shuffle"/>
+ <component x="160" y="10" name="filter" title="filter" color="yellow1">
+ <implementation.python script="nuvem/filter_.py"/>
+ <service name="filter"/>
+ <reference name="item"/>
+ <reference name="condition"/>
+ <reference name="list"/>
+ </component>
+ <component x="80" y="10" name="map" title="map" color="yellow1">
+ <implementation.python script="nuvem/map_.py"/>
+ <service name="map"/>
+ <reference name="item"/>
+ <reference name="transform"/>
+ <reference name="list"/>
+ </component>
+ <component x="80" y="90" name="reduce" title="reduce" color="yellow1">
+ <implementation.python script="nuvem/reduce_.py"/>
+ <service name="reduce"/>
+ <reference name="item"/>
+ <reference name="accum"/>
+ <reference name="transform"/>
+ <reference name="init"/>
+ <reference name="list"/>
+ </component>
+ <component x="220" y="10" name="reverse" title="reverse" color="yellow1">
+ <implementation.python script="nuvem/reverse.py"/>
+ <service name="reverse"/>
+ <reference name="list"/>
+ </component>
+ <component x="160" y="90" name="shuffle" title="shuffle" color="yellow1">
+ <implementation.python script="nuvem/shuffle_.py"/>
+ <service name="shuffle"/>
+ <reference name="list"/>
+ </component>
+</composite>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/values/palette.composite b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/values/palette.composite
new file mode 100644
index 0000000000..4cd3a9d14e
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/palettes/values/palette.composite
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="palette" targetNamespace="http://palette">
+ <service name="comment" promote="comment"/>
+ <service name="false" promote="false"/>
+ <service name="item" promote="item"/>
+ <service name="name" promote="name"/>
+ <service name="nothing" promote="nothing"/>
+ <service name="now" promote="now"/>
+ <service name="number" promote="number"/>
+ <service name="text" promote="text"/>
+ <service name="true" promote="true"/>
+ <service name="valueof" promote="valueof"/>
+ <component x="210" y="110" name="comment" title="{propval}" color="white">
+ <implementation.python script="nuvem/comment.py"/>
+ <service name="comment" visible="false"/>
+ <property>comment</property>
+ </component>
+ <component x="260" y="10" name="false" title="false" color="orange1">
+ <implementation.python script="nuvem/false_.py"/>
+ <service name="false"/>
+ </component>
+ <component x="80" y="60" name="item" title="{propval}:" color="orange1">
+ <implementation.python script="nuvem/item.py"/>
+ <service name="item"/>
+ <reference name="value"/>
+ <property>name</property>
+ </component>
+ <component x="150" y="60" name="name" title="" color="orange1">
+ <implementation.python script="nuvem/name.py"/>
+ <service name="name"/>
+ <property>name</property>
+ </component>
+ <component x="80" y="110" name="nothing" title="nothing" color="orange1">
+ <implementation.python script="nuvem/nothing.py"/>
+ <service name="nothing"/>
+ </component>
+ <component x="150" y="110" name="now" title="now" color="orange1">
+ <implementation.python script="nuvem/now.py"/>
+ <service name="now"/>
+ <reference name="format"/>
+ </component>
+ <component x="140" y="10" name="number" title="#" color="orange1">
+ <implementation.python script="nuvem/number.py"/>
+ <service name="number"/>
+ <property>123</property>
+ </component>
+ <component x="80" y="10" name="text" title=" '{propval}'" color="orange1">
+ <implementation.python script="nuvem/text.py"/>
+ <service name="text"/>
+ <property>text</property>
+ </component>
+ <component x="200" y="10" name="true" title="true" color="orange1">
+ <implementation.python script="nuvem/true_.py"/>
+ <service name="true"/>
+ </component>
+ <component x="210" y="60" name="valueof" title="valueof" color="orange1">
+ <implementation.python script="nuvem/valueof.py"/>
+ <service name="valueof"/>
+ <property>name</property>
+ </component>
+</composite>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/store/all/store.apps b/sca-cpp/branches/lightweight-sca/hosting/server/data/store/all/store.apps
new file mode 100644
index 0000000000..cb12aa05c7
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/store/all/store.apps
@@ -0,0 +1 @@
+((feed (title "App Store") (id "all") (entry (title "Check my public social data") (id "me360") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Where are my friends") (id "nearme") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Where are my friends") (id "nearme2") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Our photos of an event") (id "ourphotos") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Slice") (id "slice") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "My online store") (id "shoppingcart") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "SMS send service") (id "twsms") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "An empty test app") (id "test") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Test values and lists") (id "testvalues") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Test social components") (id "testsocial") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Test URL components") (id "testurl") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Test logic components") (id "testlogic") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Test text processing components") (id "testtext") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Test HTTP components") (id "testhttp") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Test SMS API") (id "testsms") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Test widgets") (id "testwidgets") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Test more widgets") (id "testwidgets2") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Test event components") (id "testevents") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Test search components") (id "testsearch") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Test database components") (id "testdb") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Test HTML generator components") (id "testwidgets3") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Test animation components") (id "testanimation") (author "admin@example.com") (updated "Jan 01, 2012"))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/store/featured/store.apps b/sca-cpp/branches/lightweight-sca/hosting/server/data/store/featured/store.apps
new file mode 100644
index 0000000000..adfcf5e10d
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/store/featured/store.apps
@@ -0,0 +1 @@
+((feed (title "App Store") (id "featured") (entry (title "Check my public social data") (id "me360") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Where are my friends") (id "nearme") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Where are my friends") (id "nearme2") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Our photos of an event") (id "ourphotos") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Slice") (id "slice") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "My online store") (id "shoppingcart") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "SMS send service") (id "twsms") (author "admin@example.com") (updated "Jan 01, 2012"))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/store/new/store.apps b/sca-cpp/branches/lightweight-sca/hosting/server/data/store/new/store.apps
new file mode 100644
index 0000000000..b444d7f73c
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/store/new/store.apps
@@ -0,0 +1 @@
+((feed (title "App Store") (id "new") (entry (title "Check my public social data") (id "me360") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Where are my friends") (id "nearme") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Where are my friends") (id "nearme2") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Our photos of an event") (id "ourphotos") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Slice") (id "slice") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "My online store") (id "shoppingcart") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "SMS send service") (id "twsms") (author "admin@example.com") (updated "Jan 01, 2012"))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/data/store/top/store.apps b/sca-cpp/branches/lightweight-sca/hosting/server/data/store/top/store.apps
new file mode 100644
index 0000000000..63a7b34d46
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/data/store/top/store.apps
@@ -0,0 +1 @@
+((feed (title "App Store") (id "top") (entry (title "Check my public social data") (id "me360") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Where are my friends") (id "nearme") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Where are my friends") (id "nearme2") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Our photos of an event") (id "ourphotos") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "Slice") (id "slice") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "My online store") (id "shoppingcart") (author "admin@example.com") (updated "Jan 01, 2012")) (entry (title "SMS send service") (id "twsms") (author "admin@example.com") (updated "Jan 01, 2012"))))
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/delete-auth b/sca-cpp/branches/lightweight-sca/hosting/server/delete-auth
new file mode 100755
index 0000000000..407d730c80
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/delete-auth
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+# 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.
+
+here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
+mkdir -p $1
+root=`echo "import os; print os.path.realpath('$1')" | python`
+admin=$2
+apass=$3
+user=$4
+
+httpd_prefix=`cat $here/../../modules/http/httpd.prefix`
+
+conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
+sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"`
+if [ "$sslconf" = "" ]; then
+ scheme="http"
+ addr=`echo $conf | awk '{ print $7 }'`
+ host=`$here/../../modules/http/httpd-addr ip $addr`
+ if [ "$host" = "" ]; then
+ host="localhost"
+ fi
+ port=`$here/../../modules/http/httpd-addr port $addr`
+else
+ scheme="https"
+ ssladdr=`echo $sslconf | awk '{ print $6 }'`
+ host=`$here/../../modules/http/httpd-addr ip $ssladdr`
+ if [ "$host" = "" ]; then
+ host="localhost"
+ fi
+ port=`$here/../../modules/http/httpd-addr port $ssladdr`
+fi
+
+# Compute user id
+slash=`echo $user | grep "/"`
+if [ "$slash" = "" ]; then
+ id="\"$user\""
+ upath=$user
+else
+ id=`echo $user | awk -F "/" '{ printf "\"%s\" \"%s\"", $2, $3 }'`
+ upath=`echo $user | awk -F "/" '{ printf "%s/%s", $2, $3 }'`
+fi
+
+# Delete user auth
+curl -k -L -u $admin:$apass -X DELETE -H "X-Forwarded-Server: $host" $scheme://$host:$port/c/Authenticator/$upath
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/get-auth b/sca-cpp/branches/lightweight-sca/hosting/server/get-auth
new file mode 100755
index 0000000000..2be546f91f
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/get-auth
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+# 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.
+
+here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
+mkdir -p $1
+root=`echo "import os; print os.path.realpath('$1')" | python`
+admin=$2
+apass=$3
+user=$4
+
+httpd_prefix=`cat $here/../../modules/http/httpd.prefix`
+
+conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
+
+sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"`
+if [ "$sslconf" = "" ]; then
+ scheme="http"
+ addr=`echo $conf | awk '{ print $7 }'`
+ host=`$here/../../modules/http/httpd-addr ip $addr`
+ if [ "$host" = "" ]; then
+ host="localhost"
+ fi
+ port=`$here/../../modules/http/httpd-addr port $addr`
+else
+ scheme="https"
+ ssladdr=`echo $sslconf | awk '{ print $6 }'`
+ host=`$here/../../modules/http/httpd-addr ip $ssladdr`
+ if [ "$host" = "" ]; then
+ host="localhost"
+ fi
+ port=`$here/../../modules/http/httpd-addr port $ssladdr`
+fi
+
+# Compute user id
+slash=`echo $user | grep "/"`
+if [ "$slash" = "" ]; then
+ id="\"$user\""
+ upath=$user
+else
+ id=`echo $user | awk -F "/" '{ printf "\"%s\" \"%s\"", $2, $3 }'`
+ upath=`echo $user | awk -F "/" '{ printf "%s/%s", $2, $3 }'`
+fi
+
+# Get user auth
+curl -k -L -u $admin:$apass -H "X-Forwarded-Server: $host" $scheme://$host:$port/c/Authenticator/$upath
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/account/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/account/index.html
new file mode 100644
index 0000000000..a0c2e78c31
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/account/index.html
@@ -0,0 +1,222 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<div id="bodydiv" class="body">
+
+<div class="viewform">
+
+<form id="userForm">
+<table style="width: 100%;">
+<tr><tr><td><b>Photo:</b></td></tr>
+<tr><td><img id="userimg" style="width: 50px; height: 50px; vertical-align: top;"></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>Name:</b></td></tr>
+<tr><td><input type="text" id="userTitle" class="flatentry" size="30" placeholder="Enter your name" style="width: 300px;"/></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>About Me:</b></td></tr>
+<tr><td><textarea id="userDescription" class="flatentry" cols="40" rows="3" placeholder="Enter a short description of yourself" style="width: 300px;"></textarea></td></tr>
+</table>
+
+<br/>
+<table style="width: 100%;">
+<tr>
+<th class="thl thr" style="padding-top: 4px; padding-bottom: 4px; padding-left: 2px; padding-right: 2px; ">Calendar</th>
+</tr>
+</table>
+
+<table>
+<tr><td style="padding-right: 2px;"><input type="text" id="sched1" class="flatentry" size="10" placeholder="Schedule" style="width: 80px;"/></td><td><input type="text" id="service1" class="flatentry" size="2048" placeholder="Service URL" style="width: 200px;"/></td></tr>
+<tr><td style="padding-right: 2px;"><input type="text" id="sched2" class="flatentry" size="10" placeholder="Schedule" style="width: 80px;"/></td><td><input type="text" id="service2" class="flatentry" size="2048" placeholder="Service URL" style="width: 200px;"/></td></tr>
+<tr><td style="padding-right: 2px;"><input type="text" id="sched3" class="flatentry" size="10" placeholder="Schedule" style="width: 80px;"/></td><td><input type="text" id="service3" class="flatentry" size="2048" placeholder="Service URL" style="width: 200px;"/></td></tr>
+<tr><td style="padding-right: 2px;"><input type="text" id="sched4" class="flatentry" size="10" placeholder="Schedule" style="width: 80px;"/></td><td><input type="text" id="service4" class="flatentry" size="2048" placeholder="Service URL" style="width: 200px;"/></td></tr>
+<tr><td style="padding-right: 2px;"><input type="text" id="sched5" class="flatentry" size="10" placeholder="Schedule" style="width: 80px;"/></td><td><input type="text" id="service5" class="flatentry" size="2048" placeholder="Service URL" style="width: 200px;"/></td></tr>
+</table>
+<br/>
+
+<table style="width: 100%;">
+<tr>
+<th class="thl thr" style="padding-top: 4px; padding-bottom: 4px; padding-left: 2px; padding-right: 2px; ">Key chain</th>
+</tr>
+</table>
+
+<table>
+<tr><td style="padding-right: 2px;"><input type="text" id="name1" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value1" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
+<tr><td style="padding-right: 2px;"><input type="text" id="name2" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value2" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
+<tr><td style="padding-right: 2px;"><input type="text" id="name3" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value3" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
+<tr><td style="padding-right: 2px;"><input type="text" id="name4" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value4" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
+<tr><td style="padding-right: 2px;"><input type="text" id="name5" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value5" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
+<tr><td style="padding-right: 2px;"><input type="text" id="name6" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value6" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
+<tr><td style="padding-right: 2px;"><input type="text" id="name7" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value7" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
+<tr><td style="padding-right: 2px;"><input type="text" id="name8" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value8" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
+<tr><td style="padding-right: 2px;"><input type="text" id="name9" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value9" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
+<tr><td style="padding-right: 2px;"><input type="text" id="name10" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value10" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
+</table>
+</form>
+
+</div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Init service references.
+ */
+var editorComp = sca.component("Editor");
+var user= sca.defun(sca.reference(editorComp, "user"));
+var accounts = sca.reference(editorComp, "accounts");
+
+/**
+ * Set page titles.
+ */
+document.title = config.windowtitle() + ' - Account';
+$('viewhead').innerHTML = '<span class="cmenu">' + username + '</span>';
+
+/**
+ * Set images.
+ */
+$('userimg').src = ui.b64img(appcache.get('/public/user.b64'));
+
+/**
+ * The current account entry and corresponding saved XML content.
+ */
+var accountentry;
+var savedaccountentryxml = '';
+
+/**
+ * Get and display the user's account.
+ */
+function getaccount() {
+ showStatus('Loading');
+
+ return accounts.get('', function(doc) {
+
+ // Stop now if we didn't get an account
+ if (doc == null) {
+ showError('Account info not available');
+ return false;
+ }
+ showOnlineStatus();
+
+ accountentry = car(elementsToValues(atom.readATOMEntry(mklist(doc))));
+ $('userTitle').value = cadr(assoc("'title", cdr(accountentry)));
+
+ var content = cadr(assoc("'content", cdr(accountentry)));
+ var acct = isNil(content)? mklist() : cdr(content);
+
+ var desc = assoc("'description", acct);
+ $('userDescription').innerHTML = isNil(desc) || isNil(cdr(desc))? '' : cadr(desc);
+
+ var cal = assoc("'calendar", acct);
+ reduce(function(i, evt) {
+ var sched = assoc("'@schedule", evt);
+ var svc = assoc("'@service", evt);
+ $('sched' + i).value = isNil(sched)? '' : cadr(sched);
+ $('service' + i).value = isNil(svc)? '' : cadr(svc);
+ return i + 1;
+ }, 1, isNil(cal)? mklist() : cadr(cadr(cal)));
+
+ var keys = assoc("'keys", acct);
+ reduce(function(i, key) {
+ var kn = assoc("'@name", key);
+ var kv = assoc("'@value", key);
+ $('name' + i).value = isNil(kn)? '' : cadr(kn);
+ $('value' + i).value = isNil(kv)? '' : cadr(kv);
+ return i + 1;
+ }, 1, isNil(keys)? mklist() : cadr(cadr(keys)));
+
+ savedaccountentryxml = car(atom.writeATOMEntry(valuesToElements(mklist(accountentry))));
+ return true;
+ });
+}
+
+/**
+ * Save the user's account.
+ */
+function save(entryxml) {
+ if (isNil(username))
+ return false;
+ showStatus('Saving');
+ savedaccountentryxml = entryxml;
+ accounts.put('', savedaccountentryxml, function(e) {
+ if (e) {
+ showStatus('Local copy');
+ return false;
+ }
+
+ showStatus('Saved');
+ return true;
+ });
+ return true;
+}
+
+/**
+ * Handle a change event
+ */
+function onaccountchange() {
+ var title = $('userTitle').value;
+ var desc = $('userDescription').value;
+ var cal = map(function(i) {
+ var sched = $('sched' + i).value;
+ var svc = $('service' + i).value;
+ return mklist("'event", mklist("'@schedule", sched), mklist("'@service", svc));
+ }, range(1, 6));
+ var keys = map(function(i) {
+ var kn = $('name' + i).value;
+ var kv = $('value' + i).value;
+ return mklist("'key", mklist("'@name", kn), mklist("'@value", kv));
+ }, range(1, 11));
+
+ var accountentry = mklist("'entry", mklist("'title", title != ''? title : username), mklist("'id", username),
+ mklist("'content", mklist("'account", mklist("'description", desc), cons("'keys", keys), cons("'calendar", cal))));
+ var entryxml = car(atom.writeATOMEntry(valuesToElements(mklist(accountentry))));
+ if (savedaccountentryxml == entryxml)
+ return false;
+
+ showStatus('Modified');
+ return save(entryxml);
+}
+
+$('userTitle').onchange = onaccountchange;
+$('userDescription').onchange = onaccountchange;
+map(function(i) {
+ $('sched' + i).onchange = onaccountchange;
+ $('service' + i).onchange = onaccountchange;
+ return true;
+}, range(1, 6));
+map(function(i) {
+ $('name' + i).onchange = onaccountchange;
+ $('value' + i).onchange = onaccountchange;
+ return true;
+}, range(1, 11));
+
+/**
+ * Handle a form submit event.
+ */
+$('userForm').onsubmit = function() {
+ onaccountchange();
+ return false;
+};
+
+/**
+ * Get the user's account.
+ */
+getaccount();
+
+})();
+</script>
+
+</div>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/app/cache-template.cmf b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/app/cache-template.cmf
new file mode 100644
index 0000000000..5881cf83dd
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/app/cache-template.cmf
@@ -0,0 +1,17 @@
+CACHE MANIFEST
+
+# Version SHA1
+
+# App resources
+/favicon.ico
+/public/iframe-min.html
+/public/img.png
+/public/notauth/
+/public/notfound/
+/public/notyet/
+/public/oops/
+/public/touchicon.png
+
+NETWORK:
+*
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/app/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/app/index.html
new file mode 100644
index 0000000000..cddf4fb477
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/app/index.html
@@ -0,0 +1,1012 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<html manifest="cache-manifest.cmf">
+<head>
+<title></title>
+<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"/>
+<meta name="apple-mobile-web-app-capable" content="yes"/>
+<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
+<link rel="apple-touch-icon" href="/public/touchicon.png"/>
+<base href="/"/>
+<script type="text/javascript">
+(function() {
+
+window.appcache = {};
+
+/**
+ * Get and cache a resource.
+ */
+appcache.get = function(uri) {
+ var h = uri.indexOf('#');
+ var u = h == -1? uri : uri.substring(0, h);
+
+ // Get resource from local storage first
+ var ls = window.lstorage || localStorage;
+ var item = null;
+ try { item = ls.getItem(u); } catch(e) {}
+ if (item != null && item != '')
+ return item;
+
+ // Get resource from network
+ var http = new XMLHttpRequest();
+ http.open("GET", u, false);
+ http.setRequestHeader("Accept", "*/*");
+ http.send(null);
+ if (http.status == 200) {
+ if (http.getResponseHeader("X-Login") != null) {
+ if (window.debug) debug('http error', u, 'X-Login');
+ // Redirect to login page if not signed in
+ document.location = '/login/';
+ return null;
+ } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
+ if (window.debug) debug('http error', u, 'No-Content');
+ return null;
+ }
+ try { ls.setItem(u, http.responseText); } catch(e) {}
+ return http.responseText;
+ }
+ if (window.debug) debug('http error', u, http.status, http.statusText);
+ // Redirect to login page if not signed in
+ if (http.status == 403)
+ document.location = '/login/';
+ return null;
+};
+
+})();
+
+/**
+ * Load Javascript and CSS.
+ */
+(function() {
+
+var bootjs = document.createElement('script');
+bootjs.type = 'text/javascript';
+bootjs.text = appcache.get('/all-min.js');
+document.head.appendChild(bootjs);
+document.head.appendChild(ui.declareCSS(appcache.get('/ui-min.css')));
+
+})();
+
+/**
+ * Redirect to login page if not signed in.
+ */
+(function() {
+
+if (document.location.protocol == 'https:' && !hasauthcookie())
+ document.location = '/login/';
+
+})();
+
+</script>
+</head>
+<body class="delayed">
+<div id="mainbodydiv" class="mainbodydiv">
+
+<div id="headdiv" class="hsection">
+<script type="text/javascript">
+(function() {
+
+$('headdiv').appendChild(ui.declareScript(appcache.get('/config-min.js')));
+
+})();
+</script>
+</div>
+
+<div id="content">
+</div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Get the app name
+ */
+var appname = location.pathname.split('/')[1];
+
+/**
+ * Set page title.
+ */
+document.title = appname;
+
+/**
+ * The main page div.
+ */
+var contentdiv = $('content');
+
+/**
+ * The main app composite and page definitions.
+ */
+var appcomposite = null;
+var apppage = null;
+
+/**
+ * Initialize the app HTTP clients.
+ */
+var appComp = sca.component('App');
+var pagecomp = sca.reference(appComp, 'pages');
+var composcomp = sca.reference(appComp, 'composites');
+var startcomp = sca.httpclient('start', '/' + appname + '/start');
+var stopcomp = sca.httpclient('stop', '/' + appname + '/stop');
+var timercomp = sca.httpclient('timer', '/' + appname + '/timer');
+var animationcomp = sca.httpclient('animation', '/' + appname + '/animation');
+var locationcomp = sca.httpclient('location', '/' + appname + '/location');
+
+/**
+ * Pre-fetch app resources.
+ */
+var appresources = [
+ ['/all-min.js'],
+ ['/ui-min.css'],
+ ['/config-min.js'],
+ ['/public/config-min.js']
+];
+
+/**
+ * Handle application cache events.
+ */
+applicationCache.addEventListener('checking', function(e) {
+ //debug('appcache checking', e);
+}, false);
+applicationCache.addEventListener('error', function(e) {
+ //debug('appcache error', e);
+}, false);
+applicationCache.addEventListener('noupdate', function(e) {
+ //debug('appcache noupdate', e);
+}, false);
+applicationCache.addEventListener('downloading', function(e) {
+ //debug('appcache downloading', e);
+}, false);
+applicationCache.addEventListener('progress', function(e) {
+ //debug('appcache progress', e);
+}, false);
+applicationCache.addEventListener('updateready', function(e) {
+ //debug('appcache updateready', e);
+ try {
+ applicationCache.swapCache();
+ } catch(e) {}
+ //debug('appcache swapped', e);
+}, false);
+applicationCache.addEventListener('cached', function(e) {
+ //debug('appcache cached', e);
+ map(function(res) {
+ appcache.get(res[0]);
+ }, appresources);
+}, false);
+
+/**
+ * Handle network offline/online events.
+ */
+window.addEventListener('offline', function(e) {
+ //debug('going offline');
+}, false);
+window.addEventListener('online', function(e) {
+ //debug('going online');
+}, false);
+
+//debug(navigator.onLine? 'online' : 'offline');
+
+/**
+ * Find a named value in a tree of elements. The value name is given
+ * as a list of ids.
+ */
+function namedvalue(l, id) {
+ if (isNil(l))
+ return null;
+ var e = car(l);
+
+ // Element matches id segment
+ if (car(id) == elementName(e)) {
+
+ // Found element matching the whole id path
+ if (isNil(cdr(id)))
+ return e;
+
+ // Search for next id segments in child elements
+ if (!elementHasValue(e)) {
+ var v = namedvalue(elementChildren(e), cdr(id));
+ if (v != null)
+ return v;
+ }
+ }
+
+ // Search for id through the whole element tree
+ if (!elementHasValue(e)) {
+ var v = namedvalue(elementChildren(e), id);
+ if (v != null)
+ return v;
+ }
+ return namedvalue(cdr(l), id);
+}
+
+/**
+ * Return the value of an input element.
+ */
+function inputvalue(e) {
+ if (e.className == 'entry' || e.className == 'password') {
+ return car(childElements(e)).value;
+ }
+ if (e.className == 'button') {
+ return car(childElements(e)).value;
+ }
+ if (e.className == 'checkbox') {
+ if (!car(childElements(e)).checked)
+ return null;
+ return car(childElements(e)).value;
+ }
+ if (e.className == 'select') {
+ return car(childElements(car(childElements(e)))).value;
+ }
+ return null;
+};
+
+/**
+ * Set a value into a widget.
+ */
+function setwidgetvalue(e, dv) {
+ var htattrs = namedElementChild("'htattrs", dv);
+
+ function attr(ce) {
+ return mklist(elementName(ce) == "'htstyle"? 'style' : elementName(ce).substring(1), elementHasValue(ce)? elementValue(ce) : elementChildren(ce));
+ }
+
+ function vattr(dv) {
+ return (elementHasValue(dv) && !isNil(elementValue(dv)))? mklist(mklist('value', isNil(elementValue(dv))? '' : elementValue(dv))) : mklist();
+ }
+
+ function sattr(dv) {
+ var s = namedElementChild("'htstyle", dv);
+ return isNil(s)? mklist() : mklist(mklist('style', elementHasValue(s)? elementValue(s) : elementChildren(s)))
+ }
+
+ var attrs = append(append(isNil(htattrs)? mklist() : map(attr, elementChildren(htattrs)), vattr(dv)), sattr(dv));
+
+ // Set the attributes of the widget
+ function setattrs(vsetter, attrs, ce) {
+ return map(function(a) {
+ if (car(a) == 'value')
+ return vsetter(a, ce);
+
+ if (car(a) == 'style') {
+ // Split a style property between a style attribute
+ // and a stylesheet definition in the document's head
+
+ function prop(s) {
+ if (s == ';')
+ return '';
+ var i = s.indexOf('<style>');
+ if (i == -1)
+ return s;
+ var j = s.indexOf('</style>');
+ return s.substring(0, i) + prop(s.substring(j + 8));
+ }
+
+ function sheet(s) {
+ var i = s.indexOf('<style>');
+ if (i == -1)
+ return '';
+ var j = s.indexOf('</style>');
+ return s.substring(i + 7, j) + sheet(s.substring(j + 8));
+ }
+
+ var st = cadr(a).replace(new RegExp('{id}', 'g'), e.id);
+ var p = prop(st);
+ var s = sheet(st);
+
+ // Define the stylesheet
+ if (s != '') {
+ var esheet = ui.elementByID(contentdiv, 'style_' + e.id);
+ if (isNil(esheet)) {
+ var nesheet = document.createElement('style');
+ nesheet.id = 'style_' + e.id;
+ nesheet.type = 'text/css';
+ document.head.appendChild(nesheet);
+ nesheet.innerHTML = s;
+ } else {
+ esheet.innerHTML = s;
+ }
+ }
+
+ var aname = ce.style.webkitAnimationName;
+
+ // Set the style attribute
+ ce.setAttribute('style', p);
+
+ // Restart current animation if necessary
+ if (!isNil(aname) && ce.style.webkitAnimationName == aname) {
+ ce.style.webkitAnimationName = '';
+ setTimeout(function() {
+ ce.style.webkitAnimationName = aname;
+ }, 0);
+ }
+ return a;
+ }
+
+ ce.setAttribute(car(a), cadr(a));
+ return a;
+ }, attrs);
+ }
+
+ if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section') {
+ var ce = car(childElements(e));
+ return setattrs(function(a, ce) { ce.innerHTML = cadr(a); }, attrs, ce);
+ }
+ if (e.className == 'entry' || e.className == 'password') {
+ var ce = car(childElements(e));
+ return setattrs(function(a, ce) { ce.defaultValue = cadr(a); }, attrs, ce);
+ }
+ if (e.className == 'button') {
+ var ce = car(childElements(e));
+ return setattrs(function(a, ce) { ce.value = cadr(a); }, attrs, ce);
+ }
+ if (e.className == 'checkbox') {
+ var ce = car(childElements(e));
+
+ function setcheckvalue(a, ce) {
+ var v = cadr(a);
+ ce.value = v;
+ map(function(n) { if (n.nodeName == "SPAN") n.innerHTML = v; return n; }, nodeList(e.childNodes));
+ return true;
+ }
+
+ return setattrs(setcheckvalue, attrs, ce);
+ }
+ if (e.className == 'select') {
+ var ce = car(childElements(car(childElements(e))));
+
+ function setselectvalue(a, ce) {
+ var v = cadr(a);
+ ce.value = v;
+ ce.innerHTML = v;
+ return true;
+ }
+
+ return setattrs(setselectvalue, attrs, ce);
+ }
+ if (e.className == 'list') {
+ var dl = ui.datalist(isNil(dv)? mklist() : mklist(dv));
+ e.innerHTML = dl;
+ return dl;
+ }
+ if (e.className == 'table') {
+ var dl = ui.datatable(isNil(dv)? mklist() : mklist(dv));
+ e.innerHTML = dl;
+ return dl;
+ }
+ if (e.className == 'link') {
+ var ce = car(childElements(e));
+
+ function setlinkvalue(a, ce) {
+ var v = cadr(a);
+ if (isList(v)) {
+ ce.href = car(v);
+ ce.innerHTML = cadr(v);
+ return true;
+ }
+ ce.href = v;
+ ce.innerHTML = v;
+ return true;
+ }
+
+ return setattrs(setlinkvalue, attrs, ce);
+ }
+ if (e.className == 'img') {
+ var ce = car(childElements(e));
+ return setattrs(function(a, ce) { ce.setAttribute('src', cadr(a)); }, attrs, ce);
+ }
+ if (e.className == 'iframe') {
+ var ce = car(childElements(e));
+ return setattrs(function(a, ce) { ce.setAttribute('src', cadr(a)); }, attrs, ce);
+ }
+ return '';
+};
+
+/**
+ * Update the app page with the given app data.
+ */
+function updatepage(l) {
+ if (isNil(l))
+ return true;
+
+ // Update the widgets values
+ function updatewidget(e) {
+ var dv = namedvalue(l, map(function(t) { return "'" + t; }, e.id.split('.')));
+ if (dv == null || isNil(dv))
+ return e;
+ setwidgetvalue(e, dv);
+ return e;
+ }
+
+ map(updatewidget, filter(function(e) { return !isNil(e.id) && e.id.substring(0, 5) != 'page:'; }, nodeList(ui.elementByID(contentdiv, 'page').childNodes)));
+ return true;
+}
+
+/**
+ * Convert a document to application data.
+ */
+function docdata(doc) {
+ if (isNil(doc))
+ return null;
+
+ if (json.isJSON(mklist(doc)))
+ return json.readJSON(mklist(doc));
+
+ if (atom.isATOMEntry(mklist(doc)))
+ return atom.readATOMEntry(mklist(doc));
+
+ if (atom.isATOMFeed(mklist(doc)))
+ return atom.readATOMFeed(mklist(doc));
+
+ return doc;
+}
+
+/**
+ * Bind a handler to a widget.
+ */
+function bindwidgethandler(e, appname) {
+ if (e.className == 'button') {
+ var b = car(childElements(e));
+ b.name = e.id;
+ b.onclick = function() { return buttonClickHandler(b.value, appname); };
+ return e;
+ }
+ if (e.className == 'link') {
+ var l = car(childElements(e));
+ var hr = l.href;
+ if (hr.substring(0, 5) == 'link:' && hr.indexOf('://') == -1) {
+ var f = function(e) {
+ e.preventDefault();
+ return buttonClickHandler(hr.substring(5), appname);
+ };
+ l.ontouchstart = l.onclick = f;
+ l.href = 'javascript:void()';
+ }
+ return e;
+ }
+ if (e.className == 'entry' || e.className == 'password' || e.className == 'checkbox') {
+ car(childElements(e)).name = e.id;
+ return e;
+ }
+ if (e.className == 'select') {
+ var ce = car(childElements(car(childElements(e))));
+ ce.name = e.id;
+ return e;
+ }
+ return e;
+}
+
+/**
+ * Initial fixup of a widget.
+ */
+function fixupwidget(e) {
+ if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section') {
+ if (e.className == 'section')
+ e.style.width = '100%';
+ var ce = car(childElements(e));
+ if (ce.innerHTML == '=' + e.id)
+ ce.innerHTML = '';
+ return e;
+ }
+ if (e.className == 'entry' || e.className == 'password') {
+ var ce = car(childElements(e));
+ if (ce.defaultValue == '=' + e.id)
+ ce.defaultValue = '';
+ return e;
+ }
+ if (e.className == 'button') {
+ var ce = car(childElements(e));
+ if (ce.value == '=' + e.id)
+ ce.value = '';
+ return e;
+ }
+ if (e.className == 'checkbox') {
+ var ce = car(childElements(e));
+ if (ce.value == '=' + e.id) {
+ ce.value = '';
+ map(function(n) { if (n.nodeName == "SPAN") n.innerHTML = ''; return n; }, nodeList(e.childNodes));
+ }
+ return e;
+ }
+ if (e.className == 'select') {
+ var ce = car(childElements(car(childElements(e))));
+ if (ce.value == '=' + e.id) {
+ ce.value = '';
+ ce.innerHTML = '';
+ }
+ return e;
+ }
+ if (e.className == 'list') {
+ car(childElements(e)).innerHTML = '';
+ e.style.width = '100%';
+ car(childElements(e)).style.width = '100%';
+ return e;
+ }
+ if (e.className == 'table') {
+ car(childElements(e)).innerHTML = '';
+ e.style.width = '100%';
+ car(childElements(e)).style.width = '100%';
+ return e;
+ }
+ if (e.className == 'link') {
+ var ce = car(childElements(e));
+ if (ce.innerHTML == '=' + e.id)
+ ce.innerHTML = '';
+ return e;
+ }
+ if (e.className == 'img') {
+ var ce = car(childElements(e));
+ return e;
+ }
+ if (e.className == 'iframe') {
+ var ce = car(childElements(e));
+ e.innerHTML = '<iframe src="' + ce.href + '" frameborder="no" scrolling="no"></iframe>';
+ return e;
+ }
+ return e;
+}
+
+/**
+ * Set initial value of a widget.
+ */
+function initwidget(e) {
+ if (!isNil(e.id) && e.id.substring(0, 5) != 'page:')
+ setwidgetvalue(e, mklist());
+ return e;
+}
+
+/**
+ * Return the component bound to a uri.
+ */
+function isbound(uri, comps) {
+ return !isNil(filter(function(comp) {
+ return !isNil(filter(function(svc) {
+ return !isNil(filter(function(b) {
+ return uri == scdl.uri(b);
+ }, scdl.bindings(svc)));
+ }, scdl.services(comp)));
+ }, comps));
+}
+
+/**
+ * Get app data from the main app page component.
+ */
+function getappdata(appname, page, compos) {
+ try {
+
+ // Eval a component init script
+ function evalcompinit(doc) {
+ if (isNil(doc))
+ return true;
+ var js = car(json.readJSON(mklist(doc)));
+ if (!elementHasValue(js))
+ return true;
+ eval(elementValue(js));
+ return true;
+ }
+
+ // Initial setup of a widget
+ function setupwidget(e) {
+ initwidget(e);
+ fixupwidget(e);
+ bindwidgethandler(e, appname);
+ }
+
+ // Setup the widgets
+ map(setupwidget, filter(function(e) { return !isNil(e.id); }, nodeList(ui.elementByID(contentdiv, 'page').childNodes)));
+
+ // Get the app components
+ var comps = scdl.components(compos);
+
+ // Get the component app data
+ if (isbound("start", comps)) {
+ startcomp.get(location.search, function(doc, e) {
+ if (isNil(doc)) {
+ debug('error on get(start, ' + location.search + ')', e);
+ return false;
+ }
+
+ // Display data on the page
+ updatepage(docdata(doc));
+ });
+ }
+
+ // Get and eval the optional timer, animation and location watch setup scripts
+ if (isbound("timer", comps)) {
+ timercomp.get('setup', function(doc, e) {
+ if (isNil(doc)) {
+ debug('error on get(timer, setup)', e);
+ return false;
+ }
+
+ // Evaluate the component init expression
+ return evalcompinit(doc);
+ });
+ }
+
+ if (isbound("animation", comps)) {
+ animationcomp.get('setup', function(doc, e) {
+ if (isNil(doc)) {
+ debug('error on get(animation, setup)', e);
+ return false;
+ }
+
+ // Evaluate the component init expression
+ return evalcompinit(doc);
+ });
+ }
+
+ if (isbound("location", comps)) {
+ locationcomp.get('setup', function(doc, e) {
+ if (isNil(doc)) {
+ debug('error on get(location, setup)', e);
+ return false;
+ }
+
+ // Evaluate the component init expression
+ return evalcompinit(doc);
+ });
+ }
+
+ return true;
+
+ } catch(e) {
+ debug('error in getappdata()', e);
+ return true;
+ }
+}
+
+/**
+ * Return the page in an ATOM entry.
+ */
+function atompage(doc) {
+ var entry = atom.readATOMEntry(mklist(doc));
+ if (isNil(entry))
+ return mklist();
+ var content = namedElementChild("'content", car(entry));
+ if (content == null)
+ return mklist();
+ return elementChildren(content);
+}
+
+/**
+ * Get the app page.
+ */
+function getapppage(appname, compos) {
+ pagecomp.get(appname, function(doc, e) {
+ //debug('page get');
+ if (isNil(doc)) {
+ debug('error in getapppage', e);
+ return false;
+ }
+
+ // Set the app HTML page into the content div
+ var page = atompage(doc);
+ contentdiv.innerHTML = writeStrings(writeXML(page, false));
+ apppage = page;
+
+ // Merge in the app data
+ if (!isNil(appcomposite))
+ getappdata(appname, apppage, appcomposite);
+});
+
+}
+
+/**
+ * Build a query string from the values of the page's input fields.
+ */
+function compquery() {
+ function queryarg(e) {
+ return e.id + '=' + inputvalue(e);
+ }
+
+ function childrenList(n) {
+ return append(nodeList(n.childNodes), reduce(append, mklist(), map(childrenList, nodeList(n.childNodes))));
+ }
+
+ var args = map(queryarg, filter(function(e) { return !isNil(e.id) && !isNil(inputvalue(e)); }, childrenList(ui.elementByID(contentdiv, 'page'))));
+
+ // Append current location properties if known
+ if (!isNil(geoposition)) {
+ var g = geoposition;
+ args = append(args, mklist('latitude=' + g.coords.latitude, 'longitude=' + g.coords.longitude, 'altitude=' + g.coords.altitude,
+ 'accuracy=' + g.coords.accuracy, 'altitudeAccuracy=' + g.coords.altitudeAccuracy, 'heading=' + g.coords.heading,
+ 'speed=' + g.coords.speed));
+ }
+
+ return '?' + args.join('&');
+}
+
+/**
+ * Handle a button click event.
+ */
+function buttonClickHandler(id, appname) {
+ try {
+ var uri = compquery();
+ return sca.component(id, appname).get(uri, function(doc, e) {
+ if (isNil(doc)) {
+ debug('error on get(button, ' + uri + ')', e);
+ return false;
+ }
+
+ // Inject data into the page
+ updatepage(docdata(doc));
+ });
+ } catch(e) {
+ debug('error in buttonClickHandler()', e);
+ return true;
+ }
+}
+
+/**
+ * Handle a timer interval event.
+ */
+function intervalHandler() {
+ try {
+ var uri = compquery();
+ return timercomp.get(uri, function(doc, e) {
+ if (isNil(doc)) {
+ debug('error on get(timer, ' + uri + ')', e);
+ return false;
+ }
+
+ // Inject data into the page
+ updatepage(docdata(doc));
+ });
+ } catch(e) {
+ debug('error in intervalHandler()', e);
+ return true;
+ }
+}
+
+/**
+ * Setup an interval timer.
+ */
+function setupIntervalHandler(msec) {
+ intervalHandler();
+ try {
+ return setInterval(intervalHandler, msec);
+ } catch(e) {
+ debug('error in setupIntervalHandler()', e);
+ return true;
+ }
+}
+
+/**
+ * Handle an animation event.
+ */
+var animationData = null;
+var gettingAnimationData = false;
+var currentAnimationData = null;
+var animationLoop = 0;
+var currentAnimationLoop = 0;
+
+function animationHandler() {
+ try {
+ function applyAnimation() {
+ // Update page with current animation data
+ updatepage(car(currentAnimationData));
+
+ // End of animation?
+ if (isNil(cdr(currentAnimationData))) {
+ if (currentAnimationLoop == -1) {
+ // Repeat current animation forever
+ currentAnimationData = animationData;
+ return true;
+ }
+
+ currentAnimationLoop = currentAnimationLoop - 1;
+ if (currentAnimationLoop <= 0) {
+ // Get next animation data
+ currentAnimationData = null;
+ animationData = null;
+ return true;
+ }
+
+ // Repeat animation
+ currentAnimationData = animationData;
+ return true;
+ }
+
+ // Move to the next animation frame
+ currentAnimationData = cdr(currentAnimationData);
+ return true;
+ }
+
+ // Get new animation data if necessary
+ if (isNil(animationData)) {
+ if (gettingAnimationData)
+ return true;
+ var uri = compquery();
+ return animationcomp.get(uri, function(doc, e) {
+ if (isNil(doc)) {
+ debug('error on get(animation, ' + uri + ')', e);
+ return false;
+ }
+
+ // Apply the new animation
+ currentAnimationData = docdata(doc);
+ currentAnimationLoop = animationLoop;
+ gettingAnimationData = false;
+ applyAnimation();
+ });
+ }
+
+ // Apply the current animation
+ return applyAnimation();
+
+ } catch(e) {
+ debug('error in animationHandler()', e);
+ return true;
+ }
+}
+
+/**
+ * Setup an animation.
+ */
+function setupAnimationHandler(msec, loop) {
+ animationLoop = loop;
+ animationHandler();
+ try {
+ return setInterval(animationHandler, msec);
+ } catch(e) {
+ debug('error in setupAnimationHandler()', e);
+ return true;
+ }
+}
+
+/**
+ * Handle a location watch event.
+ */
+var locationWatch = null;
+var geoposition = null;
+
+function locationHandler(pos) {
+ try {
+ geoposition = pos;
+ var uri = compquery();
+ return locationcomp.get(uri, function(doc, e) {
+ if (isNil(doc)) {
+ debug('error on get(location, ' + uri + ')', e);
+ return false;
+ }
+
+ // Inject data into the page
+ updatepage(docdata(doc));
+ });
+ } catch(e) {
+ return locationErrorHandler(e);
+ }
+}
+
+function locationErrorHandler(e) {
+ debug('location error', e);
+ if (!isNil(locationWatch)) {
+ try {
+ navigator.geolocation.clearWatch(locationWatch);
+ } catch(e) {}
+ locationWatch = null;
+ }
+ return true;
+}
+
+/**
+ * Setup a location watch handler.
+ */
+function setupLocationHandler() {
+ function installLocationHandler() {
+ if (!isNil(locationWatch))
+ return true;
+ try {
+ locationWatch = navigator.geolocation.watchPosition(locationHandler, locationErrorHandler);
+ } catch(e) {
+ debug('error in installLocationHandler()', e);
+ }
+ return true;
+ }
+
+ installLocationHandler();
+ setInterval(installLocationHandler, 10000);
+ return true;
+}
+
+/**
+ * Handle orientation change.
+ */
+document.body.onorientationchange = function(e) {
+ //debug('onorientationchange');
+
+ // Scroll to the top and hide the address bar
+ window.scrollTo(0, 0);
+
+ return true;
+};
+
+/**
+ * Return the composite in an ATOM entry.
+ */
+function atomcomposite(doc) {
+ var entry = atom.readATOMEntry(mklist(doc));
+ if (isNil(entry))
+ return mklist();
+ var content = namedElementChild("'content", car(entry));
+ if (content == null)
+ return mklist();
+ return elementChildren(content);
+}
+
+/**
+ * Get the app composite.
+ */
+function getappcomposite(appname) {
+ return composcomp.get(appname, function(doc, e) {
+ //debug('page get');
+ if (isNil(doc)) {
+ debug('error in getappcomposite', e);
+ return false;
+ }
+
+ var compos = atomcomposite(doc);
+ if (isNil(compos)) {
+
+ // Create a default empty composite if necessary
+ var x = '<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" ' +
+ 'targetNamespace="http://app" name="app"></composite>';
+ compos = readXML(mklist(x));
+ }
+ appcomposite = compos;
+
+ // Merge in the app data
+ if (!isNil(apppage))
+ getappdata(appname, apppage, appcomposite);
+ });
+}
+
+/**
+ * Initialize the document.
+ */
+function onload() {
+ //debug('onload');
+
+ // Scroll to the top and hide the address bar
+ window.scrollTo(0, 0);
+
+ // Show the page
+ document.body.style.visibility = 'visible';
+
+ // Initialize the app composite
+ getappcomposite(appname);
+
+ // Initialize the app page
+ getapppage(appname);
+
+ return true;
+}
+
+onload();
+
+})();
+</script>
+
+<div id="footdiv" class="fsection">
+</div>
+
+</div>
+</body>
+</html>
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/cache-template.cmf b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/cache-template.cmf
new file mode 100644
index 0000000000..8d9aa26f7d
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/cache-template.cmf
@@ -0,0 +1,18 @@
+CACHE MANIFEST
+
+# Version SHA1
+
+# App resources
+/
+/favicon.ico
+/public/iframe-min.html
+/public/img.png
+/public/notauth/
+/public/notfound/
+/public/notyet/
+/public/oops/
+/public/touchicon.png
+
+NETWORK:
+*
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/clone/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/clone/index.html
new file mode 100644
index 0000000000..0a2f7733bc
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/clone/index.html
@@ -0,0 +1,157 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<div id="bodydiv" class="body">
+
+<div class="viewform">
+
+<form id="cloneAppForm">
+<table style="width: 100%;">
+<tr><td><b>New App Name:</b></td></tr>
+<tr><td><input type="text" id="appName" class="flatentry" size="15" autocapitalize="off" placeholder="Your app name"/></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>Icon:</b></td></tr>
+<tr><td><img id="appimg" style="width: 50px; height: 50px; vertical-align: top;"></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>Title:</b></td></tr>
+<tr><td><input type="text" id="appTitle" class="flatentry" size="30" placeholder="Enter the title of your app" style="width: 300px;"/></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>Description:</b></td></tr>
+<tr><td><textarea id="appDescription" class="flatentry" cols="40" rows="3" placeholder="Enter a short description of your app" style="width: 300px;"></textarea></td></tr>
+<tr><td>
+<input id="cloneAppOKButton" type="submit" class="graybutton bluebutton" style="font-weight: bold;" value="Clone" title="Clone the app"/>
+<input id="cloneAppCancelButton" type="button" class="graybutton" value="Cancel"/>
+</td></tr>
+</table>
+</form>
+
+</div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Get the app name.
+ */
+var appname = ui.fragmentParams(location)['app'];
+
+/**
+ * Set page titles.
+ */
+document.title = config.windowtitle() + ' - ' + config.clone() + ' - ' + appname;
+$('viewhead').innerHTML = '<span class="smenu">' + config.clone() + ' ' + appname + '</span>';
+$('cloneAppOKButton').value = config.clone();
+$('cloneAppOKButton').title = config.clone() + ' this app';
+
+/**
+ * Set images.
+ */
+$('appimg').src = ui.b64img(appcache.get('/public/app.b64'));
+
+/**
+ * Init service references.
+ */
+var editorComp = sca.component("Editor");
+var apps = sca.reference(editorComp, "apps");
+
+/**
+ * The current app entry and corresponding saved XML content.
+ */
+var appentry;
+var savedappentryxml = '';
+
+/**
+ * Get and display an app.
+ */
+function getapp(name) {
+ if (isNil(name))
+ return false;
+ showStatus('Loading');
+
+ return apps.get(name, function(doc) {
+
+ // Stop now if we didn't get the app
+ if (doc == null) {
+ showError('App not available');
+ return false;
+ }
+ showOnlineStatus();
+
+ appentry = doc != null? car(elementsToValues(atom.readATOMEntry(mklist(doc)))) : mklist("'entry", mklist("'title", ''), mklist("'id", name));
+ $('appTitle').value = cadr(assoc("'title", cdr(appentry)));
+ var content = cadr(assoc("'content", cdr(appentry)));
+ var description = assoc("'description", content);
+ $('appDescription').value = isNil(description) || isNil(cadr(description))? '' : cadr(description);
+ savedappentryxml = car(atom.writeATOMEntry(valuesToElements(mklist(appentry))));
+ return true;
+ });
+}
+
+/**
+ * Save an app.
+ */
+function save(name, entryxml) {
+ showStatus('Saving');
+ savedappentryxml = entryxml;
+ apps.put(name, savedappentryxml, function(e) {
+ if (e) {
+ showStatus('Local copy');
+ return false;
+ }
+ showStatus('Saved');
+
+ // Open it in the page editor
+ ui.navigate('/#view=page&app=' + name, '_view');
+ return false;
+ });
+ return false;
+}
+
+/**
+ * Clone an app.
+ */
+$('cloneAppForm').onsubmit = function() {
+ var name = $('appName').value;
+ if (name == '') {
+ showError('Missing app name');
+ return false;
+ }
+ showStatus('Saving');
+
+ // Clone the app
+ var title = $('appTitle').value;
+ var description = $('appDescription').value;
+ appentry = mklist("'entry", mklist("'title", title != ''? title : name), mklist("'id", appname), mklist("'content", mklist("'stats", mklist("'description", description))));
+ var entryxml = car(atom.writeATOMEntry(valuesToElements(mklist(appentry))));
+ return save(name, entryxml);
+};
+
+/**
+ * Cancel cloning an app.
+ */
+$('cloneAppCancelButton').onclick = function() {
+ history.back();
+};
+
+/**
+ * Get the current app.
+ */
+getapp(appname);
+
+})();
+</script>
+
+</div>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/config.js b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/config.js
new file mode 100644
index 0000000000..70d3ea1195
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/config.js
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+if (isNil(config))
+ config = {};
+
+/**
+ * UI configuration.
+ */
+config.windowtitle = function() {
+ return 'App Builder';
+};
+
+config.pagetitle = function() {
+ return '<span style="font-weight: bold;">App Builder</span>';
+};
+
+config.hometitle = function() {
+ return '<br/><span style="font-weight: bold;">Create SCA Composite Apps</span><br/><br/>';
+};
+
+config.clone = function() {
+ return 'Clone';
+};
+
+config.logic = function() {
+ return 'Logic';
+};
+
+config.viewfoot = function() {
+ return ui.menubar(mklist(ui.menu('menuabout', 'About', '/', '_view', 'note')), mklist());
+};
+
+config.appresources = function() {
+ return mklist();
+};
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/create/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/create/index.html
new file mode 100644
index 0000000000..d8d2b30f3c
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/create/index.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<div id="bodydiv" class="body">
+
+<div class="viewform">
+
+<form id="createAppForm">
+<table style="width: 100%;">
+<tr><td><b>App Name:</b></td></tr>
+<tr><td><input type="text" id="appName" class="flatentry" size="15" autocapitalize="off" placeholder="Your app name"/></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>App Icon:</b></td></tr>
+<tr><td><img id="appimg" style="width: 50px; height: 50px; vertical-align: top;"></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>App Title:</b></td></tr>
+<tr><td><input type="text" id="appTitle" class="flatentry" size="30" placeholder="Enter the title of your app" style="width: 300px;"/></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>Description:</b></td></tr>
+<tr><td><textarea id="appDescription" class="flatentry" cols="40" rows="3" placeholder="Enter a short description of your app" style="width: 300px;"></textarea></td></tr>
+<tr><td>
+<input id="createAppOKButton" type="submit" class="graybutton bluebutton" style="font-weight: bold;" value="Create" title="Create the app"/>
+<input id="createAppCancelButton" type="button" class="graybutton" value="Cancel"/>
+</td></tr>
+</table>
+</form>
+
+</div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Set page titles.
+ */
+document.title = config.windowtitle() + ' - Create App';
+$('viewhead').innerHTML = '<span class="smenu">Create an App</span>';
+
+/**
+ * Set images.
+ */
+$('appimg').src = ui.b64img(appcache.get('/public/app.b64'));
+
+/**
+ * Init service references.
+ */
+var editorComp = sca.component("Editor");
+var apps = sca.reference(editorComp, "apps");
+
+/**
+ * The current app entry and corresponding saved XML content.
+ */
+var appentry;
+var savedappentryxml = '';
+
+/**
+ * Save an app.
+ */
+function save(name, entryxml) {
+ showStatus('Saving');
+ savedappentryxml = entryxml;
+ apps.put(name, savedappentryxml, function(e) {
+ if (e) {
+ showStatus('Local copy');
+ return false;
+ }
+ showStatus('Saved');
+
+ // Open it in the page editor
+ ui.navigate('/#view=page&app=' + name, '_view');
+ return false;
+ });
+ return false;
+}
+
+/**
+ * Create an app.
+ */
+$('createAppForm').onsubmit = function() {
+ var name = $('appName').value;
+ if (name == '') {
+ showError('Missing app name');
+ return false;
+ }
+ showStatus('Modified');
+
+ // Clone the 'new' app template
+ var title = $('appTitle').value;
+ var description = $('appDescription').value;
+ appentry = mklist("'entry", mklist("'title", title != ''? title : name), mklist("'id", 'new'), mklist("'content", mklist("'stats", mklist("'description", description))));
+ var entryxml = car(atom.writeATOMEntry(valuesToElements(mklist(appentry))));
+ return save(name, entryxml);
+};
+
+/**
+ * Cancel creating an app.
+ */
+$('createAppCancelButton').onclick = function() {
+ history.back();
+};
+
+/**
+ * Show the status.
+ */
+showOnlineStatus();
+
+})();
+</script>
+
+</div>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/delete/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/delete/index.html
new file mode 100644
index 0000000000..5a668af401
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/delete/index.html
@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<div id="bodydiv" class="body">
+
+<div class="viewform">
+
+<form id="deleteAppForm">
+<table style="width: 100%;">
+<tr><tr><td style="padding-top: 6px;"><b>App Icon:</b></td></tr>
+<tr><td><img id="appimg" style="width: 50px; height: 50px; vertical-align: top;"></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>App Title:</b></td></tr>
+<tr><td><input type="text" id="appTitle" class="flatentry" size="30" readonly="readonly" style="width: 300px;"/></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>Author:</b></td></tr>
+<tr><td><span id="appAuthor"></span></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>Updated:</b></td></tr>
+<tr><td><span id="appUpdated"></span></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>Description:</b></td></tr>
+<tr><td><textarea id="appDescription" class="flatentry" cols="40" rows="3" readonly="readonly" style="width: 300px;"></textarea></td></tr>
+<tr><td>
+<input id="deleteAppOKButton" type="submit" class="graybutton bluebutton" style="font-weight: bold;" value="Delete" title="Delete the app"/>
+<input id="deleteAppCancelButton" type="button" class="graybutton" value="Cancel"/>
+</td></tr>
+</table>
+</form>
+
+</div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Get the app name.
+ */
+var appname = ui.fragmentParams(location)['app'];
+
+/**
+ * Set page titles.
+ */
+document.title = config.windowtitle() + ' - ' + 'Delete' + ' - ' + appname;
+$('viewhead').innerHTML = '<span class="smenu">Delete ' + appname + '</span>';
+
+/**
+ * Set images.
+ */
+$('appimg').src = ui.b64img(appcache.get('/public/app.b64'));
+
+/**
+ * Init service references.
+ */
+var editorComp = sca.component("Editor");
+var apps = sca.reference(editorComp, "apps");
+
+/**
+ * The current app entry and corresponding saved XML content.
+ */
+var appentry;
+
+/**
+ * Get and display an app.
+ */
+function getapp(name) {
+ if (isNil(name))
+ return false;
+ showStatus('Loading');
+
+ return apps.get(name, function(doc) {
+
+ // Stop now if we didn't get the app
+ if (doc == null) {
+ showError('App not available');
+ return false;
+ }
+ showOnlineStatus();
+
+ appentry = doc != null? car(elementsToValues(atom.readATOMEntry(mklist(doc)))) : mklist("'entry", mklist("'title", ''), mklist("'id", name));
+ $('appTitle').value = cadr(assoc("'title", cdr(appentry)));
+ $('appAuthor').innerHTML = cadr(assoc("'author", cdr(appentry)));
+ $('appUpdated').innerHTML = cadr(assoc("'updated", cdr(appentry)));
+ var content = cadr(assoc("'content", cdr(appentry)));
+ var description = assoc("'description", content);
+ $('appDescription').value = isNil(description) || isNil(cadr(description))? '' : cadr(description);
+ return true;
+ });
+}
+
+/**
+ * Delete an app.
+ */
+$('deleteAppForm').onsubmit = function() {
+ showStatus('Deleting');
+
+ // Delete the app
+ apps.del(appname, function(e) {
+ if (e) {
+ showStatus('Local copy');
+ return false;
+ }
+ showOnlineStatus();
+
+ // Return to the app store
+ ui.navigate('/#view=store', '_view');
+ return false;
+ });
+ return false;
+};
+
+/**
+ * Cancel cloning an app.
+ */
+$('deleteAppCancelButton').onclick = function() {
+ history.back();
+};
+
+/**
+ * Get the current app.
+ */
+getapp(appname);
+
+})();
+</script>
+
+</div>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/favicon.ico b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/favicon.ico
new file mode 100644
index 0000000000..a7b502b9e1
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/favicon.ico
Binary files differ
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/graph/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/graph/index.html
new file mode 100644
index 0000000000..d360336375
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/graph/index.html
@@ -0,0 +1,2100 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<div id="bodydiv" class="body">
+
+<div id="contentdiv" class="viewcontent" style="width: 2500px;">
+<div id="graphdiv" class="graphdiv" style="top: 0px; left: -2500px; width: 5000px; height: 5000px;"></div>
+<div id="playdiv" style="position: absolute; top: 0x; left: 0px; width: 2500px; height: 5000px; visibility: hidden"></div>
+</div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Get the current app name.
+ */
+var appname = ui.fragmentParams(location)['app'];
+var ispalette = false;
+if (isNil(appname)) {
+ appname = ui.fragmentParams(location)['palette'];
+
+ // Edit a palette instead of a regular app
+ if (!isNil(appname))
+ ispalette = true;
+}
+
+/**
+ * Set page title.
+ */
+document.title = config.windowtitle() + ' - ' + config.logic() + ' - ' + appname;
+
+/**
+ * Set header div.
+ */
+$('viewhead').innerHTML = '<span id="appTitle" class="cmenu">' + appname + '</span>' +
+'<input type="button" id="deleteCompButton" title="Delete a component" class="graybutton redbutton plusminus" style="position: absolute; top: 4px; left: 5px;" disabled="true" value="-"/>' +
+'<span style="position: absolute; top: 0px; left: 45px; right: 115px; padding: 0px; background: transparent;"><input id="compValue" type="text" value="" class="flatentry" title="Component value" autocapitalize="off" placeholder="Value" style="position: absolute; left: 0px; top: 4px; width: 100%; visibility: hidden;" readonly="readonly"/></span>' +
+'<input type="button" id="playCompButton" title="View component value" class="graybutton plusminus" style="position: absolute; top: 4px; right: 75px;" disabled="true" value="&gt;"/>' +
+'<input type="button" id="copyCompButton" title="Copy a component" class="graybutton bluebutton" style="position: absolute; top: 4px; right: 40px;" disabled="true" value="C"/>' +
+'<input type="button" id="addCompButton" title="Add a component" class="graybutton bluebutton plusminus" style="position: absolute; top: 4px; right: 5px;" disabled="true" value="+"/>';
+
+/**
+ * Track the current app composite, author, and saved XML content.
+ */
+var author = '';
+var editable = false;
+var composite;
+var savedcomposxml = '';
+
+/**
+ * Component value field, add, delete and play buttons.
+ */
+var cvalue = $('compValue');
+var atitle = $('appTitle');
+var cadd = $('addCompButton');
+var cdelete = $('deleteCompButton');
+var ccopy = $('copyCompButton');
+var cplay = $('playCompButton');
+
+/**
+ * Init componnent references.
+ */
+var editorComp = sca.component("Editor");
+var palettes = sca.reference(editorComp, "palettes");
+var composites = sca.reference(editorComp, ispalette? "palettes" : "composites");
+
+/**
+ * Composite rendering functions.
+ */
+var graph = {};
+
+/**
+ * Basic colors
+ */
+graph.colors = {};
+graph.colors.black = '#000000';
+graph.colors.blue = '#0000ff';
+graph.colors.cyan = '#00ffff';
+graph.colors.gray = '#808080'
+graph.colors.lightgray = '#dcdcdc'
+graph.colors.green = '#00ff00';
+graph.colors.magenta = '#ff00ff';
+graph.colors.orange = '#ffa500';
+graph.colors.pink = '#ffc0cb';
+graph.colors.purple = '#800080';
+graph.colors.red = '#ff0000';
+graph.colors.white = '#ffffff';
+graph.colors.yellow = '#ffff00';
+graph.colors.link = '#357ae8';
+
+graph.colors.orange1 = '#ffd666';
+graph.colors.green1 = '#bbe082';
+graph.colors.blue1 = '#66dbdf';
+graph.colors.yellow1 = '#fdf57a';
+graph.colors.cyan1 = '#e6eafb';
+graph.colors.lightgray1 = '#eaeaea'
+graph.colors.pink1 = '#ffd9e0';
+graph.colors.red1 = '#d03f41';
+graph.colors.white1 = '#ffffff';
+
+graph.colors.orange2 = '#ffbb00';
+graph.colors.green2 = '#96d333';
+//graph.colors.blue2 = '#0d7cc1';
+graph.colors.blue2 = '#00c3c9';
+graph.colors.red2 = '#d03f41';
+graph.colors.yellow2 = '#fcee21';
+graph.colors.magenta2 = '#c0688a';
+graph.colors.cyan2 = '#d5dcf9';
+graph.colors.lightgray2 = '#dcdcdc'
+graph.colors.pink2 = '#ffc0cb';
+graph.colors.white2 = '#ffffff';
+
+graph.colors.orange3 = '#ffc700';
+graph.colors.green3 = '#92e120';
+graph.colors.blue3 = '#008fd1';
+graph.colors.yellow3 = '#fdf400';
+graph.colors.cyan3 = '#b4d3fd';
+graph.colors.lightgray3 = '#e3e3e3'
+graph.colors.pink3 = '#da749b';
+graph.colors.red3 = '#ed3f48';
+graph.colors.white3 = '#ffffff';
+
+/**
+ * Default positions and sizes.
+ */
+graph.palcx = 2500;
+graph.proxcx = 20;
+graph.proxcy = 20;
+graph.buttoncx = 55;
+graph.buttoncy = 23;
+graph.curvsz = 4;
+graph.tabsz = 2;
+graph.titlex = 4;
+graph.titley = 0;
+
+/**
+ * Make a composite graph editor.
+ */
+graph.mkedit = function(graphdiv, pos, atitle, cvalue, cadd, ccopy, cdelete, onchange, onselect) {
+
+ // Track element dragging and selection
+ graph.dragging = null;
+ graph.dragged = false;
+ graph.selected = null;
+ cvalue.readOnly = true;
+ cvalue.style.visibility = 'hidden';
+ atitle.style.visibility = 'visible';
+ ccopy.disabled = true;
+ cdelete.disabled = true;
+ cadd.disabled = !editable;
+
+ // Register event listeners
+ graph.oncomposchange = onchange;
+ graph.oncompselect = onselect;
+
+ /**
+ * Find the first draggable element in a hierarchy of elements.
+ */
+ function draggable(n) {
+ //debug('draggable', n);
+ if (n == graphdiv || n == null)
+ return null;
+ if (n.className == 'g' && !isNil(n.id) && n.id != '')
+ return n;
+ return draggable(n.parentNode);
+ }
+
+ /**
+ * Handle a mouse down or touch start event.
+ */
+ function onmousedown(e) {
+
+ // Remember mouse or touch position
+ var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
+ graph.downX = pos.screenX;
+ graph.downY = pos.screenY;
+ graph.moveX = pos.screenX;
+ graph.moveY = pos.screenY;
+
+ // Engage the click component selection right away
+ // on mouse controlled devices
+ if (typeof e.touches == 'undefined')
+ onclick(e);
+
+ // Find and remember draggable component
+ var dragging = draggable(e.target);
+ if (dragging == null || dragging != graph.selected)
+ return true;
+ graph.dragging = dragging;
+ graph.dragged = false;
+
+ // Remember current drag position
+ graph.dragX = pos.screenX;
+ graph.dragY = pos.screenY;
+
+ e.preventDefault();
+ return true;
+ };
+
+ if (!ui.isMobile()) {
+ graphdiv.onmousedown = function(e) {
+ //debug('onmousedown');
+ return onmousedown(e);
+ }
+ } else {
+ graphdiv.ontouchstart = function(e) {
+ //debug('ontouchstart');
+ return onmousedown(e);
+ }
+ }
+
+ /**
+ * Handle a mouse up or touch end event.
+ */
+ function onmouseup(e) {
+
+ // Engage the click component selection now on touch devices
+ if (ui.isMobile()) {
+ if (!graph.dragged && graph.moveX == graph.downX && graph.moveY == graph.downY)
+ return onclick(e);
+ }
+
+ // Stop here if the component was not dragged
+ if (graph.dragging == null)
+ return true;
+ if (!graph.dragged) {
+ graph.dragging = null;
+ return true;
+ }
+
+ if (graph.dragging.parentNode == graphdiv && graph.dragging.id.substring(0, 8) != 'palette:') {
+
+ // Add new dragged component to the composite
+ if (isNil(graph.dragging.compos)) {
+ var compos = scdl.composite(graphdiv.compos);
+ setElement(compos, graph.sortcompos(graph.addcomps(mklist(graph.dragging.comp), compos)));
+ graph.dragging.compos = graphdiv.compos;
+ }
+
+ // Update component position
+ setElement(graph.dragging.comp, graph.movecomp(graph.dragging.comp, graph.abspos(graph.draggingg)));
+
+ // Wire component to neighboring reference
+ if (!isNil(graph.dragging.svcpos)) {
+ var compos = scdl.composite(graphdiv.compos);
+ setElement(compos, graph.sortcompos(graph.clonerefs(graph.wire(graph.dragging, compos, graphdiv))));
+ }
+
+ // Snap top level component position to grid
+ if (graph.dragging.parentNode == graphdiv) {
+ var gpos = graph.relpos(graph.dragging);
+ setElement(graph.dragging.comp, graph.movecomp(graph.dragging.comp, graph.mkpath().pos(graph.gridsnap(gpos.x), graph.gridsnap(gpos.y))));
+ }
+ }
+
+ // Forget current dragged component
+ graph.dragging = null;
+ graph.dragged = false;
+
+ // Refresh the composite
+ //debug('onmouseup refresh');
+ var nodes = graph.refresh(graphdiv);
+
+ // Reselect the previously selected component
+ if (!isNil(graph.selected)) {
+ graph.selected = graph.findcompnode(scdl.name(graph.selected.comp), nodes);
+ graph.compselect(graph.selected, true, atitle, cvalue, ccopy, cdelete);
+
+ // Trigger component select event
+ graph.oncompselect(graph.selected);
+ }
+
+ // Trigger composite change event
+ graph.oncomposchange(false);
+ return true;
+ };
+
+ if (!ui.isMobile()) {
+ graphdiv.onmouseup = function(e) {
+ //debug('onmouseup');
+ return onmouseup(e);
+ }
+ } else {
+ graphdiv.ontouchend = function(e) {
+ //debug('ontouchend');
+ return onmouseup(e);
+ }
+ }
+
+ /**
+ * Handle a mouse or touch click event.
+ */
+ function onclick(e) {
+ //debug('onclick logic');
+
+ // Find selected component
+ var selected = draggable(e.target);
+ if (selected == null) {
+ if (graph.selected != null) {
+
+ // Reset current selection
+ graph.compselect(graph.selected, false, atitle, cvalue, ccopy, cdelete);
+ graph.selected = null;
+
+ // Trigger component select event
+ graph.oncompselect(null);
+ }
+
+ // Dismiss the palette
+ if (e.target == graphdiv && ui.numpos(graphdiv.style.left) != (graph.palcx * -1))
+ graphdiv.style.left = ui.pixpos(graph.palcx * -1);
+
+ return true;
+ }
+
+
+ // Ignore duplicate click events
+ if (selected == graph.selected)
+ return true;
+ if (selected.id.substring(0, 8) == 'palette:' && ui.numpos(graphdiv.style.left) != 0)
+ return true;
+
+ // Deselect previously selected component
+ graph.compselect(graph.selected, false, atitle, cvalue, ccopy, cdelete);
+
+ // Clone component from the palette
+ if (selected.id.substring(0, 8) == 'palette:') {
+ var compos = scdl.composite(graphdiv.compos);
+ var comp = graph.clonepalette(selected, compos);
+ setElement(compos, graph.sortcompos(graph.addcomps(mklist(comp), compos)));
+
+ // Move into the editing area and hide the palette
+ graphdiv.style.left = ui.pixpos(graph.palcx * -1);
+
+ // Refresh the composite
+ //debug('onclick refresh');
+ var nodes = graph.refresh(graphdiv);
+
+ // Reselect the previously selected component
+ graph.selected = graph.findcompnode(scdl.name(comp), nodes);
+ graph.compselect(graph.selected, true, atitle, cvalue, ccopy, cdelete);
+
+ // Trigger component select event
+ graph.oncompselect(graph.selected);
+
+ // Trigger composite change event
+ graph.oncomposchange(true);
+
+ } else {
+ graph.selected = selected;
+
+ // Select the component
+ graph.compselect(graph.selected, true, atitle, cvalue, ccopy, cdelete);
+
+ // Trigger component select event
+ graph.oncompselect(graph.selected);
+ }
+
+ //debug('comp selected');
+
+ e.preventDefault();
+ return true;
+ }
+
+ if (!ui.isMobile()) {
+ graphdiv.onclick = function(e) {
+ //debug('onclick');
+ return onclick(e);
+ }
+ } else {
+ graphdiv.onclick = function(e) {
+ //debug('onclick');
+ return onclick(e);
+ }
+ }
+
+ /**
+ * Handle a mouse or touch move event.
+ */
+ function onmousemove(e) {
+ if (graph.dragging == null)
+ return true;
+
+ // Ignore duplicate mouse move events
+ if (graph.moveX == graph.dragX && graph.moveY == graph.dragY)
+ return true;
+
+ // Remember that the component was dragged
+ graph.dragged = true;
+
+ // Cut wire to component
+ if (graph.dragging.parentNode != graphdiv) {
+ var compos = scdl.composite(graphdiv.compos);
+ setElement(compos, graph.sortcompos(graph.cutwire(graph.dragging, compos, graphdiv)));
+
+ // Bring component to the top
+ graph.bringtotop(graph.dragging, graphdiv);
+ }
+
+ // Calculate new position of dragged element
+ var gpos = graph.relpos(graph.dragging);
+ var newX = gpos.x + (graph.moveX - graph.dragX);
+ var newY = gpos.y + (graph.moveY - graph.dragY);
+ if (newX >= graph.palcx)
+ graph.dragX = graph.moveX
+ else
+ newX = graph.palcx;
+ if (newY >= 0)
+ graph.dragY = graph.moveY;
+ else
+ newY = 0;
+
+ // Move the dragged element
+ graph.move(graph.dragging, graph.mkpath().pos(newX, newY));
+
+ return false;
+ };
+
+ if (!ui.isMobile()) {
+ window.onmousemove = function(e) {
+ //debug('onmousemove');
+
+ // Remember mouse position
+ graph.moveX = e.screenX;
+ graph.moveY = e.screenY;
+
+ return onmousemove(e);
+ }
+ } else {
+ graphdiv.ontouchmove = function(e) {
+ //debug('ontouchmove');
+
+ // Remember touch position
+ var pos = e.touches[0];
+ if (graph.moveX == pos.screenX && graph.moveY == pos.screenY)
+ return true;
+ graph.moveX = pos.screenX;
+ graph.moveY = pos.screenY;
+ if (graph.moveX == graph.dragX && graph.moveY == graph.dragY)
+ return true;
+
+ return onmousemove(e);
+ }
+ }
+
+ /**
+ * Handle field on change events.
+ */
+ function onvaluechange() {
+ if (graph.selected == null)
+ return false;
+ if (graphdiv.parentNode.style.visibility == 'hidden')
+ return false;
+
+ // Change component name and refactor references to it
+ function changename() {
+ var compos = scdl.composite(graphdiv.compos);
+ cvalue.value = graph.ucid(cvalue.value, compos, false);
+ graph.selected.id = cvalue.value;
+ setElement(compos, graph.sortcompos(graph.renamecomp(graph.selected.comp, compos, cvalue.value)));
+
+ // Refresh the composite
+ //debug('onchangename refresh');
+ var nodes = graph.refresh(graphdiv);
+
+ // Reselected the previously selected component
+ graph.selected = graph.findcompnode(scdl.name(graph.selected.comp), nodes);
+ graph.compselect(graph.selected, true, atitle, cvalue, ccopy, cdelete);
+
+ // Trigger component select event
+ graph.oncompselect(graph.selected);
+
+ // Trigger composite change event
+ graph.oncomposchange(true);
+ return false;
+ }
+
+ // Change the component property value
+ function changeprop() {
+ graph.setproperty(graph.selected.comp, cvalue.value);
+ var hasprop = graph.hasproperty(graph.selected.comp);
+ cvalue.readOnly = (hasprop? false : true) || !editable;
+ cvalue.style.visibility = hasprop? 'visible' : 'hidden';
+ atitle.style.visibility = hasprop? 'hidden' : 'visible';
+ cvalue.value = graph.property(graph.selected.comp);
+
+ // Refresh the composite
+ //debug('onchangeprop refresh');
+ var nodes = graph.refresh(graphdiv);
+
+ // Reselected the previously selected component
+ graph.selected = graph.findcompnode(scdl.name(graph.selected.comp), nodes);
+ graph.compselect(graph.selected, true, atitle, cvalue, ccopy, cdelete);
+
+ // Trigger component select event
+ graph.oncompselect(graph.selected);
+
+ // Trigger composite change event
+ graph.oncomposchange(true);
+ return false;
+ }
+
+ return graph.hasproperty(graph.selected.comp)? changeprop() : changename();
+ };
+
+ cvalue.onchange = function() {
+ return onvaluechange();
+ }
+
+ // Handle delete event
+ function ondeleteclick() {
+ if (graph.selected == null)
+ return false;
+ if (graph.selected.id.substring(0, 8) != 'palette:') {
+
+ // Remove selected component
+ var compos = scdl.composite(graphdiv.compos);
+ if (isNil(graph.selected.compos))
+ setElement(compos, graph.sortcompos(graph.cutwire(graph.selected, compos, graphdiv)));
+ setElement(compos, graph.sortcompos(graph.clonerefs(graph.gcollect(graph.removecomp(graph.selected.comp, compos)))));
+
+ // Reset current selection
+ graph.compselect(graph.selected, false, atitle, cvalue, ccopy, cdelete);
+ graph.selected = null;
+
+ // Refresh the composite
+ //debug('ondelete refresh');
+ graph.refresh(graphdiv);
+
+ // Trigger component select event
+ graph.oncompselect(null);
+
+ // Trigger composite change event
+ graph.oncomposchange(true);
+ }
+ return false;
+ };
+
+ cdelete.onclick = function() {
+ return ondeleteclick();
+ };
+
+ // Handle copy event
+ function oncopyclick() {
+ if (graph.selected == null)
+ return false;
+ if (graph.selected.id.substring(0, 8) == 'palette:')
+ return false;
+
+ // Clone the selected component
+ var compos = scdl.composite(graphdiv.compos);
+ var comps = graph.clonecomp(graph.selected, compos);
+ setElement(compos, graph.sortcompos(graph.addcomps(comps, compos)));
+
+ // Refresh the composite
+ //debug('oncopyclick refresh');
+ var nodes = graph.refresh(graphdiv);
+
+ // Select the component clone
+ graph.selected = graph.findcompnode(scdl.name(car(comps)), nodes);
+ graph.compselect(graph.selected, true, atitle, cvalue, ccopy, cdelete);
+
+ // Trigger component select event
+ graph.oncompselect(graph.selected);
+
+ // Trigger composite change event
+ graph.oncomposchange(true);
+
+ return false;
+ };
+
+ ccopy.onclick = function() {
+ return oncopyclick();
+ };
+
+ // Handle add event
+ cadd.onclick = function() {
+
+ // Show the palette
+ graphdiv.style.left = ui.pixpos(0);
+ return false;
+ };
+
+ // Create a hidden SVG element to help compute the width
+ // of component and reference titles
+ graph.offtitles = document.createElement('span');
+ graph.offtitles.style.visibility = 'hidden';
+ graph.offtitles.position = 'absolute';
+ graph.offtitles.top = -500;
+ graph.offtitles.width = 500;
+ graph.offtitles.height = 50;
+ graphdiv.appendChild(graph.offtitles);
+
+ return graphdiv;
+};
+
+/**
+ * Point class.
+ */
+graph.Point = function(x, y) {
+ this.x = x;
+ this.y = y;
+};
+
+graph.mkpoint = function(x, y) {
+ return new graph.Point(x, y);
+};
+
+/**
+ * Path class.
+ */
+graph.Path = function() {
+ this.x = 0;
+ this.y = 0;
+ this.xmin = null;
+ this.xmax = null;
+ this.xmin = -8;
+ this.ymax = null;
+ this.draw = function(ctx) {
+ return ctx;
+ };
+}
+graph.Path.prototype.pos = function(x, y) {
+ this.x = x;
+ this.y = y;
+ if (this.xmin == null || x < this.xmin) this.xmin = x;
+ if (this.xmax == null || x > this.xmax) this.xmax = x;
+ if (this.ymin == null || y < this.ymin) this.ymin = y;
+ if (this.ymax == null || y > this.ymax) this.ymax = y;
+ return this;
+};
+graph.Path.prototype.rmove = function(x, y) {
+ return this.move(this.x + x, this.y + y);
+};
+graph.Path.prototype.rline = function(x, y) {
+ return this.line(this.x + x, this.y + y);
+};
+graph.Path.prototype.rcurve = function(x1, y1, x, y) {
+ return this.curve(this.x + x1, this.y + y1, this.x + x1 + x, this.y + y1 + y);
+};
+graph.Path.prototype.clone = function() {
+ return graph.mkpath().pos(this.x, this.y);
+};
+graph.Path.prototype.move = function(x, y) {
+ var d = this.draw;
+ this.draw = function(ctx) {
+ d(ctx);
+ ctx.moveTo(x, y);
+ return ctx;
+ };
+ return this.pos(x, y);
+};
+graph.Path.prototype.line = function(x, y) {
+ var d = this.draw;
+ this.draw = function(ctx) {
+ d(ctx);
+ ctx.lineTo(x, y);
+ return ctx;
+ };
+ return this.pos(x, y);
+};
+graph.Path.prototype.curve = function(x1, y1, x, y) {
+ var d = this.draw;
+ this.draw = function(ctx) {
+ d(ctx);
+ ctx.quadraticCurveTo(x1, y1, x, y);
+ return ctx;
+ };
+ return this.pos(x, y);
+};
+graph.Path.prototype.end = function() {
+ var d = this.draw;
+ this.draw = function(ctx) {
+ ctx.beginPath();
+ d(ctx);
+ ctx.fill();
+ ctx.beginPath();
+ d(ctx);
+ ctx.stroke();
+ };
+ return this;
+};
+graph.Path.prototype.bounds = function() {
+ var width = this.xmin == null || this.xmax == null? 0 : this.xmax - this.xmin + 1;
+ var height = this.ymin == null || this.ymax == null? 0 : this.ymax - this.ymin + 1;
+ return graph.mkpath().pos(width, height);
+};
+
+graph.mkpath = function() {
+ return new graph.Path();
+};
+
+/**
+ * Translate the position of an element.
+ */
+graph.translate = function(g, x, y) {
+ var t = 'translate(' + ui.pixpos(x) + ',' + ui.pixpos(y) + ')';
+ g.style.setProperty('-webkit-transform', t, null);
+ g.style.setProperty('-moz-transform', t, null);
+ g.style.setProperty('-o-transform', t, null);
+ g.style.setProperty('transform', t, null);
+ g.ctmx = x;
+ g.ctmy = y;
+ return g;
+};
+
+/**
+ * Apply a path to an element.
+ */
+graph.drawshape = function(g) {
+ // Set shape element size
+ var b = g.path.bounds();
+ g.width = b.x + 4;
+ g.height = b.y + 4;
+
+ // Get canvas context
+ var ctx = g.getContext('2d');
+ ctx.save();
+
+ // Apply translation
+ ctx.translate((g.path.xmin * -1) + 2, (g.path.ymin * -1) + 2);
+
+ // Draw the shape
+ ctx.fillStyle = g.fillStyle;
+ ctx.strokeStyle = !isNil(g.strokeStyle)? g.strokeStyle : graph.colors.gray;
+ ctx.lineWidth = !isNil(g.lineWidth)? g.lineWidth : 1;
+ g.path.draw(ctx);
+
+ // Reset canvas context
+ ctx.restore();
+ return g;
+}
+
+/**
+ * Return an element representing a title.
+ */
+graph.mktitle = function(t, x, y) {
+ var title = document.createElement('span');
+ title.className = 'gtitle';
+ title.style.left = ui.pixpos(x);
+ title.style.top = ui.pixpos(y);
+ title.appendChild(document.createTextNode(t));
+ graph.offtitles.appendChild(title);
+ title.style.width = ui.pixpos(title.clientWidth + 2);
+ title.style.height = ui.pixpos(title.clientHeight + 2);
+ return title;
+};
+
+/**
+ * Return an element representing the title of a component.
+ */
+graph.comptitle = function(comp) {
+ return memo(comp, 'title', function() {
+ var ct = graph.title(comp);
+ var pt = graph.propertytitle(comp);
+ if (ct == '' && pt == '')
+ return null;
+ return graph.mktitle((ct != '' && pt != '')? ct + ' ' + pt : ct + pt, graph.titlex, graph.titley);
+ });
+};
+
+/**
+ * Return the width of the title of a component.
+ */
+graph.comptitlewidth = function(comp) {
+ var title = graph.comptitle(comp);
+ if (isNil(title))
+ return 0;
+ return title.clientWidth;
+};
+
+/**
+ * Draw a component shape selection.
+ */
+graph.compselect = function(g, s, atitle, cvalue, ccopy, cdelete) {
+ if (isNil(g) || !s) {
+ cvalue.value = '';
+ cvalue.readOnly = true;
+ cvalue.style.visibility = 'hidden';
+ atitle.style.visibility = 'visible';
+ ccopy.disabled = true;
+ cdelete.disabled = true;
+ if (isNil(g))
+ return true;
+ g.shape.strokeStyle = null;
+ g.shape.lineWidth = null;
+ graph.drawshape(g.shape);
+ return true;
+ }
+
+ cvalue.value = graph.hasproperty(g.comp)? graph.property(g.comp) : g.id;
+ cvalue.readOnly = false || !editable;
+ cvalue.style.visibility = 'visible';
+ atitle.style.visibility = 'hidden';
+ ccopy.disabled = false || !editable;
+ cdelete.disabled = false || !editable;
+
+ g.shape.strokeStyle = graph.colors.link;
+ g.shape.lineWidth = 2;
+ graph.drawshape(g.shape);
+ g.parentNode.appendChild(g);
+ return true;
+};
+
+/**
+ * Draw a palette shape selection.
+ */
+graph.paletteselect = function(g, s) {
+ if (isNil(g))
+ return true;
+ if (!s) {
+ g.shape.strokeStyle = null;
+ g.shape.lineWidth = null;
+ graph.drawshape(g.shape);
+ return true;
+ }
+
+ g.shape.strokeStyle = graph.colors.link;
+ g.shape.lineWidth = 2;
+ graph.drawshape(g.shape);
+ g.parentNode.appendChild(g);
+ return true;
+};
+
+/**
+ * Return a node representing a component.
+ */
+graph.compnode = function(comp, cassoc, pos) {
+ //debug('compnode', graph.title(comp));
+
+ // Create the component shape
+ var shape = document.createElement('canvas');
+ shape.className = 'path';
+ shape.fillStyle = graph.color(comp);
+ shape.path = graph.comppath(comp, cassoc);
+ graph.drawshape(shape);
+
+ // Make the component title element
+ var title = graph.comptitle(comp);
+
+ // Create a span group element and add the shape and title to it
+ var g = document.createElement('span');
+ g.className = 'g';
+ g.comp = comp;
+ g.id = scdl.name(comp);
+ graph.translate(g, pos.x, pos.y);
+ g.pos = pos.clone();
+ g.appendChild(shape);
+ g.shape = shape;
+ g.style.width = ui.pixpos(shape.width);
+ g.style.height = ui.pixpos(shape.height);
+ if (!isNil(title)) {
+ title.style.left = ui.pixpos(shape.path.xmin * -1);
+ g.appendChild(title);
+ }
+
+ // Store the positions of the services and references
+ g.refpos = reverse(shape.path.refpos);
+ g.svcpos = reverse(shape.path.svcpos);
+
+ return g;
+};
+
+/**
+ * Find the node representing a component.
+ */
+graph.findcompnode = function(name, nodes) {
+ if (isNil(nodes))
+ return null;
+ if (isNil(car(nodes).comp))
+ return graph.findcompnode(name, cdr(nodes));
+ if (name == scdl.name(car(nodes).comp))
+ return car(nodes);
+ var node = graph.findcompnode(name, nodeList(car(nodes).childNodes));
+ if (!isNil(node))
+ return node;
+ return graph.findcompnode(name, cdr(nodes));
+}
+
+/**
+ * Return a graphical group.
+ */
+graph.mkgroup = function(pos) {
+ var g = document.createElement('div');
+ g.className = 'g';
+ graph.translate(g, pos.x, pos.y);
+ g.pos = pos.clone();
+ return g;
+};
+
+/**
+ * Return a node representing a button.
+ */
+graph.mkbutton = function(t, pos) {
+
+ // Create the main button shape
+ var shape = document.createElement('canvas');
+ shape.className = 'path';
+ shape.fillStyle = graph.colors.lightgray1;
+ shape.path = graph.buttonpath();
+ graph.drawshape(shape);
+
+ // Make the button title
+ var title = graph.mktitle(t, graph.titlex, graph.titley);
+
+ // Create a group and add the button shape and title to it
+ var g = document.createElement('span');
+ g.className = 'g';
+ graph.translate(g, pos.x, pos.y);
+ g.pos = pos.clone();
+ g.appendChild(shape);
+ g.appendChild(title);
+
+ // Store the button shape in the group
+ g.shape = shape;
+
+ return g;
+};
+
+/**
+ * Return the position of a node relative to its parent.
+ */
+graph.relpos = function(g) {
+ var curX = g.ctmx? g.ctmx : 0;
+ var curY = g.ctmy? g.ctmy : 0;
+ return graph.mkpath().pos(curX, curY);
+};
+
+/**
+ * Move a node.
+ */
+graph.move = function(g, pos) {
+ g.pos = pos.clone();
+ graph.translate(g, g.pos.x, g.pos.y);
+ return g;
+};
+
+/**
+ * Return the absolute position of a component node.
+ */
+graph.abspos = function(e) {
+ if (isNil(e) || e == graphdiv)
+ return graph.mkpath();
+ var gpos = graph.relpos(e);
+ var pgpos = graph.abspos(e.parentNode);
+ return graph.mkpath().pos(gpos.x + pgpos.x, gpos.y + pgpos.y);
+};
+
+/**
+ * Bring a component node to the top.
+ */
+graph.bringtotop = function(n, g) {
+ if (n == g)
+ return null;
+ graph.move(n, graph.abspos(n));
+ g.appendChild(n);
+}
+
+/**
+ * Return the title of a SCDL element.
+ */
+graph.title = function(e) {
+ var t = scdl.title(e);
+ if (t != null) {
+ if (t == 'gt')
+ return '>'
+ if (t == 'lt')
+ return '<';
+ if (t.indexOf('{propval}') != -1)
+ return '';
+ if (t.indexOf('{compname}') == -1)
+ return t;
+ return t.replace('{compname}', scdl.name(e));
+ }
+ return scdl.name(e);
+};
+
+/**
+ * Return the property value of a SCDL component.
+ */
+graph.property = function(e) {
+ var p = scdl.properties(e);
+ if (isNil(p))
+ return '';
+ if (scdl.visible(car(p)) == 'false')
+ return '';
+ var pv = scdl.propertyValue(car(p));
+ return pv;
+};
+
+/**
+ * Return the title of a property of a SCDL component.
+ */
+graph.propertytitle = function(e) {
+ var pv = graph.property(e);
+ var t = scdl.title(e);
+ if (t.indexOf('{propval}') == -1)
+ return pv;
+ return t[0] == ' '? t.substr(1).replace('{propval}', pv) : t.replace('{propval}', pv);
+};
+
+/**
+ * Return true if a SCDL component has a property.
+ */
+graph.hasproperty = function(e) {
+ var p = scdl.properties(e);
+ if (isNil(p))
+ return false;
+ if (scdl.visible(car(p)) == 'false')
+ return false;
+ return true;
+};
+
+/**
+ * Change the property value of a SCDL component.
+ */
+graph.setproperty = function(e, value) {
+ var p = scdl.properties(e);
+ if (isNil(p))
+ return '';
+ if (scdl.visible(car(p)) == 'false')
+ return '';
+ var name = scdl.name(car(p));
+ setElement(car(p), mklist(element, "'property", mklist(attribute, "'name", name != null? name : "property"), value));
+ return value;
+};
+
+/**
+ * Return the color of a SCDL component.
+ */
+graph.color = function(comp) {
+ return memo(comp, 'color', function() {
+ var c = scdl.color(comp);
+ return c == null? graph.colors.blue1 : graph.colors[c];
+ });
+};
+
+/**
+ * Return the services on the left side of a component.
+ */
+graph.lsvcs = function(comp) {
+ return memo(comp, 'lsvcs', function() {
+ var svcs = scdl.services(comp);
+ if (isNil(svcs))
+ return mklist(mklist("'element","'service","'attribute","'name",scdl.name(comp)));
+ var l = filter(function(s) {
+ var a = scdl.align(s);
+ var v = scdl.visible(s);
+ return (a == null || a == 'left') && v != 'false';
+ }, svcs);
+ if (isNil(l))
+ return mklist();
+ return mklist(car(l));
+ });
+};
+
+/**
+ * Return the references on the right side of a component.
+ */
+graph.rrefs = function(comp) {
+ return memo(comp, 'rrefs', function() {
+ return filter(function(r) {
+ var a = scdl.align(r);
+ var v = scdl.visible(r);
+ return (a == null || a == 'right') && v != 'false';
+ }, scdl.references(comp));
+ });
+};
+
+/**
+ * Return the height of a reference on the right side of a component.
+ */
+graph.rrefheight = function(ref, cassoc) {
+ return memo(ref, 'rheight', function() {
+ var target = assoc(scdl.target(ref), cassoc);
+ if (isNil(target))
+ return graph.tabsz * 8;
+ return graph.compclosureheight(cadr(target), cassoc);
+ });
+};
+
+/**
+ * Return the total height of the references on the right side of a component.
+ */
+graph.rrefsheight = function(refs, cassoc) {
+ if (isNil(refs))
+ return 0;
+ return graph.rrefheight(car(refs), cassoc) + graph.rrefsheight(cdr(refs), cassoc);
+};
+
+/**
+ * Return the height of a component node.
+ */
+graph.compheight = function(comp, cassoc) {
+ return memo(comp, 'height', function() {
+ var lsvcs = graph.lsvcs(comp);
+ var lsvcsh = Math.max(1, length(lsvcs)) * (graph.tabsz * 8) + (graph.tabsz * 4);
+ var rrefs = graph.rrefs(comp);
+ var rrefsh = graph.rrefsheight(rrefs, cassoc) + (graph.tabsz * 2);
+ return Math.max(lsvcsh, rrefsh);
+ });
+};
+
+/**
+ * Return the height of a component and the components wired to its bottom side.
+ */
+graph.compclosureheight = function(comp, cassoc) {
+ return memo(comp, 'closureheight', function() {
+ return graph.compheight(comp, cassoc);
+ });
+};
+
+/**
+ * Return the max width of the references on the right side of a component.
+ */
+graph.rrefswidth = function(refs, cassoc) {
+ if (isNil(refs))
+ return 0;
+ return Math.max(graph.rrefwidth(car(refs), cassoc), graph.rrefswidth(cdr(refs), cassoc));
+};
+
+/**
+ * Return the width of a component.
+ */
+graph.compwidth = function(comp, cassoc) {
+ return memo(comp, 'width', function() {
+ var ctw = graph.comptitlewidth(comp);
+ var rrefsw = (isNil(graph.rrefs(comp))? 0 : (graph.tabsz * 4));
+ var twidth = (graph.titlex * 2) + ctw + rrefsw;
+ var width = Math.max(twidth, (graph.tabsz * 8) + (graph.tabsz * 4));
+ return width;
+ });
+};
+
+/**
+ * Return a path representing a reference positioned to the right of a component.
+ */
+graph.rrefpath = function(ref, cassoc, path, maxheight) {
+ var height = graph.rrefheight(ref, cassoc);
+
+ // Record reference position in the path
+ var xpos = path.x;
+ var ypos = path.y;
+ path.refpos = cons(mklist(ref, graph.mkpath().pos(xpos, ypos + (graph.tabsz * 5))), path.refpos);
+
+ // Compute the reference path
+ return path.rline(0,graph.tabsz * 2).rcurve(0,graph.tabsz,-graph.tabsz,0).rcurve(-graph.tabsz,0,0,-graph.tabsz/2.0).rcurve(0,-graph.tabsz/2.0,-graph.tabsz,0).rcurve(-graph.tabsz,0,0,graph.tabsz/2.0).rline(0,graph.tabsz * 3).rcurve(0,graph.tabsz/2.0,graph.tabsz,0).rcurve(graph.tabsz,0,0,-graph.tabsz/2.0).rcurve(0,-graph.tabsz/2.0,graph.tabsz,0).rcurve(graph.tabsz,0,0,graph.tabsz).line(path.x, Math.min(ypos + height, maxheight));
+};
+
+/**
+ * Return a path representing a service positioned to the left of a component.
+ */
+graph.lsvcpath = function(svc, cassoc, path, minheight) {
+ var height = graph.tabsz * 8;
+
+ // Record service position in the path
+ var xpos = path.x;
+ var ypos = path.y;
+ path.svcpos = cons(mklist(svc, graph.mkpath().pos(xpos, ypos - (graph.tabsz * 6))), path.svcpos);
+
+ // Compute the service path
+ return path.rline(0, -(graph.tabsz * 2)).rcurve(0,-graph.tabsz,-graph.tabsz,0).rcurve(-graph.tabsz,0,0,graph.tabsz/2.0).rcurve(0,graph.tabsz/2.0,-graph.tabsz,0).rcurve(-graph.tabsz,0,0,-graph.tabsz/2.0).rline(0,-(graph.tabsz * 3)).rcurve(0,-graph.tabsz/2.0,graph.tabsz,0).rcurve(graph.tabsz,0,0,graph.tabsz/2.0).rcurve(0,graph.tabsz/2.0,graph.tabsz,0).rcurve(graph.tabsz,0,0,-graph.tabsz).line(path.x, Math.max(ypos - height, minheight));
+};
+
+/**
+ * Return a path representing a component node.
+ */
+graph.comppath = function(comp, cassoc) {
+
+ // Calculate the width and height of the component node
+ var width = graph.compwidth(comp, cassoc);
+ var height = graph.compheight(comp, cassoc);
+
+ /**
+ * Apply a path rendering function to a list of services or references.
+ */
+ function renderpath(x, f, cassoc, path, height) {
+ if (isNil(x))
+ return path;
+ return renderpath(cdr(x), f, cassoc, f(car(x), cassoc, path, height), height);
+ }
+
+ var path = graph.mkpath().move(graph.curvsz,0);
+
+ // Store the positions of services and references in the path
+ path.refpos = mklist();
+ path.svcpos = mklist();
+
+ // Render the references on the right side of the component
+ var rrefs = graph.rrefs(comp);
+ path = path.line(width - graph.curvsz,path.y).rcurve(graph.curvsz,0,0,graph.curvsz);
+ path = renderpath(rrefs, graph.rrefpath, cassoc, path, height - graph.curvsz);
+
+ // Render the references on the bottom side of the component
+ var boffset = graph.curvsz;
+ path = path.line(path.x,height - graph.curvsz).rcurve(0,graph.curvsz,graph.curvsz * -1,0).line(boffset, path.y);
+
+ // Render the services on the left side of the component
+ var lsvcs = graph.lsvcs(comp);
+ var loffset = graph.curvsz + (length(lsvcs) * (graph.tabsz * 8));
+ path = path.line(graph.curvsz,path.y).rcurve(graph.curvsz * -1,0,0,graph.curvsz * -1).line(path.x, loffset);
+ path = renderpath(lsvcs, graph.lsvcpath, cassoc, path, graph.curvsz);
+
+ // Close the component node path
+ path = path.line(0,graph.curvsz).rcurve(0,graph.curvsz * -1,graph.curvsz,0);
+
+ return path.end();
+};
+
+/**
+ * Return the position of a component.
+ */
+graph.comppos = function(comp, pos) {
+ var x = scdl.x(comp);
+ var y = scdl.y(comp);
+ return graph.mkpath().pos(x != null? Number(x) + graph.palcx : pos.x, y != null? Number(y) : pos.y);
+};
+
+/**
+ * Return a path representing a button node.
+ */
+graph.buttonpath = function(t) {
+ var path = graph.mkpath().move(graph.curvsz,0);
+ path = path.line(graph.buttoncx - graph.curvsz,path.y).rcurve(graph.curvsz,0,0,graph.curvsz);
+ path = path.line(path.x,graph.buttoncy - graph.curvsz).rcurve(0,graph.curvsz,-graph.curvsz,0).line(graph.curvsz, path.y);
+ path = path.line(graph.curvsz,path.y).rcurve(-graph.curvsz,0,0,-graph.curvsz).line(path.x, graph.curvsz);
+ path = path.line(0,graph.curvsz).rcurve(0,-graph.curvsz,graph.curvsz,0);
+ return path.end();
+};
+
+/**
+ * Render a SCDL composite into a list of component nodes.
+ */
+graph.composite = function(compos, pos, aspalette) {
+ var name = scdl.name(scdl.composite(compos));
+ var comps = scdl.components(compos);
+ var cassoc = scdl.nameToElementAssoc(comps);
+ var proms = scdl.promotions(compos);
+
+ // Unmemoize any memoized info about components and their references.
+ map(function(c) {
+ unmemo(c);
+ map(function(r) {
+ unmemo(r);
+ }, scdl.references(c));
+ }, comps);
+
+ /**
+ * Render a component.
+ */
+ function rendercomp(comp, cassoc, pos) {
+
+ /**
+ * Render the references on the right side of a component.
+ */
+ function renderrrefs(refs, cassoc, pos, gcomp) {
+
+ /**
+ * Render a reference on the right side of a component.
+ */
+ function renderrref(ref, cassoc, pos, gcomp) {
+ var target = assoc(scdl.target(ref), cassoc);
+ if (isNil(target))
+ return null;
+
+ // Render the component target of the reference
+ return rendercomp(cadr(target), cassoc, pos);
+ }
+
+ /**
+ * Move the rendering cursor down below a reference.
+ */
+ function rendermove(ref, cassoc, pos) {
+ return pos.clone().rmove(0, graph.rrefheight(ref, cassoc));
+ }
+
+ if (isNil(refs))
+ return mklist();
+
+ // Return list of (ref, comp rendering) pairs
+ var grefcomp = renderrref(car(refs), cassoc, pos, gcomp);
+ return cons(mklist(car(refs), grefcomp), renderrrefs(cdr(refs), cassoc, rendermove(car(refs), cassoc, pos), gcomp));
+ }
+
+ // Compute the component shape
+ var gcomp = graph.compnode(comp, cassoc, pos);
+
+ // Render the components wired to the component references
+ var rrefs = graph.rrefs(comp);
+ var rpos = graph.mkpath().rmove(graph.compwidth(comp, cassoc), 0);
+ var grrefs = renderrrefs(rrefs, cassoc, rpos, gcomp);
+
+ // Store list of (ref, pos, component rendering) triplets in the component
+ function refposgcomp(refpos, grefs) {
+ if (isNil(refpos))
+ return mklist();
+
+ // Append component rendering to component
+ var gref = cadr(car(grefs));
+ if (gref != null)
+ gcomp.appendChild(gref);
+ return cons(mklist(car(car(refpos)), cadr(car(refpos)), gref), refposgcomp(cdr(refpos), cdr(grefs)));
+ }
+
+ gcomp.refpos = refposgcomp(gcomp.refpos, grrefs);
+
+ return gcomp;
+ }
+
+ /**
+ * Render a list of promoted service components.
+ */
+ function renderproms(svcs, cassoc, pos) {
+
+ /**
+ * Return the component promoted by a service.
+ */
+ function promcomp(svc, cassoc) {
+ var c = assoc(scdl.promote(svc), cassoc);
+ if (isNil(c))
+ return mklist();
+ return cadr(c);
+ }
+
+ /**
+ * Move the rendering cursor down below a component.
+ */
+ function rendermove(comp, cassoc, pos) {
+ return pos.clone().rmove(0, graph.compclosureheight(comp, cassoc) + Math.max((graph.tabsz * 2), 8));
+ }
+
+ if (isNil(svcs))
+ return mklist();
+
+ // Render the first promoted component in the list
+ // then recurse to render the rest of the list
+ var comp = promcomp(car(svcs), cassoc);
+ if (isNil(comp))
+ return renderproms(cdr(svcs), cassoc, rendermove(car(svcs), cassoc, pos));
+
+ var cpos = graph.comppos(comp, pos);
+ return cons(rendercomp(comp, cassoc, cpos), renderproms(cdr(svcs), cassoc, rendermove(comp, cassoc, cpos)));
+ }
+
+ // Render the promoted service components
+ var rproms = renderproms(proms, cassoc, pos.clone().rmove(graph.tabsz * 4, graph.tabsz * 4));
+
+ if (aspalette) {
+
+ // Prefix ids of palette component elements with 'palette:' and
+ // move them to the palette area
+ return map(function(r) {
+ r.id = 'palette:' + r.id;
+ var gpos = r.pos;
+ graph.move(r, graph.mkpath().pos(gpos.x - graph.palcx, gpos.y));
+ return r;
+ }, rproms);
+
+ } else {
+
+ // Link app component elements to the containing composite
+ return map(function(r) { r.compos = compos; return r; }, rproms);
+ }
+};
+
+/**
+ * Return a component unique id.
+ */
+graph.ucid = function(prefix, compos1, compos2, clone) {
+
+ // Build an assoc list keyed by component name
+ var comps = map(function(c) { return mklist(scdl.name(c), c); }, append(namedElementChildren("'component", compos1), namedElementChildren("'component", compos2)));
+
+ if (!clone && isNil(assoc(prefix, comps)))
+ return prefix;
+
+ /**
+ * Find a free component id.
+ */
+ function ucid(p, id) {
+ if (isNil(assoc(p + id, comps)))
+ return p + id;
+ return ucid(p, id + 1);
+ }
+
+ /**
+ * Remove trailing digits from a prefix.
+ */
+ function untrail(p) {
+ if (p.length < 2 || p[p.length - 1] < '0' || p[p.length - 1] > '9')
+ return p;
+ return untrail(p.substring(0, p.length - 1));
+ }
+
+ return ucid(prefix == ''? 'comp' : (clone? untrail(prefix) : prefix), 1);
+};
+
+/**
+ * Clone a palette component node.
+ */
+graph.clonepalette = function(e, compos) {
+
+ // Clone the SCDL component and give it a unique name
+ var wcomp = append(mklist(element, "'component", mklist(attribute, "'name", graph.ucid(scdl.name(e.comp), compos, compos, true))),
+ filter(function(c) { return !(isAttribute(c) && attributeName(c) == "'name")}, elementChildren(e.comp)));
+ var x = '<composite>' + writeXML(mklist(wcomp), false) + '</composite>';
+ var rcompos = scdl.composite(readXML(mklist(x)));
+ var comp = car(scdl.components(mklist(rcompos)));
+
+ // Update component position
+ setElement(comp, graph.movecomp(comp, graph.abspos(e).rmove(graph.palcx, 0)));
+
+ return comp;
+};
+
+/**
+ * Move a SCDL component to the given position.
+ */
+graph.movecomp = function(comp, pos) {
+ if (isNil(pos))
+ return append(mklist(element, "'component"),
+ filter(function(e) { return !(isAttribute(e) && (attributeName(e) == "'x" || attributeName(e) == "'y")); }, elementChildren(comp)));
+ return append(mklist(element, "'component", mklist(attribute, "'x", '' + (pos.x - graph.palcx)), mklist(attribute, "'y", '' + pos.y)),
+ filter(function(e) { return !(isAttribute(e) && (attributeName(e) == "'x" || attributeName(e) == "'y")); }, elementChildren(comp)));
+};
+
+/**
+ * Align a pos along a 10pixel grid.
+ */
+graph.gridsnap = function(x) {
+ return Math.round(x / 10) * 10;
+}
+
+/**
+ * Clone a component node and all the components it references.
+ */
+graph.clonecomp = function(e, compos) {
+
+ // Write the component and the components it references to XML
+ function collectcomp(e) {
+ function collectrefs(refpos) {
+ if (isNil(refpos))
+ return mklist();
+ var r = car(refpos);
+ var n = caddr(r);
+ if (isNil(n))
+ return collectrefs(cdr(refpos));
+ return append(collectcomp(n), collectrefs(cdr(refpos)));
+ }
+
+ return cons(e.comp, collectrefs(e.refpos));
+ }
+
+ var allcomps = collectcomp(e);
+ var ls = map(function(e) { return writeXML(mklist(e), false); }, allcomps);
+ var x = '<composite>' + writeStrings(ls) + '</composite>';
+
+ // Read them back from XML to clone them
+ var rcompos = scdl.composite(readXML(mklist(x)));
+ var comps = scdl.components(mklist(rcompos));
+
+ // Give them new unique names
+ map(function(e) {
+
+ // Rename each component
+ var oname = scdl.name(e);
+ var name = graph.ucid(oname, compos, rcompos, true);
+ setElement(e, append(mklist(element, "'component", mklist(attribute, "'name", name)),
+ filter(function(c) { return !(isAttribute(c) && attributeName(c) == "'name")}, elementChildren(e))));
+
+ // Refactor references to the component
+ map(function(c) { return graph.refactorrefs(scdl.references(c), oname, name); }, comps);
+ }, comps);
+
+ // Update the top component position
+ var comp = car(comps);
+ setElement(comp, graph.movecomp(comp, graph.abspos(e).rmove(10, 10)));
+
+ return comps;
+};
+
+/**
+ * Sort elements of a composite.
+ */
+graph.sortcompos = function(compos) {
+ return append(mklist(element, "'composite"), elementChildren(compos).sort(function(a, b) {
+
+ // Sort attributes, place them at the top
+ var aa = isAttribute(a);
+ var ba = isAttribute(b);
+ if (aa && !ba) return -1;
+ if (!aa && ba) return 1;
+ if (aa && ba) {
+ var aan = attributeName(a);
+ var ban = attributeName(b);
+ if (aan < ban) return -1;
+ if (aan > ban) return 1;
+ return 0;
+ }
+
+ // Sort elements, place services before components
+ var aen = elementName(a);
+ var ben = elementName(b);
+ if (aen == "'service" && ben == "'component") return -1;
+ if (aen == "'component" && ben == "'service") return 1;
+ var an = scdl.name(a);
+ var bn = scdl.name(b);
+ if (an < bn) return -1;
+ if (an > bn) return 1;
+ return 0;
+ }));
+}
+
+/**
+ * Add a list of components to a SCDL composite. The first
+ * component in the list is a promoted component.
+ */
+graph.addcomps = function(comps, compos) {
+ var comp = car(comps);
+ var name = scdl.name(comp);
+ var prom = mklist(element, "'service", mklist(attribute, "'name", name), mklist(attribute, "'promote", name));
+ return append(mklist(element, "'composite"), append(elementChildren(compos), cons(prom, comps)));
+};
+
+/**
+ * Remove a component from a SCDL composite.
+ */
+graph.removecomp = function(comp, compos) {
+ var name = scdl.name(comp);
+ return append(mklist(element, "'composite"),
+ filter(function(c) { return !(isElement(c) && scdl.name(c) == name); }, elementChildren(compos)));
+};
+
+/**
+ * Garbage collect components not referenced or promoted.
+ */
+graph.gcollect = function(compos) {
+
+ // List the promoted components
+ var proms = map(function(s) { return mklist(scdl.promote(s), true); }, scdl.promotions(mklist(compos)));
+
+ // List the referenced components
+ var refs = reduce(function(a, comp) {
+ return append(a,
+ map(function(ref) { return mklist(scdl.target(ref), true); }, filter(function(ref) { return scdl.target(ref) != null; }, scdl.references(comp))));
+ }, mklist(), scdl.components(mklist(compos)));
+
+ // Filter out the unused components
+ var used = append(proms, refs);
+ return append(mklist(element, "'composite"),
+ filter(function(c) { return !(isElement(c) && elementName(c) == "'component" && isNil(assoc(scdl.name(c), used))); }, elementChildren(compos)));
+}
+
+/**
+ * Clone and cleanup clonable references.
+ */
+graph.clonerefs = function(compos) {
+ return append(mklist(element, "'composite"),
+ map(function(c) {
+ if (elementName(c) != "'component")
+ return c;
+
+ // If the references are clonable
+ var refs = scdl.references(c);
+ if (isNil(refs))
+ return c;
+ if (scdl.clonable(car(refs)) != 'true')
+ return c;
+
+ // Filter out the unwired references and add a fresh unwired
+ // reference at the end of the list
+ var cc = append(
+ filter(function(e) { return !(elementName(e) == "'reference" && scdl.target(e) == null); }, elementChildren(c)),
+ mklist(mklist(element, "'reference", mklist(attribute, "'name", scdl.name(car(refs))), mklist(attribute, "'clonable", "true"))));
+ return append(mklist(element, "'component"), cc);
+
+ }, elementChildren(compos)));
+}
+
+/**
+ * Refactor references to a component.
+ */
+graph.refactorrefs = function(refs, oname, nname) {
+ if (isNil(refs))
+ return true;
+ var ref = car(refs);
+ if (scdl.target(ref) != oname)
+ return graph.refactorrefs(cdr(refs), oname, nname);
+
+ // Change the reference's target attribute
+ setElement(ref, append(mklist(element, "'reference"),
+ append(filter(function(e) { return !(isAttribute(e) && attributeName(e) == "'target"); }, elementChildren(ref)),
+ mklist(mklist(attribute, "'target", nname)))));
+
+ return graph.refactorrefs(cdr(refs), oname, nname);
+};
+
+/**
+ * Rename a component.
+ */
+graph.renamecomp = function(comp, compos, name) {
+
+ // Refactor all the references to the renamed component
+ var oname = scdl.name(comp);
+ map(function(c) { return graph.refactorrefs(scdl.references(c), oname, name); }, namedElementChildren("'component", compos));
+
+ // Rename the SCDL promoted service and component
+ var proms = filter(function(s) { return scdl.name(s) == oname }, scdl.services(compos));
+ if (!isNil(proms))
+ setElement(car(proms), mklist(element, "'service", mklist(attribute, "'name", name), mklist(attribute, "'promote", name)));
+ setElement(comp, append(mklist(element, "'component"),
+ cons(mklist(attribute, "'name", name),
+ filter(function(e) { return !(isAttribute(e) && attributeName(e) == "'name"); }, elementChildren(comp)))));
+
+ return append(mklist(element, "'composite"), elementChildren(compos));
+};
+
+/**
+ * Cut the wire to a component node and make that node a
+ * top level component node.
+ */
+graph.cutwire = function(node, compos, g) {
+
+ /**
+ * Find the reference wired to a node and cut its wire.
+ */
+ function cutref(refs, node) {
+ if (isNil(refs))
+ return true;
+ var ref = car(refs);
+ if (caddr(ref) == node) {
+ setlist(ref, mklist(car(ref), cadr(ref), null));
+ setElement(car(ref),
+ append(mklist(element, "'reference"),
+ filter(function(e) { return !(isAttribute(e) && attributeName(e) == "'target"); }, elementChildren(car(ref)))));
+ }
+ return cutref(cdr(refs), node);
+ }
+
+ // Cut any reference wire, if found
+ cutref(node.parentNode.refpos, node);
+
+ // Make the component node a top level node.
+ node.compos = g.compos;
+
+ // Update the SCDL composite, add a promote element for
+ // that component
+ var comp = node.comp;
+ var name = scdl.name(comp);
+ var prom = mklist(element, "'service", mklist(attribute, "'name", name), mklist(attribute, "'promote", name));
+ return append(mklist(element, "'composite"),
+ append(mklist(prom), filter(function(c) { return !(isElement(c) && elementName(c) == "'service" && scdl.name(c) == name); }, elementChildren(compos))));
+}
+
+/**
+ * Wire a component to the closest neighbor reference.
+ */
+graph.wire = function(n, compos, g) {
+
+ // Compute position of the component's service node
+ var spos = cadr(car(n.svcpos));
+ var aspos = graph.abspos(n).rmove(spos.x, spos.y);
+
+ /**
+ * Find closest unwired reference node among all the references
+ * of all the components.
+ */
+ function closecomprefs(nodes, spos, cref) {
+
+ /**
+ * Find the closest unwired reference node among all the
+ * references of a node.
+ */
+ function closerefs(npos, refs, spos, cref) {
+ if (isNil(refs))
+ return cref;
+ var fdist = cadddr(cref);
+ var ref = car(refs);
+
+ // Skip wired reference
+ if (!isNil(filter(function(n) { return isAttribute(n) && attributeName(n) == "'target"; }, car(ref))))
+ return closerefs(npos, cdr(refs), spos, cref);
+
+ // Compute distance between service node and reference node
+ var rpos = cadr(ref).clone().rmove(npos.x, npos.y);
+ var dx = Math.pow(rpos.x - spos.x, 2);
+ var dy = Math.pow(rpos.y - spos.y, 2);
+
+ // Check for proximity threshold
+ var rdist = (dx < (graph.proxcx * graph.proxcx) && dy < (graph.proxcy * graph.proxcy))? Math.sqrt(dx + dy) : 25000000;
+
+ // Go through all the references in the component
+ return closerefs(npos, cdr(refs), spos, fdist < rdist? cref : mklist(car(ref), cadr(ref), caddr(ref), rdist));
+ }
+
+ if (isNil(nodes))
+ return cref;
+
+ // Skip non-component nodes
+ var node = car(nodes);
+ if (isNil(node.comp))
+ return closecomprefs(cdr(nodes), spos, cref);
+
+ // Compute the component absolute position
+ var npos = graph.abspos(node);
+
+ // Go through all the components and their references
+ return closecomprefs(append(nodeList(node.childNodes), cdr(nodes)), spos, closerefs(npos, node.refpos, spos, cref));
+ }
+
+ // Find closest reference node
+ var cref = closecomprefs(nodeList(g.childNodes), aspos, mklist(null, graph.mkpath(), null, 25000000));
+ if (car(cref) == null)
+ return compos;
+ if (cadddr(cref) == 25000000)
+ return compos;
+
+ // Wire component to that reference, un-promote it, and
+ // update the SCDL reference and composite
+ setElement(n.comp, graph.movecomp(graph.dragging.comp, null));
+ n.compos = null;
+ setElement(car(cref), append(mklist(element, "'reference", mklist(attribute, "'target", scdl.name(n.comp))), elementChildren(car(cref))));
+ var name = scdl.name(n.comp);
+ return append(mklist(element, "'composite"),
+ filter(function(c) { return !(isElement(c) && elementName(c) == "'service" && scdl.name(c) == name); }, elementChildren(compos)));
+}
+
+/**
+ * Display a list of graphical nodes.
+ */
+graph.display = function(nodes, g) {
+
+ // Append the nodes to the graphical canvas
+ appendNodes(nodes, g);
+ return nodes;
+};
+
+/**
+ * Hide a graph.
+ */
+graph.hide = function(g) {
+
+ // Remove nodes from the graph
+ map(function(n) { if (!isNil(n.comp) && n.id.substr(0, 8) != 'palette:') { g.removeChild(n); } return n; }, nodeList(g.childNodes));
+ return g;
+};
+
+/**
+ * Refresh a graph.
+ */
+graph.refresh = function(g) {
+ //debug('refresh');
+
+ // Remove existing nodes from the graph
+ map(function(n) { if (!isNil(n.comp) && n.id.substr(0, 8) != 'palette:') { g.removeChild(n); } return n; }, nodeList(g.childNodes));
+
+ // Redisplay the composite associated with the graph
+ var nodes = graph.composite(g.compos, graph.mkpath().pos(graph.palcx,0), false);
+ appendNodes(nodes, g);
+ return nodes;
+};
+
+/**
+ * Display and enable editing of a composite and the graphical
+ * nodes that represent it.
+ */
+graph.edit = function(appname, compos, nodes, g) {
+
+ // Store the composite elements, and sort them to allow for change detection later
+ g.compos = compos;
+ var scompos = scdl.composite(g.compos);
+ setElement(scompos, graph.sortcompos(scompos));
+
+ // Remove existing nodes from the graph
+ map(function(n) { if (!isNil(n.comp) && n.id.substr(0, 8) != 'palette:') { g.removeChild(n); } return n; }, nodeList(g.childNodes));
+
+ // Display the composite nodes
+ appendNodes(nodes, g);
+ return nodes;
+};
+
+/**
+ * Track the composition graph, whether it's visible or not and the selected component.
+ */
+var gvisible = true;
+var gcomp = null;
+var cdiv = $('contentdiv');
+var pdiv = $('playdiv');
+var graphdiv = $('graphdiv');
+
+/**
+ * Track the palettes.
+ */
+var gpalettes = new Array();
+var spalette = 'control';
+var bpalette = null;
+
+/**
+ * Get and display an application composite.
+ */
+function getapp(name, g) {
+ if (isNil(name))
+ return false;
+ showStatus('Loading');
+
+ return composites.get(name, function(doc) {
+
+ // Stop now if we didn't get a composite
+ if (doc == null) {
+ showError('App not available');
+ return false;
+ }
+
+ // Get the composite from the ATOM entry
+ var composentry = car(atom.readATOMEntry(mklist(doc)));
+ var content = namedElementChild("'content", composentry);
+ composite = isNil(content)? mklist() : elementChildren(content);
+ if (isNil(composite)) {
+
+ // Create a default empty composite if necessary
+ var x = '<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" ' +
+ 'targetNamespace="http://app" name="app"></composite>';
+ composite = readXML(mklist(x));
+ }
+
+ // Display the composite
+ graph.edit(name, composite, graph.composite(composite, graph.mkpath().move(graph.palcx,0), false, g), g);
+
+ // Track the saved composite XML
+ savedcomposxml = car(writeXML(composite, false));
+
+ // Enable author to edit the composite
+ author = elementValue(namedElementChild("'author", composentry));
+ editable = author == username;
+ cadd.disabled = !editable;
+ showStatus(editable? onlineStatus() : 'Read only');
+ return true;
+ });
+}
+
+/**
+ * Display a palette. Get it from the server if needed.
+ */
+function displaypalette(name, g, palette, gpalettes) {
+ if (isNil(name))
+ return;
+ if (isNil(gpalettes[name])) {
+
+ // Get the palette from the server
+ palettes.get(name, function(doc) {
+ var entry = car(atom.readATOMEntry(mklist(doc)));
+ var content = namedElementChild("'content", entry);
+ var compos = isNil(content)? mklist() : elementChildren(content);
+ gpalettes[name] = graph.composite(compos, graph.mkpath().move(2580,0), true, g);
+ graph.display(gpalettes[name], g);
+ });
+ return true;
+ }
+ graph.display(gpalettes[name], g);
+ return true;
+}
+
+/**
+ * Install a palette, including a button to select the palette, and
+ * the palette content.
+ */
+function installpalette(name, pos, g, bg, palette, gpalettes) {
+ var b = graph.mkbutton(name, pos);
+ graph.display(mklist(b), g);
+ b.onclick = function(e) {
+
+ // Swap the selected palette
+ graph.paletteselect(bpalette, false);
+ displaypalette(spalette, bg, palette, gpalettes);
+ bpalette = b;
+ graph.paletteselect(b, true);
+ spalette = name;
+ return displaypalette(spalette, g, palette, gpalettes);
+ };
+
+ if (name != spalette) {
+
+ // Will get the palette from the server later if needed
+ gpalettes[name] = null;
+ return true;
+ }
+
+ // Display the selected palette
+ graph.paletteselect(b, true);
+ displaypalette(name, g, palette, gpalettes);
+
+ return b;
+}
+
+/**
+ * Save the current composite.
+ */
+function save(savexml) {
+ showStatus('Saving');
+ savedcomposxml = savexml;
+ var entry = '<?xml version="1.0" encoding="UTF-8"?>\n' + '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ '<title type="text">' + appname + '</title><id>' + appname + '</id><author><email>' + author + '</email></author>' +
+ '<content type="application/xml">' + savedcomposxml + '</content></entry>';
+ composites.put(appname, entry, function(e) {
+ if (e) {
+ showStatus('Local copy');
+ return false;
+ }
+ showStatus('Saved');
+ return false;
+ });
+ return true;
+}
+
+/**
+ * Handle a composite change event.
+ */
+function oncomposchange(prop) {
+ if (!editable)
+ return false;
+
+ var newxml = car(writeXML(composite, false));
+ if (savedcomposxml == newxml)
+ return false;
+ showStatus('Modified');
+
+ // Save property changes right away
+ if (prop)
+ return save(newxml);
+
+ // Autosave other changes after 1 second
+ showStatus('Modified');
+ setTimeout(function() {
+ if (savedcomposxml == newxml) {
+ showStatus('Saved');
+ return false;
+ }
+ return save(newxml);
+ }, 1000);
+ return true;
+}
+
+/**
+ * Return the link to a component.
+ */
+function complink(appname, cname) {
+ if (cname == '' || isNil(cname))
+ return '';
+ var protocol = location.protocol;
+ var host = location.hostname;
+ var port = ':' + location.port;
+ if (port == ':80' || port == ':443' || port == ':')
+ port = '';
+ var link = protocol + '//' + host + port + '/' + appname + '/c/' + cname;
+ return link;
+}
+
+/**
+ * Handle a component select event.
+ */
+function oncompselect(gsel) {
+ if (gsel == gcomp)
+ return true;
+ gcomp = gsel;
+
+ cdelete.disabled = isNil(gsel) || !editable;
+ ccopy.disabled = isNil(gsel) || !editable;
+ cplay.disabled = isNil(gsel);
+ return true;
+}
+
+/**
+ * Show the result data of a component.
+ */
+function showdata(gcomp) {
+ if (!gvisible)
+ return true;
+ if (isNil(gcomp))
+ return true;
+ cvalue.value = complink(appname, gcomp.id);
+ cplay.value = '<';
+ gvisible = false;
+ pdiv.innerHTML = '';
+ pdiv.style.visibility = 'visible';
+
+ // Get the component result data
+ var comp = sca.component(gcomp.id, appname);
+ comp.get('', function(doc) {
+ function displaydata(t, w) {
+ pdiv.style.width = w;
+ pdiv.innerHTML = t;
+ return true;
+ }
+
+ // Stop now if we didn't get the doc
+ if (doc == null)
+ return displaydata('No content', '2500px');
+
+ // Format data table
+ if (json.isJSON(mklist(doc)))
+ return displaydata(ui.datatable(json.readJSON(mklist(doc))), '2500px');
+
+ if (atom.isATOMEntry(mklist(doc)))
+ return displaydata(ui.datatable(atom.readATOMEntry(mklist(doc))), '2500px');
+
+ if (atom.isATOMFeed(mklist(doc)))
+ return display(ui.datatable(atom.readATOMFeed(mklist(doc))), '2500px');
+
+ // Insert the doc as is in an iframe
+ var t = '<table class="datatable" style="width: 100%;">' +
+ '<tr><td class="datatdltop">' + 'value' + '</td>' + '<td class="datatdr">' +
+ '<iframe style="width: 100%; height: 5000px;" scrolling="no" frameborder="0" src="' + clink + '"/>' +
+ '</td></tr></table>'
+ return displaydata(t, '100%');
+ });
+
+ setTimeout(function() {
+ graphdiv.style.visibility = 'hidden'
+ }, 0);
+ return true;
+}
+
+/**
+ * Show the composition graph.
+ */
+function showgraph(gcomp) {
+ if (gvisible)
+ return true;
+ cplay.value = '>';
+ graphdiv.style.visibility = 'visible'
+ gvisible = true;
+ graph.compselect(gcomp, true, atitle, cvalue, ccopy, cdelete);
+ setTimeout(function() {
+ pdiv.style.visibility = 'hidden';
+ pdiv.innerHTML = '';
+ }, 0);
+ return true;
+}
+
+/**
+ * Handle play component button event.
+ */
+cplay.onclick = function() {
+ if (gcomp == null)
+ return false;
+ if (!gvisible)
+ return showgraph(gcomp);
+ return showdata(gcomp);
+}
+
+/**
+ * Create editor graph area.
+ */
+graph.mkedit(graphdiv, graph.mkpath().move(-2500,0), atitle, cvalue, cadd, ccopy, cdelete, oncomposchange, oncompselect);
+
+/**
+ * Install the palettes.
+ */
+var bg = graph.mkgroup(graph.mkpath());
+var pos = graph.mkpath().move(0, 0);
+bpalette = installpalette('control', pos.rmove(5,2), graphdiv, bg, spalette, gpalettes);
+installpalette('values', pos.rmove(0,28), graphdiv, bg, spalette, gpalettes);
+installpalette('lists', pos.rmove(0, 28), graphdiv, bg, spalette, gpalettes);
+installpalette('transform', pos.rmove(0, 28), graphdiv, bg, spalette, gpalettes);
+installpalette('text', pos.rmove(0, 28), graphdiv, bg, spalette, gpalettes);
+installpalette('http', pos.rmove(0, 28), graphdiv, bg, spalette, gpalettes);
+installpalette('animation', pos.rmove(0, 28), graphdiv, bg, spalette, gpalettes);
+installpalette('talk', pos.rmove(0, 28), graphdiv, bg, spalette, gpalettes);
+installpalette('social', pos.rmove(0, 28), graphdiv, bg, spalette, gpalettes);
+installpalette('search', pos.rmove(0, 28), graphdiv, bg, spalette, gpalettes);
+installpalette('database', pos.rmove(0, 28), graphdiv, bg, spalette, gpalettes);
+installpalette('logic', pos.rmove(0, 28), graphdiv, bg, spalette, gpalettes);
+installpalette('math', pos.rmove(0, 28), graphdiv, bg, spalette, gpalettes);
+installpalette('python', pos.rmove(0, 28), graphdiv, bg, spalette, gpalettes);
+
+/**
+ * Get and display the current app.
+ */
+getapp(appname, graphdiv);
+
+})();
+</script>
+
+</div>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/home/home.b64 b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/home/home.b64
new file mode 100644
index 0000000000..9131135881
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/home/home.b64
@@ -0,0 +1 @@
+iVBORw0KGgoAAAANSUhEUgAAAaoAAACRCAIAAAAdJ2t7AAAgAElEQVR42u2d+1NT1/r/99/AD2f68ZfjOOOFGXFwhoLScqgow2E+IAylGUqDCAlBwFgU6yUwMkVyKnKGD7anSvVrcWwZLziVFioUiQJCzIWQkHATwrXCEVQUBP1Uz6d+n7XXTtgJm5ug3J5n3tMuHtfaa+2tefE8a629wrxGQ0NDW5HG4CNAQ0ND/KGhoaEh/tDQ0NAQf2hoaGiIPzQ0NDTEHxoaGhriDw0NDQ3xh4aGhob4Q0NDQ0P8oaGhoSH+0NDQ0BB/aGhoaMsSfy9fvhwbGxsdHX2G9tYMHi88ZHjUS+75L92R4/NchPe4iPA3MNyhsV4pbzz1q/mr4oZM1FsSPN5yS6763qX23obBwcHnz5/T5/981DrQ90NfV9b9zmP3O1MXpWBgWX09F/vvG/kjb3nyNK/5nsJg3KczJGnrUDMUPC5FnfGMpVnf3ePwL2GoZbAxr1+r6Ffv669NWtqCW4AbaTjT36Xn3+Piwl/rv6tKzEpk07sUPHBjR3l/f//w8PDTxxX3O9MWK/UmKq2v9wYdeUnv/b1IvbkJHuD1e230eQ73lPSr9y556glwcG9/y3V6j4sLfxD32dlXYs4sa838rS2zvF2JekuCxwsPGR41PHaIAXu67va0HaVk6e9Kfdyf+nQgdXhwMQoGBsODQQIBIQa8025NUOu4j7HOkGC0JDQ0JZibUTMVPC6jBR4dEBBiwJ62O73VCZQXD9RJT/QJI4aEZ/VLW3ALcCNwO4SAXXog4NxjwPnEH+S8lH1lrcrb9zMr+5SodyB41PDASRbccrqj+SCwD8jyn1HF/40tdsEgYaiQBWdr66TVtcC+RKNF1tYpa+9CvYnaOuEBQhZsvZvdeUsK7HuiT/yzSfa6efkIbgduimTB/f2QBS8W/L18+bK88RSN+5B9C0DAhv9pb063Nqfc7zy6JNhnJ2CP9cT+O2pJVU2Ctg7ZN3cCKrQG6+39nSpJf03CMmOfnYAPdIp+1ua4EjJv+BsbG6NrHZCOTftxVdXHfRYXVNCB5JpEPYcPy33/UXts5k1KGr5qbzoE+BvoPbyQRBved/6gd5Hl4Myb3O84JquqAfzJ6oz2j7G4MNd1x1aXLYnhjXPCgbT2qvvu9IjGhWk+hew3GHYLujgGXUhrCmhhjlfepzV0qGSAv4d3x5HxoibCqpHOFjRv1uod6EmdnOIPsLMo8Dc6Okoz39/apsdfaVkQw7x3ug1JN4naktYwTHxZ2izwZ84E9oEe3j+0kPgbiHVjmBO1B2bepL87TcLiT2ow2T7DdV4Mw6yP9ErLnSMOYorSGWZDqGlhmk+u8Rv8+HomlKCLmKJjtDDHi+/VGYB9oMd2chnDQxgm43L07CjzZq3eiUYMCRR/gJ1Fgb9nz55R/JW3T/9ZLVXBg3X9vgfKx1U9yDvH0BgeSE/yhwwjnw3+fjUrKf4e9S1Y9PfHMER/8fBXm/tG+Iurb7B9hitdGca7pHXuoIkpUTKMf3hLl6ylXfqGzbeGzT/+BG4wpgQ4uCVsHvBXT/E3pI3jeGEhIDtVJJkdZd6s1TvRs3oOf4CdRYm/nuTPXN+L/+kwG8vIw13fi81PIeWOZCjv/3//Db/8wuXvM6z5p+4uZT/DxVVR/q7U9568IBk85bVRH7q6xx50rmkXW8E1PM6dVvjsX0kq1n+xIGQzw9haRRWzzis/cc41YR8Ee7/32dkUwU6dVFT2qb1CfL58ik5nPn7BTq9c5Ya3OeA9+O+BOeOvqSjwI9tD+Czzk0djijHLJyEb132+dyN1HsmP/WMSJzR/VP/JZ5zvL7lF8f/H1dz4Zdpm2zUjnrI1u37lOvoo6C/w3zNzwV9jhZttzGszSsEjOq9cZfccOhfNfsijik6vXU99W30uVtJPfnTZOZtzg/f5Chu/GNfdodTrkVMsdW6+wSuvVDaJk4e/xoDPQyFe26lt57NGojq3er2/m+367uz1WefWtSFbSdc5Fc6XdbxBScXp/1ofE25ywN/EG5kD/mIKgrnukrNF4BkqCRCvow6XU2fBIy2Vr2Y83Q16Qhbrtx4Ms/rnil1OrRB/s4r+vkwLYxhxFHChuPjv5CmGicq5tHfN/xSFEI/rBzmq5K//5QtFueqYqn43ZHyb5R9frP+COuN/UrBxIhipmZPzAYGC6tiEQBIu5Xtad/js2R1QjL16uLyKOINPxF6p/+J0PukdEsnSKhEUPkyNKtDJD8cRvnyYkSTYqQNe2VZr4j6+qEvJOUEG8FnBF4Kdznz8gjXLecOTB5A2U0R/5R3KYvNxUHnHpPgbqw+Ei8i+juyyJqmv+jFsTvpUR5zMRm916z59wd+g+OWv+wSdf1gj4FP60cGgJmtSVb43aX4zmavJeN7Uxd/M8ySk0x0cqyf3GJL5SVurNDeI/PEU0d+zh4r+LiIoTBL9tUZcIsxyO1EgqmqUlLH8yiiIrK0JzTsCZa8ik0x7wQU+u7uzRVWVgYf8ye+VqnZpLXGu2pMtqq3ZmZNIal6qo/hj1ifuLKukTo+LdZKyXMbWPCgjlmDrfI2gkwseG03+u8ll/EpMQuEhuX5olSbsm/3s9TWck4n1zUjfnvfVhMve4t9gTAnkvFtCefgTvJHJYLfH0pKoM4CgMFn013eZ/BuTpQdaaySvKgM3Mcw2mW9LZWR1Nvn9nfVD1GvNTvJXuCtgsIL8y9umCHVqhfibdfJ7rQAen3tBn/L0wTXsv4b3L5Iy4eDPLBT+UU9rHv4MUHU25fsTEA6tOalLKzYriptT4r3Ha57k1XSaESt1qHD8yzDSqrTti6+vJhX3KMvb0q6UfbqGRcnZjDWMa1Ax1zAZfrdtzkgS7LScd33SivG9wv14/B9i+CwG/STU6XczHr9gp9+Sjv7ODa9DPkXya7yX3dZ0GFSt/+pK1fFfjMcF8ffHQFLVr7GPhhVjAwe6asPcWCpRft2wUvQcuRrBMBEhA0JO3dcQIfz1RuuBR93Jj/oSTvxtYs19R1ik6rP/CmR4RAH3WDpF8nu9qTCxuhr0490Ckz6t15omnPy2lK625YZSU83Oi8XRLV0Skymy6DRwwbvIFJ4ByIuN5BCgCTiRG65tZ51bA6tM0dq66LpKry2A5NxdLIkCamnNdj8Y3I7snWkQlyXamrcHwP2uTxd0itnmq7Yw7JXbJ8mOmUDb9f1DeJ1WEWeY0GVjeDdop569IHgjEiH2Fel/vKdKBF29dfbzctVejW7a5NecDj2vKq2IHqqJGtJEZMGvsGC/FxASXvbmgr1g3yFMfudh7q85Dj7QaSo5/MqLL4iCv9LDZUlQDi84zDJrzVlu6ePYYW9mTUbSxX+9z/DNFVLUj39yrHnAVRh/XzdzP17McSWM6zmcdtCdfzE5Bx3fIq7hl1N0ys+vv4cLMjtsrej1Q34S6vTMjMcv2OmZE/yOvpx4p/a4D8BHSQcFwB8InALJ7/C+H9M28vux46+qz5Yd561jNvp3Cznv5m92GORGxi0i6D6p+Vf9AK158MxGgj8TAeXfHnCMO0SdgnEfgI+SDgqAPxAJBifir7F4FYs5FoUav89D+QMBvygHPOkxjiwQ5UQ6DHg94xKSzfJrfO1CdMKfkA7+y+yPauc7laFCTjEXx7H9CoVgFH876xyuH8nGjGHsok240GVjeDc4EX+CNxIjFPcB+CjpoAD4A4FTAH/GsG0AsmtkEaMl29Xh4uuYTcG+I2yOzEbzTJ6dd7xWiL83WPo4dhhCadf3yCpHxzESIrGf9dPNSif8HfAmgRgbZ31gi7OUV8piTxanlDjWlAvj7z07iU7G0UAMLuX6D9UXpZAb9sg3s8n192x4ZeNLSjgzaacq5+hvHH8n5YwNf86dfjvj8Qt2mseP/iZf+oCEl2Kut/0g6KdqJeAPnDcbTzjhz/Q1BGXrinRJTx8DCqUfAf50B1n8/cVOuht77TGds7OWxHSeXTZ4ddVG3qhMeOyIv9yNE6K/yZc+IOGlmJPUakF3dUrAHzjbO76aAn/hGRA9+QeU1MQ0kqiQ+Esa2ZBqv5gDgcl/T6T3xRrWaQ8JuyKLCgILK6PZyTsb/tjojIv+xpEUuAcQoxR0Unru1JoCSfLrH1oniL8NdvyRalz0xy2YhAlddmr8Cd7IxHWbRNsK7/0qotSbNwB/4FTo1YL4o1wzKKBnt24bR7qvBZVejngFhW/t4YK71eLcCvH3Jiu/V/LJbBcTEALpZAENeegM4AT8QSDGTX4djLrSnFbwEwmv1qTuKZ0R/pg14pCC5rTv88k03GdXD7Oke//r+mPlbV98KSepd/C/klX1UWRVQS76vipJzrL4w0k6dbz+x+yU3O6iNu76kKcLdjrz8U9S82N2vjKuqO3wyVT3yeb++FHeo74vDMZMIGCxJtPSZPd/weGPUGlzlfXg2EDS1YN/JfM4+fE0+nOLDWzrO2C6Sqb5jtjm/pyc3Ixe2iddfQfabrIVMqOfCuHvqS6InWSMejCw70bmxsnm/vhRnsTQkKP+BQhobMg8pb/BYdEghD/CgsidtY0SU43/Hm4xQaIi83Rr0y5EmUyhOWRCzU/VSifvVn9+LrLORCfXXA5d56bhQpQRdaZwdurQnczNZZOah0jz8DwyYef6TeUkThZkjWRIa8l1cmOEoj+XCHr9/bbrj+NP8LKyKfEneCNTL3EMaSW3b2cBARVVN+/U/NPmt5FLHwogE6f4t1TGvCghs8Ah8oBuTbT1Bx8ob0oJ5SYEFWGAPPK3Lgt85dgK8fdGG1/MsRB5+eeQ1VJV7ad03YBdT4CPuisffx+ydQoKgtbYfgdtjhNd65lQczL82ScuMmLLybbq2GD7dcS+wRDvx0WR0En16Yes88O4Hf5kMIcFO3UizkV28YS/dCvY6azGL9jpRXYVhQ2RXdn5ymNT4+/50BFa5guc3NyfNVJm6+KjWG8ZcGnvJxzp/sb5ZdmRY2MKQSdcoa3I375G+dHekN+HFWP1QLp1TskvyZcLbI03rmMnGQ9Ojb+4pnsc8ngCpw1/pWttdJDWFtiztVURia7rGWb3OfBHnE+3/6W429Zzwelir7w7V9wCKMmm+SP3XDOu0poiFoW21eQLMZM42eb+FGRRl47Q9RAB/G2xXT+tQOLYSrgv3g2ylXew+OMKgjcyNf7+1xRHy3yB08aL6HyRCyUdWds9673JdvFtu/z6LFGnIO1d50FDwr6zHtx6iGMrxN+87fub8oWHL4ub00o7js+wPreFsEOpaksrdXiN5Hip43WuFPw9+GAUN6/XkbSZv4oybadchWk7nc34BWuyTtWMN7gM9H7BZx/86AidI0/7Djx9fMTuYUm3zvRY8cfAAZIUT+60TSAeeuR4hcnf9yA1/5jxBhep3shnH/w4+WaO9pg6U0zjhJWHltZo8LcIOSdUFrgCV7Nreue0+wobu6SmKVvN8rJT3MhkG1we3pXy2Qc/Or/CYZS8Gt/TJxnSRI8Yp3+jw6EV4u+t42+WmvkLJKpaEZt9+x448Xc2BnQ/3fzWO513TVzigHAPEl6QPe6bQk9rIer9i3pgeue8a+ISB4kBDSQRHo/7lpre2mshb7K9GcI9SHhBvLhveQrxZ4OaOelAxqdXZvb6cJEqNl7+QbD4/dgTn15sPv5uOl1U+PujO/ZMdljX4+mdiL8ZvRSsLfZJOx3ZiPhD/C0E/laanPB3r+PET9VKkMGYKZT8LiI54e+0peKuTgnKUf8yXfKLmh5/Wn1u6s0boNu3swSTX8Qf4m9Z4Q/CPbrxBQQFp6WPxYw/CPfoxhcQFJyXPlCzxB+Ee3TjCwgKE5Y+EH+Iv+WCP7rtGfA3cF9B2XftLpHTxpdFiD+67Rnwt9dYT9nXalaAnDe+oGaGP7rtGfA3oNtL2SevvANy3vhiU8u3XjKRu6rC5tdEFKZ7HZW5HZX7VJdxu1teaUSFCq+ju9wyFP5WvdMhCJF5MtfklMAReuxK2c58pW9Bth+R0rf0WhRbTdqS75chc0uWef18TQyewWuB49XYmgVnw8lyikZUoPBI3uV2NMXXUClB/KGmV7H5eLX+KyBgV9uRu+YTFH/gXAwnvkyDvy7Fj3cLgIBJavUVwyWKP/L+r8CJL6jplagzXL11FgjYVZVYWPM9xV8iOe9+wlsflFYl/nS/C/cihz5M7PD+B5NfFPPaGC5z8Nm2QLOqTmGPnvD0oW/FsTuo+W9WhQL7VCkOzrxr0YYUF8bZvIb0Th2tUtVIEX+oaVTewWW7fAm/9LbI9OyhgiKPL+GX3lAz0B5LC0UeX8IvvTVLDNnj74BS/HXnsns6Pb2sGnHhLsKsbSmhfflste0+3TXhR9lTYbJs5/2NFPlw7T192OhPwh4J43JU4Zuv9Dml8Cq8LH5dE8QS1qWwRGxQrqVM7Lvsf0rhk5fuk690t20sFY1cYzfNbvfuM0b/vIvwMSNfjPhDTa9fjA7sm+zIg0WoXqsD+yY98gA1w/xXo+Ozb9IjD/Shm3iBFsWf9ay3ePvqjG8jyeY+Fm0hirChsrBCpU9pCaSiUnrgFYc/S0Syvf12Fn+WCJaPLoVFkd0VYro3cDCfbJneJAsYaZYOloVVXw7v5p0W86LIlzaH4JHiL4Q9WkYjJ/BNZkeC+EPNKAac9sCrRRsDTnfgFWp2MeC0B169NoqydnkZasT5wbzkd1xRp7YTv1hpO9dPHyajBwJ6eg2yHhVLKLHcI8TGr9eandscste11ZVSg2I137VN5NM3njtHZbG4/LmCJrli9kdmk+cqFs2uZj3O/aHmbz/gUhHi723vB7QpJm/7BPxZxHnBztN8L0r8tjF0wm71zyUxQ9fYtFfk/6o5gkzYbfd9QWYS/QBbm7Z7qK6F5rG5MxPsp09fSyfysnIDTolWsZFgEA0M6YFam2SBNiLT4JFh1nEdlVZIEH8oxB/qbeEv3wl/RhHHIMbNoHFGTB+byTIiv9Pbac7rniXj6CaT+VqNvMoadsrP0+d2+mrKQfbEBDY89PQe4nWdV8StL7ewM4MhKTvJLCT7ljGzK/AV4g+F+EO9E/yxJx0QQnnYWdbCrpAcZafhhi57sX/qnes5YeWWcSk55yP2dJGlh5G9MmV+tGYnPTOVIq8mcJO9bAwnq8zrPPpsg6FpMk236cyjbUUF8YdC/KHecvJrzR0/93QTGwOGpIdxC7KMi0zmSldLknMjXuijhzTRQ/qYkcqgEHZCsFsvfUGRxzAyuQf95hByXpZFRLezbAt2E3sy9nPzuYlCHuAGKVsZl2S5RwjbXJwdgckvCvGHemvRX7Btf1+zpHCX83a8EBLKSTW8LTLJ6TtfOH71pdi+8tssNed62BeUxba90C8qgrhlE7igzH+Qt2mGrvPaJDVke4x3LQ8Ywm3PKMQf6q3hb+ZfcRnDHoc1k5oSNjB02rEsHSFOyZs2R/yhEH+ohcIfvvOL+EP8If4Qf4g/xB/iD/GH+EP8If4Qf4i/RY+/DpVsmePPKEf8oRB/qAn409dbb+8H/D3WLNsTT0caFBR/o6OjiD8U4g9lOwhLb7xXcxLwN6hettHfk9bvKP7GxsYQfyjEH4pTQr25sb68QyX5vTr+z6ZlyL4/m+Mf9Bgo/l6+fIn4QyH+UDb8mZubmpqaNRd6q/c80ScuMwIC+550lVD2DQ4OzpFaiD/EH+JvueGvs7PTbDZ3NFf3N5x5oFM8qZOPGBKe1S9lGeUjDQrIee1xH9jz588RfyjEH8oBf4CGtrY2q9Xav3xteHh47tRC/CH+EH/LEH80NwRbfuCDm5p73If4Q/wtFvzJEH/zJ7mlhb8n7uXLl2NjY6Ojo8+WuMEtwI3Mca0D8Yf4W1z6d3fa/jtq8k3nBhPCa+5SNLXOy5bglWCIP8TfAutBT+pJtZZEf/p6hNfc9V1bB+IP8Yf4Wxp61JdaXm8E/MWrtbK2TuTXXBTf3mXo/R3xh/hD/C0NDQ+mNjU1XdDp96i1iUYLEnAu7Cvp6bUvESD+EH+IvyWAP7pPrbql9YylWaEz7NMa9upA9StR+vpEvTGh3pxgbnZWvRn+CCo4Nflcb0ytN55paFS33rPabHBwcJEsLyD+UIi/qfBH96mVmy3Z2rr9d9R0IXgFCm58f7X6pFpbXm+EiBh+K9A4rqftjvVutvX2fnqUy7TqqZT11ybNWup9/VpFf8OZ/i79PG4uQfyhEH/T4O+HBktctVpaXStZqexz0gWdHiJi+K3QbfqhYwbI43RL2lu9503Y58DBvf0t1+drazHiD4X4mwp/d9qtZOmjVpOkrUvQ1snqjFKDKa6+YQWK3Li+Pl6t3aPWVre03mso77wV11sVD/q9On5QHfdYIx3Sxk3UE51suC5+ju+WjRgSnugTHqhZAnbp5+XFMsQfCvE3Ff4g56X4w6UPTm2d8CjOWJoh54WADiKyd3l4AXQE3ZEseD6OFUD8oRB/U218odueceOLEwEVWgM9uLS/JuEdH9wC3T3QKeblUCnEHwrxN9W2Z+6lN962Z4m2MqKufWpASGuuuu8+FtHoXH8mbedR4sJc1x1bXbYkht3ixiOtKbAPbC7apzXQtY6Hd8fB9KImwjr7Y5zfoNWTOvm8HCmK+EMh/qZ66Y1O9o+/9NZYupphPAqneQcupiSTYdaHmhzrz6zt/KnOi4FRRHql5X58nRtPTNExbmBz/dYOA13QGD+23hgewjAZl6Nnh783ajViSJiXA+URfyjE32xOfGkhCPMuaZ0pKfj1Z9t2rqp0ndAdy+UtYfOAvwnf2WYhIDtVJJnl15a/Sav5+jY1xB8K8Tdz/DX6wYeVNbd/fu++foPXJQ3xm0rd1m/wyKtkQ7wKKPucy/mv9THhJl79nGJeuQJqRpedW7ueOjZ4nyceierc6vVb14ZsBZcrW4dLmYnf3213KK3tnlMsnVA5qui0/WpeeaVkGFxvzNqMUknFaXY8DvibOIA54C+mIJjrLjlbBJ6hkgDxOupwOXUWPNJS+WrG092gJ/yyfuvBMKt/rtjl1Arxh/hD/C2Mnj1U9HcRQWGy6E9cmE1wk3EhQttAcBZxDkgUXXiEfIJDciUQXhWlM8zWoMuQY26BHJNXv5VfltZecGGYVXuyRbU1O3MSwe91qS6mRMmiINY3I92/xMQL2Vj/+sTQKk3YN/uh6HFRw6+8Pe8rgpnd2aKqyqCMWILI87ciLpEKbicKRFWNMSXceOz4ExzAZLDbY2lJ1BlAUJgs+uu77AsXkaUHWmskryoDNzHMNplvS2VkdbY7+LN+iHqt2Un4vytgsCIA/r9NEerUCvGH+EP8LYyuNxUmVleDfrxbYNKn9VrTpk1+xeeBGqER7V2hn29lSRQpImXCwV32IGuS5Dc8wx8oGVhlitbWRddVem2hrQiwAqomziQSf2At/bHdP8S5clgaDCAxkqvfHhABrEyP4XVnp569IDgAiRD7ivQ/3lMlgq7eOvt5uWqvRjdt8mtOh55XlVZED9VEDWkisjwZJtjvBYSEl725YC/YdwiTX8Qf4m+RxH0APko6KAD+QCQYnIi/xuJVwJQiNjSruwoBlF9JKSRyXufPrWUY36JiKLud14znmPz6vLIoJ5Lh23rGJSRbTIjmH9YojL+dddyPohP+QLdIXuVw8DD7o9r5FZQxvO4m4k9wADFCcR+Aj5IOCoA/EDgF8GcM2wYgu0YWMVqyXR0uvo7ZFOw7wubIeZ7EkWfnHa8V4g/xh/hbiDm+LgX3RletFnRXpwT8gbO94ytB/Plw6wmNvjsAHBsAQ+GNjf7c1J5/aF2XE/64+rwyG6/F2uK1rsiigsDCymhCtK0T1yVY/G2w4y9wtz364yqzVxvHX+AeZlr8CQ5AOvGbeW0rvPeriFJv3gD8gVOhVwvij3LNoICe3bpttOq+FlR6OeIVFL51txHR3WpxboX4Q/wh/hZ4iUNiaMhR/wIENDZkntLf4LBosOHPdB0+2WsPnRbVNhJq5JGJNmaHEtLGCBpP0RlAO/749XllSVku1F39+bnIOhOdpHM5dD1mKvwxLhHKiDpTeB6Z+3Pn5v64yjElZFZx9aELUSaugus3lbIp8Sc4gKmXOIa0ktu3s4CAiqqbd2r+afPbyKUPBZCJU/xbKmNelPiRJyEP6NZEW3/wgfKmlFBuQlARBsgjvylkga8cWyH+EH+IvwXGX1zTvYkv+YPTRgSTb8SGcVhoCwjRTpSSrc6q0+yaQw1Zqy0DHu1g2cSv79A24ny6iy0WWrU7V9xCW/lPir8tXGXXtAJJu3NlUd4Re6659tCFGHab4Vob/uzjYUFJByYwgKnx97+muIkHGYDTRqXofJELJR1Z2z3rvcl28W27/PosUacg7V3nQUPCvrMe3HqIYyvEH+IP8bfAG1ykeiOfffCjExQkja3S2WwT4dd3aNvSGl1nimlsn24TtZLNr7ukJqg8xR5DerXZ7OCbbgBOc3wP70r57IMfnV/hMEpeje/pkwxpokeM07/R4dAK8Yf4Q/wt7PZmEgMaSCLMi/sWTOxmmg1zf1VjXrY3Q7gHCS+IF/e9ayH+EH+Iv5WCP6m22CftdGQj4g/xh/hD/L1l/J22VNzVKUE56l8Ek9+VIyf8afW5qTdvgG7fzhJMfhF/iD/U0l76oBtfQFCYsPSxcvEH4R7d+AKCwoSlD8Qf4g+1NPFHtz0D/vYa6yn7Ws0KkPPGl5WHP7rtGfA3oNtL2SevvANy2vjyqjI0S+aWkR70AvGH+EMtrW3PP94tAAImqdVXDJco/sj7vxPf+lhhStQZrt46CwTsqkosrPme4i+R/a47pznBkWte7C4XryHEH+IPtbReeqPI40v4pbcVpj2WFoo8voRferNEGX7YqSkRz4Rfr4zSV4g/xB/ib5Go1+rAvkmPPFiB+a9Gx2ffZEcevKgIlG1fLZYHjFDA1YRliVZz255FXoYabpFk8Jq/7SCsVafyIxB/iCESqGQAAAU2SURBVD/E35I58GrFxoDTHng1co283MZ4+pDkVx8mpojzXCv25F5FMesBkf70BECZzJ2+IX1qtqdDI/4Qf4i/BTvtGTUZ/oo4/EH0Z80lZ61uEvnRU14K2dfaxMpwAzkIiwlJIcsj3ex7b/QgLMQf4g/xh/hbJvgzp68lZxpkc7lti5L8GKIIo37Hs7C8hxB/iD/EH+Jv2eCPnve3aVcAu74hLZWtIvhLDzco2OhPsXPEIukrCsrP9lddi3iF+EP8If4Qf8sGf69rgjZxix7uR0Wr2OJqjcZ+2vOqLKVvMjsnOKuDXhB/iD/EH+JvMeLvRQn51g5muw9d+R0qsq/wQobrqirjjvNr+dbLnviG7PIbxJVfxB/iD/G3pPH3Si9WKdmvlvN0mMt7oY8e0kw4x9QSM8ODsBB/iD/EH+JvsePPkMIdnLpJFoTv/CL+UIi/lYS/XO/kXW5HU/y6jXjkAeIPhfhbYXN/eOIL4g+F+Fsp+OtQyRYMf0Y54g/xh/hD/C0Q/vT11tv7AX+PNQtw4ulIg4Lib3R0FPGH+EP8If7e7UFYeuO9mpOAv0H1AkR/T1q/o/gbGxtD/CH+EH+Iv3eqhHpzY315h0rye3X8n03vlH1/Nsc/6DFQ/L18+RLxh/hD/CH+3i3+zM1NTU3Nmgu91Xue6BPfGQGBfU+6Sij7BgcHXy9fQ/wh/hB/ixd/nZ2dZrO5o7m6v+HMA53iSZ18xJDwrP7tyCgfaVBAzmuP+8CeP3+O+EP8If4QfwuAPwBQW1ub1WrtXwgbHh5+vawN8Yf4Q/wtavzRDBTsXYIPulvecR/iD/G3WPAnQ/wJSW5p4e+8e/ny5djY2Ojo6LO3ZnBx6GIZr3Ug/hB/i0v/7k7bf0dNvuncYELk8aVoal32G48Rf6gVjb8HPakn1VoS/enrEXl8fdfWgfhD/KGWM/4e9aWW1xsBf/FqraytE6lHFd/eZej9HfGH+EMtZ/wND6Y2NTVd0On3qLWJRgsSkLKvpKfXvhCB+EP8oZYt/ujutuqW1jOWZkV9g9zUmNDQlGBuXmmSW1oUza2Q89rjvmW/8w7xh1rp+FvY3W2L2Zb9zjvEHwrxtzC72xazrZCdd4g/1Pzgr73p0NLEX/o73t22mG2l7bxD/KHmA38WZXtzOuDv4f1DSwt/TwdO4gQ/GuIPNRf8ZbY2fgv4e9CzxPA3NFCA+END/KHeXKUtmY3mW+1NKb3th/8zumTY95/R1Af9DYg/NMQf6s0Fj52cDWe51N125HF/6pIgILBv6OFN3N2GhvhDzRV/3Nlw7eq+nov/7sl63H/s6UDq8OAiVPrw4EnIee1xH+5uQ0P8oeaEv6W7ew53t6Eh/lBzxd+S2z2Hu9vQlgn+fjV/hfhbKFVYs5bQ7jnc3Ya2rPAH/6DLG08B/n5ry0QYLYA6vsYFBDS0hcEf/DJX37sE+CtrRfwtgOp6ChF/aGgLgz9IZNp7G0rMyhJz5u37SMB3rY7fzYg/NLSFwR/Y4OCgsaMcCFjWqkQCvks191Xi7jk0tIXE3/Pnz+HjBzEgZME3m0/9du/Eb21kJQT1NlRhzars/AZyXnvch7vn0NAWDH9gw8PDeFQR7p5DQ1uJ+KMxIJ7ahrvn0NBWIv6orfBT23D3HBraysUfGhoaGuIPDQ0NDfGHhoaGhvhDQ0NDQ/yhoaGhIf7Q0NDQEH9oaGhoiD80NDQ0xB8aGhoa4g8NDQ0N8YeGhoaG+ENDQ0ND/KGhoaEh/tDQ0NAQf2hoaGiIPzQ0tJVs/x8Xr6boMQqPwwAAAABJRU5ErkJggg== \ No newline at end of file
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/home/home.png b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/home/home.png
new file mode 100644
index 0000000000..8f5a0b0d86
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/home/home.png
Binary files differ
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/home/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/home/index.html
new file mode 100644
index 0000000000..130c05fda0
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/home/index.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<div id="bodydiv" class="body">
+
+<div class="viewcontent" style="margin-left: auto; margin-right: auto; text-align: center;">
+
+<br/>
+<div id="hometitle" style="font-size: 28px;"></div>
+<br/>
+
+<!--
+<div id="homeanimation" style="width: 320px; height: 280px; padding: 0px; margin: 0px auto;"></div>
+-->
+
+<input type="button" class="graybutton bluebutton" style="font-size: 21px; padding: 10px; height: 50px;" id="getstarted" title="Get Started" value="Get Started"/>
+
+<br/><br/>
+<div class="note">Requires Safari 5+, Chrome 11+, Firefox 4+, IE 9+</div>
+
+</div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Set page titles.
+ */
+document.title = config.windowtitle();
+$('viewhead').innerHTML = '<span class="bcmenu">' + config.pagetitle() + '</span>';
+$('hometitle').innerHTML = config.hometitle();
+
+$('getstarted').onclick = function() {
+ return ui.navigate('/#view=store', '_view');
+};
+
+/**
+ * Display animation.
+ */
+var anim = $('homeanimation');
+if (!isNil(anim)) {
+ anim.style.background = 'url(\'' + ui.b64img(appcache.get('/home/home.b64')) + '\')';
+ var bgpos = 0;
+ setInterval(function() {
+ bgpos = bgpos -280;
+ if (bgpos == -2800)
+ bgpos = 0;
+ anim.style.backgroundPosition = '0px ' + ui.pixpos(bgpos);
+ }, 2000);
+}
+
+/**
+ * Show the status.
+ */
+showOnlineStatus();
+
+})();
+</script>
+
+</div>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/index.html
new file mode 100644
index 0000000000..e3e046136d
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/index.html
@@ -0,0 +1,640 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<html manifest="/cache-manifest.cmf">
+<head>
+<title></title>
+<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"/>
+<meta name="apple-mobile-web-app-capable" content="yes"/>
+<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
+<link rel="apple-touch-icon" href="/public/touchicon.png"/>
+<base href="/"/>
+<script type="text/javascript">
+(function() {
+
+window.appcache = {};
+
+/**
+ * Get and cache a resource.
+ */
+appcache.get = function(uri) {
+ var h = uri.indexOf('#');
+ var u = h == -1? uri : uri.substring(0, h);
+
+ // Get resource from local storage first
+ var ls = window.lstorage || localStorage;
+ var item = null;
+ try { item = ls.getItem(u); } catch(e) {}
+ if (item != null && item != '')
+ return item;
+
+ // Get resource from network
+ //if (window.debug) debug('appcache.get', u);
+ var http = new XMLHttpRequest();
+ http.open("GET", u, false);
+ http.setRequestHeader("Accept", "*/*");
+ http.send(null);
+ if (http.status == 200) {
+ if (http.getResponseHeader("X-Login") != null) {
+ if (window.debug) debug('http error', u, 'X-Login');
+ // Redirect to login page if not signed in
+ document.location = '/login/';
+ return null;
+ } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
+ if (window.debug) debug('http error', u, 'No-Content');
+ return null;
+ }
+ try { ls.setItem(u, http.responseText); } catch(e) {}
+ return http.responseText;
+ }
+ if (window.debug) debug('http error', u, http.status, http.statusText);
+ // Redirect to login page if not signed in
+ if (http.status == 403)
+ document.location = '/login/';
+ return null;
+};
+
+appcache.remove = function(uri) {
+ var h = uri.indexOf('#');
+ var u = h == -1? uri : uri.substring(0, h);
+ var ls = window.lstorage || localStorage;
+ try { ls.removeItem(u); } catch(e) {}
+ return true;
+};
+
+})();
+
+/**
+ * Load Javascript and CSS.
+ */
+(function() {
+
+var bootjs = document.createElement('script');
+bootjs.type = 'text/javascript';
+bootjs.text = appcache.get('/all-min.js');
+document.head.appendChild(bootjs);
+document.head.appendChild(ui.declareCSS(appcache.get('/ui-min.css')));
+
+// Disable cache for testing
+//lstorage.enabled = false;
+
+})();
+
+/**
+ * Redirect to login page if not signed in.
+ */
+(function() {
+
+if (document.location.protocol == 'https:' && !hasauthcookie())
+ document.location = '/login/';
+
+})();
+</script>
+</head>
+<body class="delayed">
+<div id="mainbodydiv" class="mainbody">
+
+<div id="headdiv" class="hsection">
+<script type="text/javascript">
+(function() {
+
+$('headdiv').appendChild(ui.declareScript(appcache.get('/config-min.js')));
+
+})();
+</script>
+</div>
+
+<div id="menubackground" class="tbarbackground fixed"></div>
+<div id="menu" class="tbarmenu fixed"></div>
+
+<div id="viewheadbackground" class="viewheadbackground fixed"></div>
+<div id="viewhead" class="viewhead fixed"></div>
+
+<div id="viewcontainer"></div>
+
+<div id="viewfootbackground" class="viewfootbackground fixed"></div>
+<div id="viewfoot" class="viewfoot fixed"></div>
+<div id="status" class="status fixed" style="visibility: hidden;"></div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Init service references.
+ */
+var editorComp = sca.component("Editor");
+var user= sca.defun(sca.reference(editorComp, "user"));
+var accounts = sca.reference(editorComp, "accounts");
+
+/**
+ * Set page title.
+ */
+document.title = config.windowtitle();
+
+/**
+ * Init div variables.
+ */
+var bdiv = $('mainbodydiv');
+var mdiv = $('menu');
+var hdiv = $('viewhead');
+var vcontainer = $('viewcontainer');
+vcontainer.className = ui.isMobile()? 'viewcontainer3dm' : 'viewcontainer3d';
+var fdiv = $('viewfoot');
+
+/**
+ * The current user name and account entry.
+ */
+window.username = 'anonymous';
+
+/**
+ * The current store category.
+ */
+var storecat = 'top';
+var storeidx = 0;
+
+/**
+ * Pre-fetch app resources.
+ */
+var appresources = [
+ ['/all-min.js'],
+ ['/ui-min.css'],
+ ['/account/', 9],
+ ['/clone/', 3],
+ ['/create/', 2],
+ ['/delete/', 3],
+ ['/graph/', 5],
+ ['/config-min.js'],
+ ['/home/', 0],
+ ['/home/home.b64'],
+ ['/page/', 4],
+ ['/public/app.b64'],
+ ['/public/config-min.js'],
+ ['/public/grid72.b64'],
+ ['/public/iframe-min.html'],
+ ['/public/img.b64'],
+ ['/public/user.b64'],
+ ['/stats/', 2],
+ ['/store/', 1]
+];
+
+/**
+ * Show a status message.
+ */
+window.showStatus = function(s, c) {
+ //debug('status', s);
+ var sdiv = $('status');
+ if (isNil(sdiv))
+ return s;
+ sdiv.innerHTML = '<span class="' + (c? c : 'okstatus') + '">' + s + '</span>';
+ sdiv.className = 'status fixed';
+ sdiv.style.visibility = 'visible';
+
+ function divtransitionend(e) {
+ e.target.style.visibility = 'hidden';
+ e.target.className = 'status fixed';
+ }
+ if (!sdiv.addedTransitionEnd) {
+ sdiv.addEventListener('webkitTransitionEnd', divtransitionend, false);
+ sdiv.addEventListener('transitionend', divtransitionend, false);
+ sdiv.addedTransitionEnd = true;
+ }
+ sdiv.className = 'statusout3 fixed';
+ return s;
+}
+
+/**
+ * Show an error message.
+ */
+window.showError = function(s) {
+ //debug('error', s);
+ return showStatus(s, 'errorstatus');
+}
+
+/**
+ * Show the online/offline status.
+ */
+window.showOnlineStatus = function() {
+ return navigator.onLine? showStatus('Online') : showError('Offline');
+}
+
+/**
+ * Handle application cache events.
+ */
+applicationCache.addEventListener('checking', function(e) {
+ //debug('appcache checking', e);
+ showStatus('Checking');
+}, false);
+applicationCache.addEventListener('error', function(e) {
+ //debug('appcache error', e);
+ showOnlineStatus();
+}, false);
+applicationCache.addEventListener('noupdate', function(e) {
+ //debug('appcache noupdate', e);
+ showOnlineStatus();
+}, false);
+applicationCache.addEventListener('downloading', function(e) {
+ //debug('appcache downloading', e);
+ showStatus('Updating');
+}, false);
+applicationCache.addEventListener('progress', function(e) {
+ //debug('appcache progress', e);
+ showStatus('Updating');
+}, false);
+applicationCache.addEventListener('updateready', function(e) {
+ //debug('appcache updateready', e);
+ try {
+ applicationCache.swapCache();
+ } catch(e) {}
+ showOnlineStatus();
+ //debug('appcache swapped', e);
+
+ // Update offline resources in local storage and reload the page
+ map(function(res) {
+ showStatus('Updating');
+ appcache.remove(res[0]);
+ appcache.get(res[0]);
+ }, append(appresources, config.appresources()));
+ window.location.reload();
+}, false);
+applicationCache.addEventListener('cached', function(e) {
+ //debug('appcache cached', e);
+ showOnlineStatus();
+
+ // Install offline resources in local storage
+ map(function(res) {
+ showStatus('Installing');
+ appcache.remove(res[0]);
+ appcache.get(res[0]);
+ }, append(appresources, config.appresources()));
+}, false);
+
+/**
+ * Handle network offline/online events.
+ */
+window.addEventListener('offline', function(e) {
+ //debug('going offline');
+ showStatus('Offline');
+}, false);
+window.addEventListener('online', function(e) {
+ //debug('going online');
+ showStatus('Online');
+}, false);
+
+//debug(navigator.onLine? 'online' : 'offline');
+
+/**
+ * Handle view transitions.
+ */
+var viewurl = '';
+var viewuri = '';
+var viewidx = 0;
+var viewdiv;
+
+/**
+ * Record which transitions should be applied to each resource.
+ */
+var apptransitions = {};
+map(function(res) {
+ if (res.length > 1)
+ apptransitions[res[0]] = res[1];
+}, append(appresources, config.appresources()));
+
+/**
+ * Return the transition that should be applied to a resource.
+ */
+function viewtransition(ouri, uri) {
+ var ot = apptransitions[ouri];
+ if (isNil(ot))
+ return 'left';
+ var t = apptransitions[uri];
+ if (isNil(t))
+ return 'left';
+ return t < ot? 'right' : 'left';
+}
+
+/**
+ * Create a new view div.
+ */
+function mkviewdiv(cname) {
+ var vdiv = document.createElement('div');
+ vdiv.className = cname;
+ if (!ui.isMobile())
+ return vdiv;
+
+ // Handle view transition end
+ function viewdivtransitionend(e) {
+ if (e.target.className == 'leftviewunloaded3dm' || e.target.className == 'rightviewunloaded3dm')
+ e.target.parentNode.removeChild(e.target);
+ }
+ vdiv.addEventListener('webkitTransitionEnd', viewdivtransitionend, false);
+ vdiv.addEventListener('transitionend', viewdivtransitionend, false);
+ return vdiv;
+}
+
+/**
+ * Return the last visited location.
+ */
+function lastvisited() {
+ if (username != lstorage.getItem('ui.lastvisit.user'))
+ return null;
+ return lstorage.getItem('ui.lastvisit.url');
+}
+
+/**
+ * Build and show the menu bar.
+ */
+function showmenu(mdiv, view, appname) {
+ mdiv.innerHTML = ui.menubar(
+ append(mklist(ui.menu('menuhome', 'Home', '/', '_view', view == 'home'),
+ ui.menu('menustore', 'Store', '/#view=store&category=' + storecat + '&idx=' + storeidx, '_view', view === 'store')),
+ (isNil(appname) || appname == 'undefined')?
+ mklist() :
+ mklist(
+ ui.menu('menustats', 'Stats', '/#view=stats&app=' + appname, '_view', view == 'stats'),
+ ui.menu('menupage', 'Page', '/#view=page&app=' + appname, '_view', view == 'page'),
+ ui.menu('menulogic', config.logic(), '/#view=graph&app=' + appname, '_view', view == 'graph'),
+ ui.menu('menurun', '<span class="greentext" style="font-weight: bold">Run!</span>', '/' + appname + '/', '_blank', false))),
+ (isNil(appname) || appname == 'undefined')? mklist(
+ hasauthcookie()? ui.menufunc('menusignout', 'Sign out', 'return logout();', false) : ui.menu('menusignin', 'Sign in', '/login/', '_self', false),
+ ui.menu('menuaccount', 'Account', '/#view=account', '_view', view == 'account')) :
+ mklist());
+
+ if (fdiv.innerHTML == '')
+ fdiv.innerHTML = config.viewfoot();
+}
+
+/**
+ * Get the current user's account.
+ */
+function getaccount() {
+ var doc = accounts.get();
+
+ // Stop now if we didn't get an account
+ if (doc == null)
+ return false;
+
+ var accountentry = car(elementsToValues(atom.readATOMEntry(mklist(doc))));
+ username = cadr(assoc("'id", cdr(accountentry)));
+ return true;
+}
+
+/**
+ * Show a view.
+ */
+function showview(url) {
+ //debug('showview', url);
+
+ // Save last visited location
+ lstorage.setItem('ui.lastvisit.user', username);
+ lstorage.setItem('ui.lastvisit.url', url);
+
+ // Determine the view to show
+ var params = ui.fragmentParams(url);
+ var view = isNil(params['view'])? 'home' : params['view'];;
+ var uri = '/' + view + '/';
+ var idx = isNil(params['idx'])? 0 : parseInt(params['idx']);
+
+ // Track store category view
+ if (view == 'store') {
+ storecat = isNil(params['category'])? 'top' : params['category'];
+ storeidx = idx;
+ }
+
+ // Determine the transition to use
+ var vtransition = uri == viewuri? (idx >= viewidx? 'left' : 'right') : viewtransition(viewuri, uri);
+
+ // Track current view url and uri
+ viewurl = url;
+ viewuri = uri;
+ viewidx = idx;
+
+ // Show the menu bar
+ var appname = params['app'];
+ showmenu(mdiv, view, appname);
+
+ // Scroll to the top and hide the address bar
+ window.scrollTo(0, 0);
+
+ // Start to unload the front view and create a new view
+ if (ui.isMobile()) {
+ // Prepare current view for transition out
+ var ovdiv = viewdiv;
+ if (!isNil(ovdiv)) {
+ ovdiv.skipNode = true;
+ ovdiv.className = 'viewunloading3dm';
+ }
+
+ // Load the requested doc into a new view
+ var vdiv = mkviewdiv(vtransition + 'viewloading3dm');
+ var vdoc = appcache.get(uri);
+ vdiv.innerHTML = vdoc;
+ vcontainer.appendChild(vdiv);
+ map(ui.evalScript, ui.innerScripts(vdiv));
+
+ // Make sure the top document is visible
+ if (document.body.style.visibility != 'visible')
+ document.body.style.visibility = 'visible';
+
+ setTimeout(function() {
+ // Transition the old view out
+ if (!isNil(ovdiv))
+ ovdiv.className = vtransition + 'viewunloaded3dm';
+
+ // Transition the new view in
+ vdiv.className = 'viewloaded3dm';
+ }, 100);
+
+ } else {
+ // Prepare current view for transition out
+ var ovdiv = viewdiv;
+ if (!isNil(ovdiv))
+ ovdiv.skipNode = true;
+
+ // Load the requested doc into the view
+ var vdiv = mkviewdiv('viewloading3d');
+ var vdoc = appcache.get(uri);
+ vdiv.innerHTML = vdoc;
+ vcontainer.appendChild(vdiv);
+ map(ui.evalScript, ui.innerScripts(vdiv));
+
+ // Make sure the top document is visible
+ if (document.body.style.visibility != 'visible')
+ document.body.style.visibility = 'visible';
+
+ setTimeout(function() {
+ // Transition the new view in
+ vdiv.className = 'viewloaded3d';
+
+ // Transition the old view out
+ if (!isNil(ovdiv))
+ ovdiv.parentNode.removeChild(ovdiv);
+ }, 100);
+ }
+
+ // Track the current visible view
+ viewdiv = vdiv;
+
+ return true;
+}
+
+/**
+ * Update the browser window location.
+ */
+function updatelocation(url) {
+ //debug('updatelocation', url);
+
+ // Add url to the history if necessary
+ if (url != ui.pathandparams(location)) {
+ history.pushState(null, null, url);
+ //debug('pushstate', history.length);
+
+ // Update the location hash if necessary
+ var f = ui.fragment(url);
+ if (f != '' && f != location.hash) {
+ location.hash = f;
+ //debug('hash', f);
+ }
+ }
+ return url;
+}
+
+/**
+ * Handle navigations.
+ */
+window.onnavigate = function(url) {
+ //debug('onnavigate', url);
+
+ // Update the browser window location
+ updatelocation(url);
+
+ // Show the specified view
+ if (url == viewurl)
+ return true;
+ return showview(url);
+};
+
+/**
+ * Handle login redirect.
+ */
+window.onloginredirect = function(e) {
+ document.location = '/login/';
+};
+
+/**
+ * Log the current user out.
+ */
+window.logout = function() {
+ // Clear session cookie and user-specific local storage entries
+ clearauthcookie();
+ lstorage.removeItem('/r/Editor/accounts');
+ lstorage.removeItem('/r/Editor/dashboards');
+ document.location = '/login/';
+ return false;
+}
+
+/**
+ * Handle history.
+ */
+window.addEventListener('popstate', function(e) {
+ //debug('onpopstate', history.length);
+ var furl = ui.fragment(location);
+ var url = location.pathname + (furl == ''? '' : '#' + furl);
+
+ // Show the current view
+ if (url == viewurl)
+ return true;
+ return showview(url);
+
+}, false);
+
+window.addEventListener('hashchange', function(e) {
+ //debug('onhashchange');
+ var furl = ui.fragment(location);
+ var url = location.pathname + (furl == ''? '' : '#' + furl);
+
+ // Show the current view
+ if (url == viewurl)
+ return true;
+ return showview(url);
+
+}, false);
+
+/**
+ * Handle orientation change.
+ */
+document.body.onorientationchange = function(e) {
+ //debug('onorientationchange');
+ ui.onorientationchange(e);
+
+ // Resize menu and view header
+ mdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
+ hdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
+ return true;
+};
+
+/**
+ * Initialize the document.
+ */
+function onload() {
+ //debug('onload', history.length);
+ ui.onload();
+
+ // Get the current user account
+ getaccount();
+
+ // Show the view specified in the given url fragment
+ var furl = ui.fragment(location);
+ if (furl != '') {
+ var url = location.pathname + '#' + furl;
+ if (url == viewurl)
+ return true;
+ return showview(url);
+ }
+
+ // Show the last visited view
+ if (ui.isMobile() && (document.referrer == null || document.referrer == '' ||
+ document.referrer.indexOf('//' + location.hostname + '/login/') != -1 ||
+ document.referrer.indexOf('//accounts.google.com/ServiceLogin') != -1 ||
+ document.referrer.indexOf('//www.facebook.com/login.php') != -1)) {
+ var lv = lastvisited();
+ var url = isNil(lv)? location.pathname : lv;
+ updatelocation(url);
+ if (url == viewurl)
+ return true;
+ return showview(url);
+ }
+
+ // Show the main home view
+ var url = location.pathname;
+ if (url == viewurl)
+ return true;
+ return showview(url);
+}
+
+onload();
+
+})();
+</script>
+
+<div id="footdiv" class="fsection">
+</div>
+
+</div>
+</body>
+</html>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/login/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/login/index.html
new file mode 100644
index 0000000000..bf09339927
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/login/index.html
@@ -0,0 +1,337 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Sign in</title>
+<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"/>
+<meta name="apple-mobile-web-app-capable" content="yes"/>
+<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
+<base href="/login/"/>
+<script type="text/javascript">
+(function() {
+
+window.appcache = {};
+
+/**
+ * Get and cache a resource.
+ */
+appcache.get = function(uri) {
+ var h = uri.indexOf('#');
+ var u = h == -1? uri : uri.substring(0, h);
+
+ // Get resource from local storage first
+ var ls = window.lstorage || localStorage;
+ var item = null;
+ try { item = ls.getItem(u); } catch(e) {}
+ if (item != null && item != '')
+ return item;
+
+ // Get resource from network
+ var http = new XMLHttpRequest();
+ http.open("GET", u, false);
+ http.setRequestHeader("Accept", "*/*");
+ http.send(null);
+ if (http.status == 200) {
+ if (http.getResponseHeader("X-Login") != null) {
+ if (window.debug) debug('http error', u, 'X-Login');
+ return null;
+ } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
+ if (window.debug) debug('http error', u, 'No-Content');
+ return null;
+ }
+ try { ls.setItem(u, http.responseText); } catch(e) {}
+ return http.responseText;
+ }
+ if (window.debug) debug('http error', u, http.status, http.statusText);
+ return null;
+};
+
+})();
+
+/**
+ * Load Javascript and CSS.
+ */
+(function() {
+
+var bootjs = document.createElement('script');
+bootjs.type = 'text/javascript';
+bootjs.text = appcache.get('/all-min.js');
+document.head.appendChild(bootjs);
+document.head.appendChild(ui.declareCSS(appcache.get('/ui-min.css')));
+
+})();
+
+</script>
+</head>
+<body class="delayed"">
+<div id="mainbodydiv" class="bodydiv">
+
+<div id="headdiv" class="hsection">
+<script type="text/javascript">
+(function() {
+
+$('headdiv').appendChild(ui.declareScript(appcache.get('/public/config-min.js')));
+
+})();
+</script>
+</div>
+
+<div id="menubackground" class="tbarbackground fixed"></div>
+<div id="menu" class="tbarmenu fixed"></div>
+
+<div id="viewheadbackground" class="viewheadbackground fixed"></div>
+<div id="viewhead" class="viewhead fixed">
+<span class="cmenu">Sign in</span>
+</div>
+
+<div id="viewcontainer">
+<div id="view">
+<div id="viewcontent" class="viewcontent" style="margin-left: auto; margin-right: auto; text-align: center;">
+
+<br/>
+<form id="formSignin" name="formSignin" method="POST" action="/login/dologin" style="width: 100%;">
+<table style="width: 100%;">
+<tr><td><span id="loginprompt" style="font-size: 16px;"></span></tr></td>
+<tr><td><input type="text" class="flatentry" name="httpd_username" value="" placeholder="User id"/></td></tr>
+<tr><td><input type="password" class="flatentry" name="httpd_password" value="" placeholder="Password"/></td></tr>
+<tr><td><input type="submit" class="graybutton bluebutton" style="font-size: 16px; line-height: 16px; padding: 6px; height: 32px" value="Sign in"/></td></tr>
+</table>
+<input type="hidden" name="httpd_location" value="/"/>
+</form>
+<br/>
+
+<form name="facebookOAuth2Form" style="width: 100%;">
+<table style="width: 100%;">
+<tr><td><span style="font-size: 16px;">Sign in with your <span style="font-weight: bold;">Facebook</span> account</span></td></tr>
+<tr><td><input type="button" id="facebookOAuth2Signin" value="Sign in" class="graybutton bluebutton" style="font-size: 16px; line-height: 16px; padding: 6px; height: 32px"/></td></tr>
+</table>
+</form>
+<br/>
+
+<form name="googleOAuth2Form" style="width: 100%;">
+<table style="width: 100%;">
+<tr><td><span style="font-size: 16px;">Sign in with your <span style="font-weight: bold;" >Google</span> account</span></td></tr>
+<tr><td><input type="button" id="googleOAuth2Signin" value="Sign in" class="graybutton bluebutton" style="font-size: 16px; line-height: 16px; padding: 6px; height: 32px"/></td></tr>
+</table>
+</form>
+<br/>
+
+<form name="oauth2Signin" action="/oauth2/authorize/" method="GET">
+<input type="hidden" name="oauth2_authorize" value=""/>
+<input type="hidden" name="oauth2_access_token" value=""/>
+<input type="hidden" name="oauth2_client_id" value=""/>
+<input type="hidden" name="oauth2_info" value=""/>
+<input type="hidden" name="oauth2_display" value=""/>
+<input type="hidden" name="oauth2_scope" value=""/>
+<input type="hidden" name="openauth_referrer" value=""/>
+</form>
+
+</div>
+</div>
+</div>
+
+<div id="viewfootbackground" class="viewfootbackground fixed"></div>
+<div id="viewfoot" class="viewfoot fixed"></div>
+<div id="status" class="status fixed" style="visibility: hidden;"></div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Init div variables.
+ */
+var mbdiv = $('menubackground');
+var mdiv = $('menu');
+var hdiv = $('viewhead');
+var hbdiv = $('viewheadbackground');
+$('viewcontainer').className = ui.isMobile()? 'viewcontainer3d' : 'viewcontainer3dm';
+$('view').className = ui.isMobile()? 'viewloaded3d' : 'viewloaded3dm';
+$('loginprompt').innerHTML = config.loginprompt();
+var fdiv = $('viewfoot');
+
+/**
+ * Set page titles.
+ */
+document.title = config.windowtitle() + ' - Sign in';
+$('viewhead').innerHTML = '<span class="bcmenu">' + config.pagetitle() + '</span>';
+
+/**
+ * Build and show the menu bar.
+ */
+function showmenu(mdiv) {
+ mdiv.innerHTML = ui.menubar(mklist(ui.menu('menuhome', 'Home', '/', '_self', false)), mklist());
+ fdiv.innerHTML = config.viewfoot();
+}
+
+showmenu(mdiv);
+
+/**
+ * Show a status message.
+ */
+window.showStatus = function(s, c) {
+ //debug('status', s);
+ var sdiv = $('status');
+ if (isNil(sdiv))
+ return s;
+ sdiv.innerHTML = '<span class="' + (c? c : 'okstatus') + '">' + s + '</span>';
+ sdiv.className = 'status fixed';
+ sdiv.style.visibility = 'visible';
+
+ function divtransitionend(e) {
+ e.target.style.visibility = 'hidden';
+ e.target.className = 'status fixed';
+ }
+ if (!sdiv.addedTransitionEnd) {
+ sdiv.addEventListener('webkitTransitionEnd', divtransitionend, false);
+ sdiv.addEventListener('transitionend', divtransitionend, false);
+ sdiv.addedTransitionEnd = true;
+ }
+ sdiv.className = 'statusout3 fixed';
+ return s;
+}
+
+/**
+ * Show an error message.
+ */
+window.showError = function(s) {
+ //debug('error', s);
+ return showStatus(s, 'errorstatus');
+}
+
+/**
+ * Parse the query parameeters.
+ */
+function queryParams() {
+ 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;
+}
+
+/**
+ * Show login status.
+ */
+function showLoginStatus() {
+ var a = queryParams()['openauth_attempt'];
+ debug('a', a);
+ if (typeof(a) != 'undefined' && a == '1')
+ showError('Incorrect email or password, please try again');
+}
+
+showLoginStatus();
+
+/**
+ * Return the referrer URL.
+ */
+function openauthReferrer() {
+ var r = queryParams()['openauth_referrer'];
+ if (typeof(r) == 'undefined' || domainname(r) != domainname(window.location.hostname))
+ return '/';
+ var q = r.indexOf('?');
+ if (q > 0)
+ return r.substring(0, q);
+ return r;
+}
+
+/**
+ * Signin with OAuth 2.0.
+ */
+function submitOAuth2Signin(w) {
+ parms = w();
+ clearauthcookie();
+ lstorage.removeItem('/r/Editor/accounts');
+ lstorage.removeItem('/r/Editor/dashboards');
+ document.oauth2Signin.oauth2_authorize.value = parms[0];
+ document.oauth2Signin.oauth2_access_token.value = parms[1];
+ document.oauth2Signin.oauth2_client_id.value = parms[2];
+ document.oauth2Signin.oauth2_info.value = parms[3];
+ document.oauth2Signin.oauth2_scope.value = parms[4];
+ document.oauth2Signin.oauth2_display.value = parms[5];
+ document.oauth2Signin.openauth_referrer.value = openauthReferrer();
+ document.oauth2Signin.action = '/oauth2/authorize/';
+ document.oauth2Signin.submit();
+}
+
+function withFacebook() {
+ var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'facebook.com', 'https://graph.facebook.com/me', 'email', ui.isMobile()? 'touch' : 'page'];
+ return parms;
+}
+
+function withGoogle() {
+ var parms = ['https://accounts.google.com/o/oauth2/auth', 'https://accounts.google.com/o/oauth2/token', 'google.com', 'https://www.googleapis.com/oauth2/v1/userinfo', 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile', ''];
+ return parms;
+}
+
+$('facebookOAuth2Signin').onclick = function() {
+ return submitOAuth2Signin(withFacebook);
+};
+
+$('googleOAuth2Signin').onclick = function() {
+ return submitOAuth2Signin(withGoogle);
+};
+
+/**
+ * Signin with a userid and password.
+ */
+function submitFormSignin() {
+ clearauthcookie();
+ document.formSignin.httpd_location.value = '/';
+ document.formSignin.submit();
+}
+
+$('formSignin').onsubmit = submitFormSignin;
+
+/**
+ * Handle orientation change.
+ */
+document.body.onorientationchange = function(e) {
+ //debug('onorientationchange');
+ ui.onorientationchange(e);
+
+ // Resize menu and view header
+ mdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
+ hdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
+ return true;
+};
+
+/**
+ * Initialize the document.
+ */
+function onload() {
+ //debug('onload');
+ ui.onload();
+
+ // Show the page
+ document.body.style.visibility = 'visible';
+ return true;
+}
+
+onload();
+
+})();
+</script>
+
+</div>
+</body>
+</html>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/page/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/page/index.html
new file mode 100644
index 0000000000..6a6e042c74
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/page/index.html
@@ -0,0 +1,1081 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<div id="bodydiv" class="body">
+
+<div id="contentdiv" class="viewcontent" style="width: 2500px;">
+<div id="pagediv" class="pagediv" style="top: 0px; left: -2500px; width: 5000px; height: 5000px;">
+
+<!--
+<div class="guide" style="position: absolute; left: 2500px; top: 0px; width: 320px; height: 460px;"></div>
+<div class="guide" style="position: absolute; left: 2500px; top: 0px; width: 480px; height: 300px;"></div>
+<div class="guide" style="position: absolute; left: 2500px; top: 0px; width: 768px; height: 911px;"></div>
+<div class="guide" style="position: absolute; left: 2500px; top: 0px; width: 1024px; height: 655px;"></div>
+-->
+
+<span class="h1" id="palette:h1" style="position: absolute; left: 0px; top: 0px;"><h1>Header Level 1</h1></span>
+<span class="h2" id="palette:h2" style="position: absolute; left: 0px; top: 30px;"><h2>Header Level 2</h2></span>
+<span class="section" id="palette:section" style="position: absolute; left: 0px; top: 60px; width: 220px;"><span class="Section">Section</span></span>
+<span class="text" id="palette:text" style="position: absolute; left: 0px; top: 90px;"><span>Some text</span></span>
+<span class="link" id="palette:link" style="position: absolute; left: 80px; top: 90px;"><a href="/"><span>Link</span></a></span>
+<span class="button" id="palette:graybutton" style="position: absolute; left: 0px; top: 120px;"><input type="button" value="Button" class="graybutton"/></span>
+<span class="button" id="palette:bluebutton" style="position: absolute; left: 80px; top: 120px;"><input type="button" value="Button" class="graybutton bluebutton"/></span>
+<span class="button" id="palette:redbutton" style="position: absolute; left: 160px; top: 120px;"><input type="button" value="Button" class="graybutton redbutton"/></span>
+<span class="entry" id="palette:entry" style="position: absolute; left: 0px; top: 160px;"><input type="text" value="Entry Field" class="flatentry" size="20" autocapitalize="off"/></span>
+<span class="password" id="palette:password" style="position: absolute; left: 0px; top: 190px;"><input type="password" value="Password" class="flatentry" size="20"/></span>
+<span class="checkbox" id="palette:checkbox" style="position: absolute; left: 0px; top: 220px;"><input type="checkbox" value="Checkbox" class="flatcheckbox"/><span>Checkbox</span></span>
+<!--
+<span class="select" id="palette:select" style="position: absolute; left: 80px; top: 220px;"><select><option value="select">Selection</option></select></span>
+-->
+<span class="list" id="palette:list" style="position: absolute; left: 0px; top: 250px; width: 220px;">
+<table class="datatable" style="width: 220px;">
+<tr><td class="datatd">List</td></tr>
+<tr><td class="datatd">List</td></tr>
+<tr><td class="datatd">List</td></tr>
+</table>
+</span>
+<span class="table" id="palette:table" style="position: absolute; left: 0px; top: 320px; width: 220px;">
+<table class="datatable" style="width: 220px;">
+<tr><td class="datatdl">Table</td><td class="datatdr">Table</td></tr>
+<tr><td class="datatdl">Table</td><td class="datatdr">Table</td></tr>
+<tr><td class="datatdl">Table</td><td class="datatdr">Table</td></tr>
+</table>
+</span>
+<!--
+<span class="iframe fakeframe" id="palette:iframe" style="position: absolute; left: 0px; top: 380px; width: 200px;"><a href="/public/iframe-min.html"><span class="fakeframe"><span>Frame ...</span></span></a></span>
+-->
+<span class="img" id="palette:img" style="position: absolute; left: 0px; top: 410px;"><img id="imgimg"/></span>
+</div>
+
+<div id="playdiv" style="visibility: hidden; position: absolute; top: 0px; left: 0px; width: 2500px; height: 5000px;">
+</div>
+
+</div>
+
+<div id="buffer" style="visibility: hidden; width: 0px; height: 0px"></div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Get the current app name.
+ */
+var appname = ui.fragmentParams(location)['app'];
+
+/**
+ * Return the link to an app.
+ */
+function applink(appname) {
+ var protocol = location.protocol;
+ var host = location.hostname;
+ var port = ':' + location.port;
+ if (port == ':80' || port == ':443' || port == ':')
+ port = '';
+ var link = protocol + '//' + host + port + '/' + appname + '/';
+ return link;
+}
+
+/**
+ * Set page titles.
+ */
+document.title = config.windowtitle() + ' - Page - ' + appname;
+
+/**
+ * Set header div.
+ */
+$('viewhead').innerHTML = '<span id="appTitle" class="cmenu">' + appname + '</span>' +
+'<input type="button" id="deleteWidgetButton" title="Delete a Widget" class="graybutton redbutton plusminus" style="position: absolute; top: 4px; left: 5px;" disabled="true" value="-"/>' +
+'<span style="position: absolute; top: 0px; left: 45px; right: 115px; padding: 0px; background: transparent;"><input id="widgetValue" type="text" value="" class="flatentry" title="Widget value" autocapitalize="off" placeholder="Value" style="position: absolute; left: 0px; top: 4px; width: 100%; visibility: hidden;" readonly="readonly"/></span>' +
+'<input type="button" id="playPageButton" title="View page" class="graybutton plusminus" style="position: absolute; top: 4px; right: 75px;" value="&gt;"/>' +
+'<input type="button" id="copyWidgetButton" title="Copy a Widget" class="graybutton bluebutton" style="position: absolute; top: 4px; right: 40px; font-size: 16px;" disabled="true" value="C"/>' +
+'<input type="button" id="addWidgetButton" title="Add a Widget" class="graybutton bluebutton plusminus" style="position: absolute; top: 4px; right: 5px;" disabled="true" value="+"/>';
+
+/**
+ * Track the current page, author, and saved XHTML content.
+ */
+var author = '';
+var editable = false;
+var savedpagexhtml = '';
+
+/**
+ * Page editor area, widget value field, add, delete and play page buttons.
+ */
+var cdiv = $('contentdiv');
+var pagediv = $('pagediv');
+var evisible = true;
+var pdiv = $('playdiv');
+var wadd = $('addWidgetButton');
+var wdelete = $('deleteWidgetButton');
+var wcopy = $('copyWidgetButton');
+var wvalue = $('widgetValue');
+var atitle = $('appTitle');
+var pplay = $('playPageButton');
+
+/**
+ * Set images.
+ */
+$('imgimg').src = ui.b64img(appcache.get('/public/img.b64'));
+
+/**
+ * Init component references.
+ */
+var editorComp = sca.component('Editor');
+var pages = sca.reference(editorComp, 'pages');
+
+/**
+ * Page editing functions.
+ */
+var page = {};
+
+/**
+ * Default positions and sizes.
+ */
+page.palcx = 2500;
+
+/**
+ * Init a page editor.
+ */
+page.mkedit = function(pagediv, atitle, wvalue, wadd, wcopy, wdelete, onchange, onselect) {
+
+ // Track element dragging and selection
+ page.dragging = null;
+ page.selected = null;
+ wvalue.readOnly = true;
+ wvalue.style.visibility = 'hidden';
+ atitle.style.visibility = 'visible';
+ page.mousemoved = false;
+ wcopy.disabled = true;
+ wdelete.disabled = true;
+ wadd.disabled = !editable;
+
+ // Trigger widget select and page change events
+ page.onpagechange = onchange;
+ page.onselectwidget = onselect;
+
+ /**
+ * Handle a mouse down event.
+ */
+ function onmousedown(e) {
+ // On mouse controlled devices, run component selection logic right away
+ var selected = page.selected;
+ if (typeof e.touches == 'undefined') {
+ //debug('onmousedown-click');
+ onclick(e);
+ }
+
+ // Find a draggable element
+ var dragging = page.draggable(e.target, pagediv);
+ if (dragging == null || dragging != page.selected)
+ return true;
+ page.dragging = dragging;
+
+ // Remember mouse position
+ var pos = typeof e.touches != "undefined"? e.touches[0] : e;
+ page.mousemoved = false;
+ page.dragX = pos.screenX;
+ page.dragY = pos.screenY;
+ page.moveX = pos.screenX;
+ page.moveY = pos.screenY;
+
+ // Prevent default behavior on first click on a widget
+ if (e.preventDefault)
+ e.preventDefault();
+ else
+ e.returnValue = false;
+
+ return true;
+ }
+
+ if (!ui.isMobile()) {
+ pagediv.onmousedown = function(e) {
+ //debug('onmousedown');
+ return onmousedown(e);
+ };
+ } else {
+ pagediv.ontouchstart = function(e) {
+ //debug('ontouchstart');
+ return onmousedown(e);
+ };
+ }
+
+ /**
+ * Handle a mouse up event.
+ */
+ function onmouseup(e) {
+ if (page.dragging == null)
+ return true;
+
+ // Snap to grid
+ var newX = page.gridsnap(ui.numpos(page.dragging.style.left));
+ var newY = page.gridsnap(ui.numpos(page.dragging.style.top));
+ page.dragging.style.left = ui.pixpos(newX);
+ page.dragging.style.top = ui.pixpos(newY);
+
+ // Fixup widget style
+ page.initwidget(page.dragging);
+
+ // Forget dragged element
+ page.dragging = null;
+
+ // Trigger page change event
+ page.onpagechange(false);
+
+ // Simulate onclick event
+ onclick(e);
+
+ return true;
+ }
+
+ if (!ui.isMobile()) {
+ pagediv.onmouseup = function(e) {
+ //debug('onmouseup');
+ return onmouseup(e);
+ };
+ } else {
+ pagediv.ontouchend = function(e) {
+ //debug('ontouchend');
+ return onmouseup(e);
+ }
+ }
+
+ /**
+ * Handle a mouse move event.
+ */
+ function onmousemove(e) {
+
+ // Track mouse moves
+ page.mousemoved = true;
+
+ if (page.dragging == null)
+ return true;
+
+ // Ignore duplicate mouse move events
+ if (page.moveX == page.dragX && page.moveY == page.dragY)
+ return true;
+
+ // Compute position of dragged element
+ var curX = ui.numpos(page.dragging.style.left);
+ var curY = ui.numpos(page.dragging.style.top);
+ var newX = curX + (page.moveX - page.dragX);
+ var newY = curY + (page.moveY - page.dragY);
+ if (newX >= page.palcx)
+ page.dragX = page.moveX;
+ else
+ newX = page.palcx;
+ if (newY >= 0)
+ page.dragY = page.moveY;
+ else
+ newY = 0;
+
+ // Move the dragged element
+ page.dragging.style.left = ui.pixpos(newX);
+ page.dragging.style.top = ui.pixpos(newY);
+ page.constrainwidget(page.dragging);
+
+ return true;
+ }
+
+ if (!ui.isMobile()) {
+ window.onmousemove = function(e) {
+
+ // Remember mouse position
+ page.moveX = e.screenX;
+ page.moveY = e.screenY;
+
+ return onmousemove(e);
+ };
+ } else {
+ pagediv.ontouchmove = function(e) {
+
+ // Remember touch position
+ var pos = e.touches[0];
+ if (page.moveX == pos.screenX && page.moveY == pos.screenY)
+ return true;
+ page.moveX = pos.screenX;
+ page.moveY = pos.screenY;
+ if (page.moveX == page.dragX && page.moveY == page.dragY)
+ return true;
+
+ onmousemove(e);
+ };
+ }
+
+ /**
+ * Handle a mouse click event.
+ */
+ function onclick(e) {
+
+ // Find selected element
+ var selected = page.draggable(e.target, pagediv);
+ if (selected == null) {
+ if (page.selected != null) {
+
+ // Reset current selection
+ page.selectwidget(page.selected, false, atitle, wvalue, wcopy, wdelete);
+ page.selected = null;
+
+ // Trigger widget select event
+ page.onselectwidget(null);
+ }
+
+ // Dismiss the palette
+ if (ui.numpos(pagediv.style.left) != (page.palcx * -1))
+ pagediv.style.left = ui.pixpos(page.palcx * -1);
+
+ return true;
+ }
+
+ // Deselect the previously selected element
+ page.selectwidget(page.selected, false, atitle, wvalue, wcopy, wdelete);
+
+ // Clone element dragged from palette
+ if (selected.id.substring(0, 8) == 'palette:') {
+ page.selected = page.clone(selected);
+
+ // Move into the editing area and hide the palette
+ page.selected.style.left = ui.pixpos(ui.numpos(page.selected.style.left) + page.palcx);
+ page.initwidget(page.selected);
+ pagediv.style.left = ui.pixpos(page.palcx * -1);
+ page.constrainwidget(page.selected);
+
+ // Bring it to the top
+ page.bringtotop(page.selected);
+
+ // Trigger page change event
+ page.onpagechange(true);
+
+ // Select the element
+ page.selectwidget(page.selected, true, atitle, wvalue, wcopy, wdelete);
+
+ // Trigger widget select event
+ page.onselectwidget(page.selected);
+
+ return true;
+
+ }
+
+ // Bring selected element to the top
+ page.selected = selected;
+ page.bringtotop(page.selected);
+
+ // Select the element
+ page.selectwidget(page.selected, true, atitle, wvalue, wcopy, wdelete);
+
+ // Trigger widget select event
+ page.onselectwidget(page.selected);
+
+ return true;
+ }
+
+ if (!ui.isMobile()) {
+ pagediv.onclick = function(e) {
+ //debug('onclick');
+ return onclick(e);
+ };
+ } else {
+ pagediv.onclick = function(e) {
+ //debug('onclick');
+ return onclick(e);
+ };
+ }
+
+ /**
+ * Handle field on change events.
+ */
+ wvalue.onchange = wvalue.onblur = function() {
+ if (page.selected == null)
+ return false;
+ page.settext(page.selected, wvalue.value);
+
+ // Trigger page change event
+ page.onpagechange(true);
+ return false;
+ };
+
+ // Handle add widget event.
+ wadd.onclick = function() {
+
+ // Show the palette
+ pagediv.style.left = ui.pixpos(0);
+ return false;
+ };
+
+ // Handle delete event.
+ wdelete.onclick = function() {
+ if (page.selected == null)
+ return false;
+
+ // Reset current selection
+ page.selectwidget(page.selected, false, atitle, wvalue, wcopy, wdelete);
+
+ // Remove selected widget
+ page.selected.parentNode.removeChild(page.selected);
+ page.selected = null;
+
+ // Trigger widget select event
+ page.onselectwidget(null);
+
+ // Trigger page change event
+ page.onpagechange(true);
+ return false;
+ };
+
+ // Handle copy event.
+ wcopy.onclick = function() {
+ if (page.selected == null)
+ return false;
+ if (page.selected.id.substring(0, 8) == 'palette:')
+ return false;
+
+ // Reset current selection
+ page.selectwidget(page.selected, false, atitle, wvalue, wcopy, wdelete);
+
+ // Clone selected widget
+ page.selected = page.clone(page.selected);
+
+ // Move 10 pixels down right
+ page.selected.style.left = ui.pixpos(ui.numpos(page.selected.style.left) + 10);
+ page.selected.style.top = ui.pixpos(ui.numpos(page.selected.style.top) + 10);
+ page.constrainwidget(page.selected);
+
+ // Bring it to the top
+ page.bringtotop(page.selected);
+
+ // Select the element
+ page.selectwidget(page.selected, true, atitle, wvalue, wcopy, wdelete);
+
+ // Trigger widget select event
+ page.onselectwidget(page.selected);
+
+ // Trigger page change event
+ page.onpagechange(true);
+ return false;
+ };
+
+ return pagediv;
+};
+
+/**
+ * Return the text of a widget.
+ */
+page.text = function(e) {
+ function formula(e) {
+ var f = e.id;
+ if (f.substring(0, 5) != 'page:')
+ return '=' + f;
+ return '';
+ }
+
+ function constant(e, f) {
+ if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section') {
+ var t = car(childElements(e)).innerHTML;
+ return t == f? '' : t;
+ }
+ if (e.className == 'button' || e.className == 'checkbox') {
+ var t = car(childElements(e)).value;
+ return t == f? '' : t;
+ }
+ if (e.className == 'entry' || e.className == 'password') {
+ var t = car(childElements(e)).defaultValue;
+ return t == f? '' : t;
+ }
+ /*
+ if (e.className == 'select') {
+ var t = car(childElements(car(childElements(e)))).value;
+ return t == f? '' : t;
+ }
+ */
+ if (e.className == 'link') {
+ var lhr = car(childElements(e)).href;
+ var hr = lhr.substring(0, 5) == 'link:'? lhr.substring(5) : '';
+ var t = car(childElements(car(childElements(e)))).innerHTML;
+ return t == f? hr : (t == hr? hr : (t == ''? hr : hr + ',' + t));
+ }
+ if (e.className == 'img') {
+ var src = car(childElements(e)).src;
+ return src == location.href? '' : src;
+ }
+ /*
+ if (e.className == 'iframe') {
+ var hr = car(childElements(e)).href;
+ return hr == location.href? '' : hr;
+ }
+ */
+ if (e.className == 'list')
+ return '';
+ if (e.className == 'table')
+ return '';
+ return '';
+ }
+
+ var f = formula(e);
+ var c = constant(e, f);
+ return f == ''? c : (c == ''? f : f + ',' + c);
+};
+
+/**
+ * Return true if a widget has editable text.
+ */
+page.hastext = function(e) {
+ if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section')
+ return true;
+ if (e.className == 'button' || e.className == 'checkbox')
+ return true;
+ if (e.className == 'entry' || e.className == 'password')
+ return true;
+ /*
+ if (e.className == 'select')
+ return false;
+ */
+ if (e.className == 'link')
+ return true;
+ if (e.className == 'img')
+ return true;
+ /*
+ if (e.className == 'iframe')
+ return true;
+ */
+ if (e.className == 'list')
+ return false;
+ if (e.className == 'table')
+ return false;
+ return false;
+};
+
+/**
+ * Set the text of a widget.
+ */
+page.settext = function(e, t) {
+ function formula(t) {
+ if (t.length > 1 && t.substring(0, 1) == '=')
+ return car(t.split(','));
+ return '';
+ }
+
+ function constant(t) {
+ return t.length > 1 && t.substring(0, 1) == '='? cdr(t.split(',')) : t.split(',');
+ }
+
+ var f = formula(t);
+ var c = constant(t);
+
+ e.id = f != ''? f.substring(1) : ('page:' + e.className);
+
+ if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section') {
+ car(childElements(e)).innerHTML = isNil(c)? f : car(c);
+ return t;
+ }
+ if (e.className == 'button') {
+ car(childElements(e)).value = isNil(c)? f : car(c);
+ return t;
+ }
+ if (e.className == 'entry' || e.className == 'password') {
+ car(childElements(e)).defaultValue = isNil(c)? f : car(c);
+ return t;
+ }
+ if (e.className == 'checkbox') {
+ car(childElements(e)).value = isNil(c)? f : car(c);
+ map(function(n) { if (n.nodeName == "SPAN") n.innerHTML = isNil(c)? f : car(c); return n; }, nodeList(e.childNodes));
+ return t;
+ }
+ /*
+ if (e.className == 'select') {
+ var ce = car(childElements(car(childElements(e))));
+ ce.value = isNil(c)? f : car(c);
+ ce.innerHTML = isNil(c)? f : car(c);
+ return t;
+ }
+ */
+ if (e.className == 'list') {
+ e.innerHTML = '<table class="datatable" style="width: 100%;;"><tr><td class="datatd">' + (isNil(c)? f : car(c)) + '</td></tr><tr><td class="datatd">...</td></tr></table>';
+ return t;
+ }
+ if (e.className == 'table') {
+ e.innerHTML = '<table class="datatable" style="width: 100%;"><tr><td class="datatdl">' + (isNil(c)? f : car(c)) + '</td><td class="datatdr">...</td></tr><tr><td class="datatdl">...</td><td class="datatdr">...</td></tr></table>';
+ return t;
+ }
+ if (e.className == 'link') {
+ var ce = car(childElements(e));
+ ce.href = isNil(c)? 'link:/index.html' : ('link:' + car(c));
+ car(childElements(ce)).innerHTML = isNil(c)? (f != ''? f : '/index.html') : isNil(cdr(c))? (f != ''? f : car(c)) : cadr(c);
+ return t;
+ }
+ if (e.className == 'img') {
+ car(childElements(e)).src = isNil(c)? '/public/img.png' : car(c);
+ return t;
+ }
+ /*
+ if (e.className == 'iframe') {
+ car(childElements(e)).href = isNil(c)? '/public/iframe-min.html' : car(c);
+ return t;
+ }
+ */
+ return '';
+};
+
+/**
+ * Initialize a widget.
+ */
+page.initwidget = function(e) {
+
+ // Add a Webkit transform to leverage hardware acceleration
+ e.style.setProperty('-webkit-transform', 'translate(0px, 0px)', null);
+
+ /*
+ if (e.className == 'iframe') {
+ var f = car(childElements(e));
+ //e.innerHTML = '<iframe src="' + f.href + '" frameborder="no" scrolling="no"></iframe>';
+ return e;
+ }
+ */
+
+ if (e.className == 'section') {
+ e.style.width = '100%';
+ return e;
+ }
+ if (e.className == 'text' || e.className == 'h1' || e.className == 'h2') {
+ return e;
+ }
+ if (e.className == 'button') {
+ return e;
+ }
+ if (e.className == 'checkbox') {
+ return e;
+ }
+ if (e.className == 'list' || e.className == 'table') {
+ e.style.width = '100%';
+ var t = car(childElements(e));
+ t.style.width = '100%';
+ return e;
+ }
+ if (e.className == 'img') {
+ var i = car(childElements(e));
+ if (i.src != '' && i.src.substring(0, 5) == 'data:')
+ i.src = '/public/img.png';
+ return e;
+ }
+ if (e.className == 'entry' || e.className == 'password') {
+ var i = car(childElements(e));
+ i.readOnly = true;
+ i.style.cursor = 'default';
+ return e;
+ }
+ if (e.className == 'link') {
+ var l = car(childElements(e));
+ l.onclick = function(e) { return false; };
+ return e;
+ }
+ return e;
+}
+
+/**
+ * Enforce widget position and style constraints.
+ */
+page.constrainwidget = function(e) {
+ if (e.className == 'section' || e.className == 'list' || e.className == 'table') {
+ e.style.left = ui.pixpos(page.palcx);
+ return e;
+ }
+ return e;
+};
+
+/**
+ * Cleanup of a widget before saving it.
+ */
+page.cleanupwidget = function(e) {
+ //debug('cleanupwidget', e);
+
+ // Clear outline
+ e.style.outline = null;
+
+ // Clear the Webkit transform
+ e.style.removeProperty('-webkit-transform');
+
+ if (e.className == 'entry' || e.className == 'password') {
+ var i = car(childElements(e));
+ i.readOnly = false;
+ i.style.cursor = null;
+ return e;
+ }
+ if (e.className == 'link') {
+ var l = car(childElements(e));
+ l.onclick = null;
+ return e;
+ }
+ return e;
+}
+
+/**
+ * Find a draggable element in a hierarchy of elements.
+ */
+page.draggable = function(n, e) {
+ if (n == e)
+ return null;
+ if (!isNil(n.id) && n.id != '')
+ return n;
+ return page.draggable(n.parentNode, e);
+}
+
+/**
+ * Align a pos along a 9pixel grid.
+ */
+page.gridsnap = function(x) {
+ return Math.round(x / 9) * 9;
+}
+
+/**
+ * Bring an element and its parent to the top.
+ */
+page.bringtotop = function(n) {
+ n.parentNode.appendChild(n);
+}
+
+/**
+ * Select a widget.
+ */
+page.selectwidget = function(n, s, atitle, wvalue, wcopy, wdelete) {
+ //debug('selectwidget', n, s);
+ if (isNil(n) || !s) {
+ // Clear the widget value field
+ wvalue.value = '';
+ wvalue.readOnly = true;
+ wvalue.style.visibility = 'hidden';
+ atitle.style.visibility = 'visible';
+ wcopy.disabled = true;
+ wdelete.disabled = true;
+
+ // Clear the widget outline
+ if (!isNil(n))
+ n.style.outline = null;
+
+ return true;
+ }
+
+ // Outline the widget
+ n.style.outline = '2px solid #598edd';
+
+ // Update the widget value field
+ wvalue.value = page.text(n);
+ wvalue.readOnly = false || !editable;
+ wvalue.style.visibility = 'visible';
+ atitle.style.visibility = 'hidden';
+ wcopy.disabled = false || !editable;
+ wdelete.disabled = false || !editable;
+
+ return true;
+};
+
+/**
+ * Clone a palette element.
+ */
+page.clone = function(e) {
+
+ /**
+ * Clone an element's HTML.
+ */
+ function mkclone(e) {
+ var ne = document.createElement('span');
+
+ // Skip the palette: prefix
+ ne.id = 'page:' + e.id.substr(8);
+
+ // Copy the class and HTML content
+ ne.className = e.className;
+ ne.innerHTML = e.innerHTML;
+
+ // Fixup the widget style
+ page.initwidget(ne);
+
+ return ne;
+ }
+
+ /**
+ * Clone an element's position.
+ */
+ function posclone(ne, e) {
+ ne.style.position = 'absolute';
+ ne.style.left = ui.pixpos(ui.numpos(e.style.left));
+ ne.style.top = ui.pixpos(ui.numpos(e.style.top));
+ e.parentNode.appendChild(ne);
+ return ne;
+ }
+
+ return posclone(mkclone(e), e);
+};
+
+/**
+ * Track the current widget.
+ */
+var widget = null;
+
+/**
+ * Get and display an app page.
+ */
+function getpage(name, pagediv) {
+ if (isNil(name))
+ return false;
+ showStatus('Loading');
+
+ return pages.get(name, function(doc) {
+
+ // Stop now if we didn't get a page
+ if (doc == null) {
+ showError('App not available');
+ return false;
+ }
+
+ // Get the page from the ATOM entry, convert it to XHTML and place it in a hidden buffer
+ var pageentry = car(atom.readATOMEntry(mklist(doc)));
+ var content = namedElementChild("'content", pageentry);
+ var el = isNil(content)? mklist() : elementChildren(content);
+ var buffer = $('buffer');
+ if (isNil(el))
+ buffer.innerHTML = '<div id="page"></div>';
+ else
+ buffer.innerHTML = writeStrings(writeXML(el, false));
+
+ // Remove any existing page nodes from the editor div
+ var fnodes = filter(function(e) {
+ if (isNil(e.id) || e.id == '' || e.id.substr(0, 8) == 'palette:')
+ return false;
+ var x = ui.numpos(e.style.left) - 2500;
+ if (x < 0 || ui.numpos(e.style.top) < 0)
+ return false;
+ return true;
+ }, nodeList(pagediv.childNodes));
+
+ map(function(e) {
+ pagediv.removeChild(e);
+ }, fnodes);
+
+ // Append new page nodes to editor
+ map(function(e) {
+ pagediv.appendChild(e);
+ if (!isNil(e.style))
+ e.style.left = ui.pixpos(ui.numpos(e.style.left) + 2500);
+ page.initwidget(e);
+ return e;
+ }, nodeList(buffer.childNodes[0].childNodes));
+
+ savedpagexhtml = pagexhtml(pagediv);
+
+ // Enable author to edit the page
+ author = elementValue(namedElementChild("'author", pageentry));
+ editable = author == username;
+ wadd.disabled = !editable;
+ showStatus(editable? onlineStatus() : 'Read only');
+
+ return true;
+ });
+}
+
+/**
+ * Handle add widget button click event.
+ */
+wadd.onclick = function(e) {
+ // Show the widget palette
+ pagediv.style.left = ui.pixpos(0);
+};
+
+/**
+ * Return the current page XHTML content.
+ */
+function pagexhtml(pagediv) {
+
+ // Copy page DOM to hidden buffer
+ var buffer = $('buffer');
+ buffer.innerHTML = '<div id="page"></div>'
+ var div = buffer.childNodes[0];
+
+ // Capture the nodes inside the page div
+ div.innerHTML = pagediv.innerHTML;
+ var nodes = nodeList(div.childNodes);
+ map(function(e) {
+ div.removeChild(e);
+ return e;
+ }, nodes);
+
+ // Filter out palette and editor artifacts, which are not
+ // part of the page, as well as nodes positioned out the
+ // editing area
+ var fnodes = filter(function(e) {
+ if (isNil(e.id) || e.id == '' || e.id.substr(0, 8) == 'palette:')
+ return false;
+ var x = ui.numpos(e.style.left) - 2500;
+ if (x < 0 || ui.numpos(e.style.top) < 0)
+ return false;
+ return true;
+ }, nodes);
+
+ // Reposition and cleanup nodes
+ map(function(e) {
+ var x = ui.numpos(e.style.left) - 2500;
+ e.style.left = ui.pixpos(x);
+ page.cleanupwidget(e);
+ return e;
+ }, fnodes);
+
+ // Sort them by position
+ var snodes = fnodes.sort(function(a, b) {
+ var ay = ui.numpos(a.style.top);
+ var by = ui.numpos(b.style.top);
+ if (ay < by) return -1;
+ if (ay > by) return 1;
+ var ax = ui.numpos(a.style.left);
+ var bx = ui.numpos(b.style.left);
+ if (ax < bx) return -1;
+ if (ax > bx) return 1;
+ return 0;
+ });
+
+ // Append the sorted nodes back to the div in order
+ map(function(e) {
+ div.appendChild(e);
+ return e;
+ }, snodes);
+
+ // Convert the page to XHTML
+ var lxhtml = readXHTMLElement(div);
+ var xhtml = writeStrings(writeXML(lxhtml, false));
+ return xhtml;
+}
+
+/**
+ * Save the current page.
+ */
+function save(newxml) {
+ showStatus('Saving');
+
+ // Get the current page XHTML content
+ savedpagexhtml = newxml;
+
+ // Update the page ATOM entry
+ var entry = '<?xml version="1.0" encoding="UTF-8"?>\n' + '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ '<title type="text">' + appname + '</title><id>' + appname + '</id><author><email>' + author + '</email></author>' +
+ '<content type="application/xml">' + newxml + '</content></entry>';
+
+ pages.put(appname, entry, function(e) {
+ if (e) {
+ showStatus('Local copy');
+ return false;
+ }
+ showStatus('Saved');
+ return false;
+ });
+ return true;
+};
+
+/**
+ * Handle a page change event
+ */
+function onpagechange(prop) {
+ if (!editable)
+ return false;
+
+ var newxml = pagexhtml(pagediv);
+ if (savedpagexhtml == newxml)
+ return false;
+ showStatus('Modified');
+
+ // Save property changes right away
+ if (prop)
+ return save(newxml);
+
+ // Autosave other changes after 1 second
+ setTimeout(function() {
+ if (savedpagexhtml == newxml) {
+ showStatus('Saved');
+ return false;
+ }
+ return save(newxml);
+ }, 1000);
+ return true;
+}
+
+/**
+ * Handle a widget select event.
+ */
+function onselectwidget(w) {
+ if (w == widget)
+ return true;
+ widget = w;
+ return true;
+}
+
+/**
+ * Play page in a frame.
+ */
+function playpage() {
+ if (!evisible)
+ return true;
+ page.selectwidget(widget, false, atitle, wvalue, wcopy, wdelete);
+ page.selected = null;
+ pplay.value = '<';
+ evisible = false;
+ pdiv.style.visibility = 'visible';
+ pdiv.innerHTML = '';
+ pdiv.innerHTML = '<iframe id="playappframe" style="position: relative; height: 5000px; width: 2500px; border: 0px;" scrolling="no" frameborder="0" src="/' +
+ appname + '"></iframe>';
+ setTimeout(function() {
+ pagediv.style.visibility = 'hidden'
+ }, 0);
+ return true;
+}
+
+/**
+ * Show the page editor.
+ */
+function showedit() {
+ if (evisible)
+ return true;
+ pplay.value = '>';
+ pagediv.style.visibility = 'visible'
+ evisible = true;
+ page.selectwidget(widget, true, atitle, wvalue, wcopy, wdelete);
+ page.selected = widget;
+ setTimeout(function() {
+ pdiv.style.visibility = 'hidden';
+ pdiv.innerHTML = '';
+ }, 0);
+ return true;
+}
+
+/**
+ * Handle play page button event.
+ */
+pplay.onclick = function() {
+ if (!evisible)
+ return showedit();
+ return playpage();
+}
+
+/**
+ * Initialize the page editor.
+ */
+page.mkedit(pagediv, atitle, wvalue, wadd, wcopy, wdelete, onpagechange, onselectwidget);
+
+/**
+ * Get and display the current app page.
+ */
+getpage(appname, pagediv);
+
+})();
+</script>
+
+</div>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/proxy/public/oops/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/proxy/public/oops/index.html
new file mode 100644
index 0000000000..b1d118d59a
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/proxy/public/oops/index.html
@@ -0,0 +1,193 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Oops</title>
+<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"/>
+<meta name="apple-mobile-web-app-capable" content="yes"/>
+<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
+<base href="/proxy/public/oops/"/>
+<script type="text/javascript">
+(function() {
+
+window.appcache = {};
+
+/**
+ * Get and cache a resource.
+ */
+appcache.get = function(uri) {
+ var h = uri.indexOf('#');
+ var u = h == -1? uri : uri.substring(0, h);
+
+ // Get resource from local storage first
+ var ls = window.lstorage || localStorage;
+ var item = null;
+ try { item = ls.getItem(u); } catch(e) {}
+ if (item != null && item != '')
+ return item;
+
+ // Get resource from network
+ var http = new XMLHttpRequest();
+ http.open("GET", u, false);
+ http.setRequestHeader("Accept", "*/*");
+ http.send(null);
+ if (http.status == 200) {
+ if (http.getResponseHeader("X-Login") != null) {
+ if (window.debug) debug('http error', u, 'X-Login');
+ return null;
+ } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
+ if (window.debug) debug('http error', u, 'No-Content');
+ return null;
+ }
+ try { ls.setItem(u, http.responseText); } catch(e) {}
+ return http.responseText;
+ }
+ if (window.debug) debug('http error', u, http.status, http.statusText);
+ return null;
+};
+
+})();
+
+/**
+ * Load Javascript and CSS.
+ */
+(function() {
+
+var bootjs = document.createElement('script');
+bootjs.type = 'text/javascript';
+bootjs.text = appcache.get('/proxy/all-min.js');
+document.head.appendChild(bootjs);
+document.head.appendChild(ui.declareCSS(appcache.get('/proxy/ui-min.css')));
+
+})();
+
+</script>
+</head>
+<body class="delayed">
+<div id="mainbodydiv" class="mainbodydiv">
+
+<div id="headdiv" class="hsection">
+<script type="text/javascript">
+(function() {
+
+$('headdiv').appendChild(ui.declareScript(appcache.get('/proxy/public/config-min.js')));
+
+})();
+</script>
+</div>
+
+<div id="menubackground" class="tbarbackground fixed"></div>
+<div id="menu" class="tbarmenu fixed"></div>
+
+<div id="viewheadbackground" class="viewheadbackground fixed"></div>
+<div id="viewhead" class="viewhead fixed"></div>
+
+<div id="viewcontainer">
+<div id="view">
+<div id="viewcontent" class="viewcontent" style="margin-left: auto; margin-right: auto; text-align: center;">
+
+<br/>
+<div class="hd2">Oops, something went wrong...</div>
+
+</div>
+</div>
+</div>
+
+<div id="viewfootbackground" class="viewfootbackground fixed"></div>
+<div id="viewfoot" class="viewfoot fixed"></div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Init div variables.
+ */
+var mdiv = $('menu');
+var hdiv = $('viewhead');
+$('viewcontainer').className = ui.isMobile()? 'viewcontainer3d' : 'viewcontainer3dm';
+$('view').className = ui.isMobile()? 'viewloaded3d' : 'viewloaded3dm';
+var fdiv = $('viewfoot');
+
+/**
+ * Set page title.
+ */
+document.title = config.windowtitle() + ' - Oops';
+$('viewhead').innerHTML = '<span class="bcmenu">' + config.pagetitle() + '</span>';
+
+/**
+ * Build and show the menu bar.
+ */
+function showmenu(mdiv) {
+ mdiv.innerHTML = ui.menubar(
+ mklist(ui.menu('menuhome', 'Home', '/', '_self', false)),
+ mklist(hasauthcookie()? ui.menufunc('menusignout', 'Sign out', 'return logout();', false) : ui.menu('menusignin', 'Sign in', '/login/', '_self', false)));
+ fdiv.innerHTML = config.viewfoot();
+}
+
+showmenu(mdiv);
+
+/**
+ * Log the current user out.
+ */
+window.logout = function() {
+ // Clear session cookie and user-specific local storage entries
+ clearauthcookie();
+ lstorage.removeItem('/r/Editor/accounts');
+ lstorage.removeItem('/r/Editor/dashboards');
+ document.location = '/login/';
+ return false;
+}
+
+/**
+ * Handle orientation change.
+ */
+document.body.onorientationchange = function(e) {
+ //debug('onorientationchange');
+ ui.onorientationchange(e);
+
+ // Resize menu and view header
+ mdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
+ hdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
+ return true;
+};
+
+/**
+ * Initialize the document.
+ */
+function onload() {
+ //debug('onload');
+ ui.onload();
+
+ // Show the page
+ document.body.style.visibility = 'visible';
+ return true;
+}
+
+onload();
+
+})();
+</script>
+
+<div id="footdiv" class="fsection">
+</div>
+
+</div>
+</body>
+</html>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/app.b64 b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/app.b64
new file mode 100644
index 0000000000..7ed235aa14
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/app.b64
@@ -0,0 +1 @@
+iVBORw0KGgoAAAANSUhEUgAAADIAAAAyAgMAAABjUWAiAAAABGdBTUEAALGPC/xhBQAAAAxQTFRFyN+N+dR1/PCI////6HjE5gAAADJJREFUKM9j+I8EPjBQifeBAQSY6coLBYN6inhaq0Bg6SDn/f//akB466ExTS6P2ukMAKumzarJO/66AAAAAElFTkSuQmCC \ No newline at end of file
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/app.png b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/app.png
new file mode 100644
index 0000000000..1f73274b76
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/app.png
Binary files differ
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/app.xcf b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/app.xcf
new file mode 100644
index 0000000000..741b7ff43f
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/app.xcf
Binary files differ
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/config.js b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/config.js
new file mode 100644
index 0000000000..54818f4810
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/config.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+if (isNil(config))
+ config = {};
+
+/**
+ * UI configuration.
+ */
+config.windowtitle = function() {
+ return 'App Builder';
+};
+
+config.pagetitle = function() {
+ return '<span style="font-weight: bold;">App Builder</span>';
+};
+
+config.loginprompt = function() {
+ return '<span>Sign in with your userid and password</span>';
+};
+
+config.viewfoot = function() {
+ return ui.menubar(mklist(ui.menu('menuabout', 'About', '/', '_view', 'note')), mklist());
+};
+
+config.appresources = function() {
+ return mklist();
+};
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/delete.b64 b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/delete.b64
new file mode 100644
index 0000000000..c8137d7ab4
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/delete.b64
@@ -0,0 +1 @@
+iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAAXNSR0IArs4c6QAAAAZiS0dEANAAPwBBXloXjQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sEFhQaKzNh4PgAAAMKSURBVEjHxZZPTBNBFMa/maVbWjcUi0YiIHIoNBADTUgsqCWgUUFjwkk5CXLUBKIc9KIXjx64oMSDoiggGC8koImCGDWYkADRIiQQgikWCq0WoXW33R0PpYjSLeWP8btN3sv85s17894QrKNeIBng8gFmJSDZgGIAqJeBjQCkH5AHioGZaHsQNUMP+ByKYB0ByVjvIAxsUkHcrRJI9pggXYBWB1pLQUqxQSlg3X4o9WWAqArpAhL04JoIYMQmxQCPD3JlGbCwBtIFaPXgWrcC+AtUEY6Ihg060NrtACyf3KgDrQ2v6e8kbzwH0URBSnvA56xAKIJ1kRzNbS2ZNhYssjodVj41VbPaxqemaqxOh9XGgkXmtpbMyKDQvqQXSKbg2iKGzfPE0v8uV7BYDIuDg95B66FhJkmM8DyxfHifK+TlGRaHhryDBwuHmSSxyBUnn6Ohh6aSQElin86U26XZWVGwWAxZD5tMAGBufmAS8vIMkssl2s+Uj6gBQuLySS/oTQpyONr9GmxHhAMvnltovJZ+73vjTiyyJSmipHw8WTrkfd33Y52385arAr1EAF00R3HqixRwu38mnT61O35/uh4AJq7Ujc0/affEUGsCDfWi9TXX3uEOeDwBABCnp/3OO42uGPuAgQLUG4urueVRlsZo1ACANiVFZ7rTkBFjMXtpqJtGV9q1q3uNJ47vlpd88kTt5VEWCLLk6gtpeyrP74qheY5wlaB6AhSqOSUUFOzIun8vh8RxZKKmZvRrw20X0WjkxCKbceexo0Z3Z+d8wDUXVIeQdgrIA6rFl5DAmVsfZ1MtT+faO5zOxrtzADB1/Ybj28tX85wgxOU8e5pN9XqqHos8QIuBGQY2GTEPD5tM8en79P7x8aWxqurx1bbPZytGRYfDrzOZBHPzA5PanCkGZki4d3GQG7DNksFdLIFkpwBQAsmugHVvJ0AB6w5PypW79EOpZ4BnOwAM8Pih1P/R6gGgDBB9kCu3Clo1GcU1kGXQgg9yxWavTgHrXp6IC///t/Iv/l2/AGa0Qa2X0eC0AAAAAElFTkSuQmCC \ No newline at end of file
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/delete.png b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/delete.png
new file mode 100644
index 0000000000..fb56bae030
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/delete.png
Binary files differ
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/delete.xcf b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/delete.xcf
new file mode 100644
index 0000000000..7691f50cc5
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/delete.xcf
Binary files differ
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/grid72.b64 b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/grid72.b64
new file mode 100644
index 0000000000..34be13e5ca
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/grid72.b64
@@ -0,0 +1 @@
+iVBORw0KGgoAAAANSUhEUgAAAEgAAABIAgMAAAAog1vUAAAABGdBTUEAALGPC/xhBQAAAAlQTFRFwuD84/T+////fj9v9QAAACxJREFUOMtjWLUqa9WsVctWrYQxVjAMCqFQdBDCMOrUUaeOOnXUqYPPqZgAABmg/C7pJC7lAAAAAElFTkSuQmCC \ No newline at end of file
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/grid72.png b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/grid72.png
new file mode 100644
index 0000000000..cf6008171a
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/grid72.png
Binary files differ
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/iframe.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/iframe.html
new file mode 100644
index 0000000000..e2b862dbaa
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/iframe.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<html>
+<head>
+</head>
+<body style="margin:3px; padding: 0px; background-color: #dcdcdc;">
+
+<div>frame ...</div>
+
+</body>
+</html>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/img.b64 b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/img.b64
new file mode 100644
index 0000000000..97dae687a0
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/img.b64
@@ -0,0 +1 @@
+iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAAIRQTFRFwdt/w9yEw9+MxN2GxN6NxN+Oxd2Mxd6Nxt6Lx96Lx96Nx9+NyN6MyN+MyN+N8u2I8+2I+NBq+NFr+NFt+NFu+NJz+NN0+dR1+dR3+dZw+dh4+9Fy+9Nz++5++++B+++F/NNz/PCH/PCI/PGW/PKc/fKd/vzp/vzq/v7+/v/z/9Jx////nQZfHwAAAIxJREFUOMtj0CYAGKiiQANdUAPdBAZmFMCIYQUzHwrgpKECblYwYEJ2LYoCHi0FMBCEAmF0E3hkxFGABJICXnYWFhY2aVE4EENTwCWgCARKCCCFoUAJFQw9BYycnBz8eBSA04cqPhNAQIX+CiSFhIRE8CiQ10ROMNgUqKNnHGU5FCCrhqZAg7Z5Ey8AALiBh6brcmloAAAAAElFTkSuQmCC \ No newline at end of file
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/img.png b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/img.png
new file mode 100644
index 0000000000..2363b25e8e
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/img.png
Binary files differ
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/img.xcf b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/img.xcf
new file mode 100644
index 0000000000..ffcc124584
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/img.xcf
Binary files differ
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/notauth/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/notauth/index.html
new file mode 100644
index 0000000000..89852393bf
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/notauth/index.html
@@ -0,0 +1,195 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Sorry</title>
+<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"/>
+<meta name="apple-mobile-web-app-capable" content="yes"/>
+<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
+<base href="/public/notauth/"/>
+<script type="text/javascript">
+(function() {
+
+window.appcache = {};
+
+/**
+ * Get and cache a resource.
+ */
+appcache.get = function(uri) {
+ var h = uri.indexOf('#');
+ var u = h == -1? uri : uri.substring(0, h);
+
+ // Get resource from local storage first
+ var ls = window.lstorage || localStorage;
+ var item = null;
+ try { item = ls.getItem(u); } catch(e) {}
+ if (item != null && item != '')
+ return item;
+
+ // Get resource from network
+ var http = new XMLHttpRequest();
+ http.open("GET", u, false);
+ http.setRequestHeader("Accept", "*/*");
+ http.send(null);
+ if (http.status == 200) {
+ if (http.getResponseHeader("X-Login") != null) {
+ if (window.debug) debug('http error', u, 'X-Login');
+ return null;
+ } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
+ if (window.debug) debug('http error', u, 'No-Content');
+ return null;
+ }
+ try { ls.setItem(u, http.responseText); } catch(e) {}
+ return http.responseText;
+ }
+ if (window.debug) debug('http error', u, http.status, http.statusText);
+ return null;
+};
+
+})();
+
+/**
+ * Load Javascript and CSS.
+ */
+(function() {
+
+var bootjs = document.createElement('script');
+bootjs.type = 'text/javascript';
+bootjs.text = appcache.get('/all-min.js');
+document.head.appendChild(bootjs);
+document.head.appendChild(ui.declareCSS(appcache.get('/ui-min.css')));
+
+})();
+
+</script>
+</head>
+<body class="delayed">
+<div id="mainbodydiv" class="mainbodydiv">
+
+<div id="headdiv" class="hsection">
+<script type="text/javascript">
+(function() {
+
+$('headdiv').appendChild(ui.declareScript(appcache.get('/public/config-min.js')));
+
+})();
+</script>
+</div>
+
+<div id="menubackground" class="tbarbackground fixed"></div>
+<div id="menu" class="tbarmenu fixed"></div>
+
+<div id="viewheadbackground" class="viewheadbackground fixed"></div>
+<div id="viewhead" class="viewhead fixed"></div>
+
+<div id="viewcontainer">
+<div id="view">
+<div id="viewcontent" class="viewcontent" style="margin-left: auto; margin-right: auto; text-align: center;">
+
+<br/>
+<div class="hd2">Sorry, you're not authorized to view this page.</div>
+
+</div>
+</div>
+</div>
+
+<div id="viewfootbackground" class="viewfootbackground fixed"></div>
+<div id="viewfoot" class="viewfoot fixed"></div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Init div variables.
+ */
+var mdiv = $('menu');
+var hdiv = $('viewhead');
+$('viewhead').innerHTML = '<span class="bcmenu">' + config.pagetitle() + '</span>';
+$('viewcontainer').className = ui.isMobile()? 'viewcontainer3d' : 'viewcontainer3dm';
+$('view').className = ui.isMobile()? 'viewloaded3d' : 'viewloaded3dm';
+var fdiv = $('viewfoot');
+
+/**
+ * Set page title.
+ */
+document.title = config.windowtitle() + ' - Sorry';
+$('viewhead').innerHTML = '<span class="bcmenu">' + config.pagetitle() + '</span>';
+
+/**
+ * Build and show the menu bar.
+ */
+function showmenu(mdiv) {
+ mdiv.innerHTML = ui.menubar(
+ mklist(ui.menu('menuhome', 'Home', '/', '_self', false)),
+ mklist(hasauthcookie()? ui.menufunc('menusignout', 'Sign out', 'return logout();', false) : ui.menu('menusignin', 'Sign in', '/login/', '_self', false)));
+ fdiv.innerHTML = config.viewfoot();
+}
+
+showmenu(mdiv);
+
+/**
+ * Log the current user out.
+ */
+window.logout = function() {
+ // Clear session cookie and user-specific local storage entries
+ clearauthcookie();
+ lstorage.removeItem('/r/Editor/accounts');
+ lstorage.removeItem('/r/Editor/dashboards');
+ document.location = '/login/';
+ return false;
+}
+
+/**
+ * Handle orientation change.
+ */
+document.body.onorientationchange = function(e) {
+ //debug('onorientationchange');
+ ui.onorientationchange(e);
+
+ // Resize menu and view header
+ mdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
+ hdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
+
+ return true;
+};
+
+/**
+ * Initialize the document.
+ */
+function onload() {
+ //debug('onload');
+ ui.onload();
+
+ // Show the page
+ document.body.style.visibility = 'visible';
+ return true;
+}
+
+onload();
+
+})();
+</script>
+
+<div id="footdiv" class="fsection">
+</div>
+
+</div>
+</body>
+</html>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/notfound/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/notfound/index.html
new file mode 100644
index 0000000000..8f0d486854
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/notfound/index.html
@@ -0,0 +1,194 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Page not found</title>
+<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"/>
+<meta name="apple-mobile-web-app-capable" content="yes"/>
+<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
+<base href="/public/notfound/"/>
+<script type="text/javascript">
+(function() {
+
+window.appcache = {};
+
+/**
+ * Get and cache a resource.
+ */
+appcache.get = function(uri) {
+ var h = uri.indexOf('#');
+ var u = h == -1? uri : uri.substring(0, h);
+
+ // Get resource from local storage first
+ var ls = window.lstorage || localStorage;
+ var item = null;
+ try { item = ls.getItem(u); } catch(e) {}
+ if (item != null && item != '')
+ return item;
+
+ // Get resource from network
+ var http = new XMLHttpRequest();
+ http.open("GET", u, false);
+ http.setRequestHeader("Accept", "*/*");
+ http.send(null);
+ if (http.status == 200) {
+ if (http.getResponseHeader("X-Login") != null) {
+ if (window.debug) debug('http error', u, 'X-Login');
+ return null;
+ } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
+ if (window.debug) debug('http error', u, 'No-Content');
+ return null;
+ }
+ try { ls.setItem(u, http.responseText); } catch(e) {}
+ return http.responseText;
+ }
+ if (window.debug) debug('http error', u, http.status, http.statusText);
+ return null;
+};
+
+})();
+
+/**
+ * Load Javascript and CSS.
+ */
+(function() {
+
+var bootjs = document.createElement('script');
+bootjs.type = 'text/javascript';
+bootjs.text = appcache.get('/all-min.js');
+document.head.appendChild(bootjs);
+document.head.appendChild(ui.declareCSS(appcache.get('/ui-min.css')));
+
+})();
+
+</script>
+</head>
+<body class="delayed">
+<div id="mainbodydiv" class="mainbodydiv">
+
+<div id="headdiv" class="hsection">
+<script type="text/javascript">
+(function() {
+
+$('headdiv').appendChild(ui.declareScript(appcache.get('/public/config-min.js')));
+
+})();
+</script>
+</div>
+
+<div id="menubackground" class="tbarbackground fixed"></div>
+<div id="menu" class="tbarmenu fixed"></div>
+
+<div id="viewheadbackground" class="viewheadbackground fixed"></div>
+<div id="viewhead" class="viewhead fixed"></div>
+
+<div id="viewcontainer">
+<div id="view">
+<div id="viewcontent" class="viewcontent" style="margin-left: auto; margin-right: auto; text-align: center;">
+
+<br/>
+<div class="hd2">Sorry, that page was not found.</div>
+<div>You may have clicked an expired link or mistyped the address.</div>
+
+</div>
+</div>
+</div>
+
+<div id="viewfootbackground" class="viewfootbackground fixed"></div>
+<div id="viewfoot" class="viewfoot fixed"></div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Init div variables.
+ */
+var mdiv = $('menu');
+var hdiv = $('viewhead');
+$('viewcontainer').className = ui.isMobile()? 'viewcontainer3d' : 'viewcontainer3dm';
+$('view').className = ui.isMobile()? 'viewloaded3d' : 'viewloaded3dm';
+var fdiv = $('viewfoot');
+
+/**
+ * Set page title.
+ */
+document.title = config.windowtitle() + ' - Page not found';
+$('viewhead').innerHTML = '<span class="bcmenu">' + config.pagetitle() + '</span>';
+
+/**
+ * Build and show the menu bar.
+ */
+function showmenu(mdiv) {
+ mdiv.innerHTML = ui.menubar(
+ mklist(ui.menu('menuhome', 'Home', '/', '_self', false)),
+ mklist(hasauthcookie()? ui.menufunc('menusignout', 'Sign out', 'return logout();', false) : ui.menu('menusignin', 'Sign in', '/login/', '_self', false)));
+ fdiv.innerHTML = config.viewfoot();
+}
+
+showmenu(mdiv);
+
+/**
+ * Log the current user out.
+ */
+window.logout = function() {
+ // Clear session cookie and user-specific local storage entries
+ clearauthcookie();
+ lstorage.removeItem('/r/Editor/accounts');
+ lstorage.removeItem('/r/Editor/dashboards');
+ document.location = '/login/';
+ return false;
+}
+
+/**
+ * Handle orientation change.
+ */
+document.body.onorientationchange = function(e) {
+ //debug('onorientationchange');
+ ui.onorientationchange(e);
+
+ // Resize menu and view header
+ mdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
+ hdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
+ return true;
+};
+
+/**
+ * Initialize the document.
+ */
+function onload() {
+ //debug('onload');
+ ui.onload();
+
+ // Show the page
+ document.body.style.visibility = 'visible';
+ return true;
+}
+
+onload();
+
+})();
+</script>
+
+<div id="footdiv" class="fsection">
+</div>
+
+</div>
+</body>
+</html>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/notyet/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/notyet/index.html
new file mode 100644
index 0000000000..e43a992f38
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/notyet/index.html
@@ -0,0 +1,194 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Page not found</title>
+<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"/>
+<meta name="apple-mobile-web-app-capable" content="yes"/>
+<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
+<base href="/public/notyet/"/>
+<script type="text/javascript">
+(function() {
+
+window.appcache = {};
+
+/**
+ * Get and cache a resource.
+ */
+appcache.get = function(uri) {
+ var h = uri.indexOf('#');
+ var u = h == -1? uri : uri.substring(0, h);
+
+ // Get resource from local storage first
+ var ls = window.lstorage || localStorage;
+ var item = null;
+ try { item = ls.getItem(u); } catch(e) {}
+ if (item != null && item != '')
+ return item;
+
+ // Get resource from network
+ var http = new XMLHttpRequest();
+ http.open("GET", u, false);
+ http.setRequestHeader("Accept", "*/*");
+ http.send(null);
+ if (http.status == 200) {
+ if (http.getResponseHeader("X-Login") != null) {
+ if (window.debug) debug('http error', u, 'X-Login');
+ return null;
+ } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
+ if (window.debug) debug('http error', u, 'No-Content');
+ return null;
+ }
+ try { ls.setItem(u, http.responseText); } catch(e) {}
+ return http.responseText;
+ }
+ if (window.debug) debug('http error', u, http.status, http.statusText);
+ return null;
+};
+
+})();
+
+/**
+ * Load Javascript and CSS.
+ */
+(function() {
+
+var bootjs = document.createElement('script');
+bootjs.type = 'text/javascript';
+bootjs.text = appcache.get('/all-min.js');
+document.head.appendChild(bootjs);
+document.head.appendChild(ui.declareCSS(appcache.get('/ui-min.css')));
+
+})();
+
+</script>
+</head>
+<body class="delayed">
+<div id="mainbodydiv" class="mainbodydiv">
+
+<div id="headdiv" class="hsection">
+<script type="text/javascript">
+(function() {
+
+$('headdiv').appendChild(ui.declareScript(appcache.get('/public/config-min.js')));
+
+})();
+</script>
+</div>
+
+<div id="menubackground" class="tbarbackground fixed"></div>
+<div id="menu" class="tbarmenu fixed"></div>
+
+<div id="viewheadbackground" class="viewheadbackground fixed"></div>
+<div id="viewhead" class="viewhead fixed"></div>
+
+<div id="viewcontainer">
+<div id="view">
+<div id="viewcontent" class="viewcontent" style="margin-left: auto; margin-right: auto; text-align: center;">
+
+<br/>
+<div class="hd2">Sorry, that page is still under construction.</div>
+<div>Please check back later.</div>
+
+</div>
+</div>
+</div>
+
+<div id="viewfootbackground" class="viewfootbackground fixed"></div>
+<div id="viewfoot" class="viewfoot fixed"></div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Init div variables.
+ */
+var mdiv = $('menu');
+var hdiv = $('viewhead');
+$('viewcontainer').className = ui.isMobile()? 'viewcontainer3d' : 'viewcontainer3dm';
+$('view').className = ui.isMobile()? 'viewloaded3d' : 'viewloaded3dm';
+var fdiv = $('viewfoot');
+
+/**
+ * Set page title.
+ */
+document.title = config.windowtitle() + ' - Page not found';
+$('viewhead').innerHTML = '<span class="bcmenu">' + config.pagetitle() + '</span>';
+
+/**
+ * Build and show the menu bar.
+ */
+function showmenu(mdiv) {
+ mdiv.innerHTML = ui.menubar(
+ mklist(ui.menu('menuhome', 'Home', '/', '_self', false)),
+ mklist(hasauthcookie()? ui.menufunc('menusignout', 'Sign out', 'return logout();', false) : ui.menu('menusignin', 'Sign in', '/login/', '_self', false)));
+ fdiv.innerHTML = config.viewfoot();
+}
+
+showmenu(mdiv);
+
+/**
+ * Log the current user out.
+ */
+window.logout = function() {
+ // Clear session cookie and user-specific local storage entries
+ clearauthcookie();
+ lstorage.removeItem('/r/Editor/accounts');
+ lstorage.removeItem('/r/Editor/dashboards');
+ document.location = '/login/';
+ return false;
+}
+
+/**
+ * Handle orientation change.
+ */
+document.body.onorientationchange = function(e) {
+ //debug('onorientationchange');
+ ui.onorientationchange(e);
+
+ // Resize menu and view header
+ mdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
+ hdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
+ return true;
+};
+
+/**
+ * Initialize the document.
+ */
+function onload() {
+ //debug('onload');
+ ui.onload();
+
+ // Show the page
+ document.body.style.visibility = 'visible';
+ return true;
+}
+
+onload();
+
+})();
+</script>
+
+<div id="footdiv" class="fsection">
+</div>
+
+</div>
+</body>
+</html>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/oops/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/oops/index.html
new file mode 100644
index 0000000000..cc97c5362e
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/oops/index.html
@@ -0,0 +1,193 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Oops</title>
+<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"/>
+<meta name="apple-mobile-web-app-capable" content="yes"/>
+<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
+<base href="/public/oops/"/>
+<script type="text/javascript">
+(function() {
+
+window.appcache = {};
+
+/**
+ * Get and cache a resource.
+ */
+appcache.get = function(uri) {
+ var h = uri.indexOf('#');
+ var u = h == -1? uri : uri.substring(0, h);
+
+ // Get resource from local storage first
+ var ls = window.lstorage || localStorage;
+ var item = null;
+ try { item = ls.getItem(u); } catch(e) {}
+ if (item != null && item != '')
+ return item;
+
+ // Get resource from network
+ var http = new XMLHttpRequest();
+ http.open("GET", u, false);
+ http.setRequestHeader("Accept", "*/*");
+ http.send(null);
+ if (http.status == 200) {
+ if (http.getResponseHeader("X-Login") != null) {
+ if (window.debug) debug('http error', u, 'X-Login');
+ return null;
+ } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
+ if (window.debug) debug('http error', u, 'No-Content');
+ return null;
+ }
+ try { ls.setItem(u, http.responseText); } catch(e) {}
+ return http.responseText;
+ }
+ if (window.debug) debug('http error', u, http.status, http.statusText);
+ return null;
+};
+
+})();
+
+/**
+ * Load Javascript and CSS.
+ */
+(function() {
+
+var bootjs = document.createElement('script');
+bootjs.type = 'text/javascript';
+bootjs.text = appcache.get('/all-min.js');
+document.head.appendChild(bootjs);
+document.head.appendChild(ui.declareCSS(appcache.get('/ui-min.css')));
+
+})();
+
+</script>
+</head>
+<body class="delayed">
+<div id="mainbodydiv" class="mainbodydiv">
+
+<div id="headdiv" class="hsection">
+<script type="text/javascript">
+(function() {
+
+$('headdiv').appendChild(ui.declareScript(appcache.get('/public/config-min.js')));
+
+})();
+</script>
+</div>
+
+<div id="menubackground" class="tbarbackground fixed"></div>
+<div id="menu" class="tbarmenu fixed"></div>
+
+<div id="viewheadbackground" class="viewheadbackground fixed"></div>
+<div id="viewhead" class="viewhead fixed"></div>
+
+<div id="viewcontainer">
+<div id="view">
+<div id="viewcontent" class="viewcontent" style="margin-left: auto; margin-right: auto; text-align: center;">
+
+<br/>
+<div class="hd2">Oops, something went wrong...</div>
+
+</div>
+</div>
+</div>
+
+<div id="viewfootbackground" class="viewfootbackground fixed"></div>
+<div id="viewfoot" class="viewfoot fixed"></div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Init div variables.
+ */
+var mdiv = $('menu');
+var hdiv = $('viewhead');
+$('viewcontainer').className = ui.isMobile()? 'viewcontainer3d' : 'viewcontainer3dm';
+$('view').className = ui.isMobile()? 'viewloaded3d' : 'viewloaded3dm';
+var fdiv = $('viewfoot');
+
+/**
+ * Set page title.
+ */
+document.title = config.windowtitle() + ' - Oops';
+$('viewhead').innerHTML = '<span class="bcmenu">' + config.pagetitle() + '</span>';
+
+/**
+ * Build and show the menu bar.
+ */
+function showmenu(mdiv) {
+ mdiv.innerHTML = ui.menubar(
+ mklist(ui.menu('menuhome', 'Home', '/', '_self', false)),
+ mklist(hasauthcookie()? ui.menufunc('menusignout', 'Sign out', 'return logout();', false) : ui.menu('menusignin', 'Sign in', '/login/', '_self', false)));
+ fdiv.innerHTML = config.viewfoot();
+}
+
+showmenu(mdiv);
+
+/**
+ * Log the current user out.
+ */
+window.logout = function() {
+ // Clear session cookie and user-specific local storage entries
+ clearauthcookie();
+ lstorage.removeItem('/r/Editor/accounts');
+ lstorage.removeItem('/r/Editor/dashboards');
+ document.location = '/login/';
+ return false;
+}
+
+/**
+ * Handle orientation change.
+ */
+document.body.onorientationchange = function(e) {
+ //debug('onorientationchange');
+ ui.onorientationchange(e);
+
+ // Resize menu and view header
+ mdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
+ hdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
+ return true;
+};
+
+/**
+ * Initialize the document.
+ */
+function onload() {
+ //debug('onload');
+ ui.onload();
+
+ // Show the page
+ document.body.style.visibility = 'visible';
+ return true;
+}
+
+onload();
+
+})();
+</script>
+
+<div id="footdiv" class="fsection">
+</div>
+
+</div>
+</body>
+</html>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/touchicon.b64 b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/touchicon.b64
new file mode 100644
index 0000000000..2239f6ae0f
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/touchicon.b64
@@ -0,0 +1 @@
+iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAIAAAADehTSAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sDGxMkCJXGmL8AAAHwSURBVGje7ZpNbhNBEIXf625sCzA/QUhkg8SGiGxZcpDcgRux5hLkEjkE7BAS9gIyk+muxyZIsSeOG09bsXHX0p4pfVNdP8/loSTsiTnsj1XWyrrMutVSG+ic/ftNqe1mIMtSjsPUu9EQJ6H/UdvNLr59cgwFWaM1p8dnLx6dFGYF6RhIXzLVGIChB3VX8Fg0DWrPqqyHxTq4MUnKKEEBoNvIN4uxiqTkofUXpgZKsqtMx3Djpb45lNWAxxbfXf6wtdH9+vkKBLLGrFLz4M1HTk+K5gAIgBCVcaTI1gOK/acazqqbw2PdYzE7tdyh9AFJTL0zNDIJMInAZpKPzBzmIZuUnjoa9QQkOBHAyWbigYDaTslybg/59f7Q4+003pqwhqcbqjLH9H2OXw0Ksl6XsWB/a39lhf1rz8vOnKoHKmtlrayVtbLuuc6SFK1Z2hEZkBwAv1us4zA9PT7rDX3v9dPiOeBxT/uY0A+qd6Pbl2Sax/kXDN9LlcrXO3Rk9k/QWluVtbIe2O5toBGwFum3bLH/pEso7RarrPNHH/D8JbBIpsjJqx2Lq3Xu2Xv61yvXJzf6/b3nK2Htyu8WB9P/XltF/wfVllgFxet9azGL+bjMD5IUYbPSMktwT8hRSdalkizcufKcs77vUlkr61bsD5lbwtgOKPT2AAAAAElFTkSuQmCC \ No newline at end of file
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/touchicon.png b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/touchicon.png
new file mode 100644
index 0000000000..f22c33d2a0
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/touchicon.png
Binary files differ
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/touchicon.xcf b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/touchicon.xcf
new file mode 100644
index 0000000000..fc713b478b
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/touchicon.xcf
Binary files differ
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/user.b64 b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/user.b64
new file mode 100644
index 0000000000..7ed235aa14
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/user.b64
@@ -0,0 +1 @@
+iVBORw0KGgoAAAANSUhEUgAAADIAAAAyAgMAAABjUWAiAAAABGdBTUEAALGPC/xhBQAAAAxQTFRFyN+N+dR1/PCI////6HjE5gAAADJJREFUKM9j+I8EPjBQifeBAQSY6coLBYN6inhaq0Bg6SDn/f//akB466ExTS6P2ukMAKumzarJO/66AAAAAElFTkSuQmCC \ No newline at end of file
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/user.png b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/user.png
new file mode 100644
index 0000000000..1f73274b76
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/public/user.png
Binary files differ
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/robots.txt b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/robots.txt
new file mode 100644
index 0000000000..1f53798bb4
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/stats/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/stats/index.html
new file mode 100644
index 0000000000..7c3d9a6434
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/stats/index.html
@@ -0,0 +1,179 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<div id="bodydiv" class="body">
+
+<div class="viewform">
+
+<form id="appForm">
+<table style="width: 100%;">
+<tr><tr><td><b>Icon:</b></td></tr>
+<tr><td><img id="appimg" style="width: 50px; height: 50px; vertical-align: top;"></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>Title:</b></td></tr>
+<tr><td><input type="text" class="flatentry" id="appTitle" size="30" readonly="readonly" placeholder="Enter the title of your app" style="width: 300px;"/></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>Author:</b></td></tr>
+<tr><td><span id="appAuthor"></span></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>Updated:</b></td></tr>
+<tr><td><span id="appUpdated"></span></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>Description:</b></td></tr>
+<tr><td><textarea id="appDescription" class="flatentry" cols="40" rows="3" readonly="readonly" placeholder="Enter a short description of your app" style="width: 300px;"></textarea></td></tr>
+</table>
+</form>
+
+</div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Get the app name.
+ */
+var appname = ui.fragmentParams(location)['app'];
+
+/**
+ * Set page titles.
+ */
+document.title = config.windowtitle() + ' - Stats - ' + appname;
+$('viewhead').innerHTML = '<span id="appname" class="cmenu">' + appname + '</span>' +
+'<input type="button" class="graybutton redbutton plusminus" style="position: absolute; top: 4px; left: 5px;" id="deleteApp" value="-" title="Delete the app" disabled="true"/>' +
+'<input type="button" class="graybutton bluebutton" style="position: absolute; top: 4px; right: 5px;" id="cloneApp" value="'+ config.clone() +'" title="' + config.clone() + ' this app"/>';
+
+/**
+ * Set images.
+ */
+$('appimg').src = ui.b64img(appcache.get('/public/app.b64'));
+
+/**
+ * Init service references.
+ */
+var editorComp = sca.component("Editor");
+var apps = sca.reference(editorComp, "apps");
+
+/**
+ * The current app entry, author and saved XML content.
+ */
+var savedappentryxml = '';
+var author;
+var appentry;
+
+/**
+ * Get and display an app.
+ */
+function getapp(name) {
+ if (isNil(name))
+ return false;
+ showStatus('Loading');
+
+ return apps.get(name, function(doc) {
+
+ // Stop now if we didn't get the app
+ if (doc == null) {
+ showError('App not available');
+ return false;
+ }
+
+ appentry = car(elementsToValues(atom.readATOMEntry(mklist(doc))));
+ $('appTitle').value = cadr(assoc("'title", cdr(appentry)));
+ author = cadr(assoc("'author", cdr(appentry)));
+ $('appAuthor').innerHTML = author;
+ $('appUpdated').innerHTML = cadr(assoc("'updated", cdr(appentry)));
+ var content = cadr(assoc("'content", cdr(appentry)));
+ var description = assoc("'description", content);
+ $('appDescription').value = isNil(description) || isNil(cadr(description))? '' : cadr(description);
+ savedappentryxml = car(atom.writeATOMEntry(valuesToElements(mklist(appentry))));
+
+ // Enable author to edit and delete the app
+ if (username == author) {
+ $('appTitle').readOnly = false;
+ $('appDescription').readOnly = false;
+ $('deleteApp').disabled = false;
+ $('deleteApp').onclick = function() {
+ return ui.navigate('/#view=delete&app=' + appname, '_view');
+ }
+ showOnlineStatus();
+ } else {
+ $('appTitle').placeholder = '';
+ $('appDescription').placeholder = '';
+ showStatus('Read only');
+ }
+ return true;
+ });
+}
+
+/**
+ * Save the current app.
+ */
+function save(entryxml) {
+ showStatus('Saving');
+ savedappentryxml = entryxml;
+ apps.put(appname, savedappentryxml, function(e) {
+ if (e) {
+ showStatus('Local copy');
+ return false;
+ }
+
+ showStatus('Saved');
+ return false;
+ });
+ return true;
+}
+
+/**
+ * Handle a change event
+ */
+function onappchange() {
+ if (username != author)
+ return false;
+ var title = $('appTitle').value;
+ var description = $('appDescription').value;
+ appentry = mklist("'entry", mklist("'title", title != ''? title : appname), mklist("'id", appname), mklist("'content", mklist("'stats", mklist("'description", description))));
+ var entryxml = car(atom.writeATOMEntry(valuesToElements(mklist(appentry))));
+ if (savedappentryxml == entryxml)
+ return false;
+ showStatus('Modified');
+ return save(entryxml);
+}
+
+$('appTitle').onchange = onappchange;
+$('appDescription').onchange = onappchange;
+
+/**
+ * Handle a form submit event.
+ */
+$('appForm').onsubmit = function() {
+ onappchange();
+ return false;
+};
+
+/**
+ * Handle Clone button event.
+ */
+$('cloneApp').onclick = function() {
+ return ui.navigate('/#view=clone&app=' + appname, '_view');
+}
+
+/**
+ * Get the current app.
+ */
+getapp(appname);
+
+})();
+</script>
+
+</div>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/store/index.html b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/store/index.html
new file mode 100644
index 0000000000..1264007fe3
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/htdocs/store/index.html
@@ -0,0 +1,170 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+-->
+<div id="bodydiv" class="body">
+
+<div id="apps" class="viewcontent"></div>
+
+<script type="text/javascript">
+(function() {
+
+/**
+ * Set page titles.
+ */
+document.title = config.windowtitle() + ' - Store';
+
+/**
+ * The store categories
+ */
+var categories = [
+ //['Featured', 'featured', 1],
+ ['Top', 'top', 2],
+ ['New', 'new', 3],
+ ['Search', 'all', 4],
+ ['My Apps', 'myapps', 5]
+];
+
+/**
+ * Find a store category.
+ */
+function findcategory(name) {
+ if (isNil(name))
+ return findcategory('top');
+ var f = filter(function(c) { return cadr(c) == name }, categories);
+ if (isNil(f))
+ return findcategory('top');
+ return car(f);
+}
+
+/**
+ * Get the current store category.
+ */
+var catname = cadr(findcategory(ui.fragmentParams(location)['category']));
+
+/**
+ * Build the store menu bar
+ */
+function catmenu() {
+ function catmenuitem(name, cat, idx) {
+ var c = cat == catname? 'smenu' : 'amenu';
+ return '<span>' + ui.href('storecat_' + cat, '/#view=store&category=' + cat + '&idx=' + idx, '_view', '<span class="' + c + '">' + name + '</span>') + '</span>';
+ }
+
+ var m = '';
+ map(function(c) { m += catmenuitem(car(c), cadr(c), caddr(c)); }, categories);
+ m += '<span class="rmenu"><input type="button" class="graybutton bluebutton" id="createApp" title="Create a new app" Value="Create"/></span>';
+ return m;
+}
+
+/**
+ * Build the store menu bar.
+ */
+$('viewhead').innerHTML = catmenu();
+
+/**
+ * Init service references.
+ */
+var editorComp = sca.component("Editor");
+var store = sca.reference(editorComp, "store");
+var dashboards = sca.reference(editorComp, "dashboards");
+
+/**
+ * Edit an app.
+ */
+function editApp(appname) {
+ return ui.navigate('/#view=page&app=' + appname, '_view');
+}
+
+/**
+ * View an app.
+ */
+function viewApp(appname) {
+ return ui.navigate('/#view=stats&app=' + appname, '_view');
+}
+
+/**
+ * Create an app.
+ */
+$('createApp').onclick = function() {
+ return ui.navigate('/#view=create', '_view');
+}
+
+/**
+ * Get and display list of apps.
+ */
+function getapps(catname) {
+ //debug('catname', catname);
+ showStatus('Loading');
+
+ function display(doc) {
+
+ // Stop now if we didn't get the apps
+ if (doc == null) {
+ showError('App not available');
+ return false;
+ }
+ showOnlineStatus();
+
+ var apps = '<div>';
+ var feed = car(elementsToValues(atom.readATOMFeed(mklist(doc))));
+ var aentries = assoc("'entry", cdr(feed));
+ var entries = isNil(aentries)? mklist() : isList(car(cadr(aentries)))? cadr(aentries) : mklist(cdr(aentries));
+
+ var appimg = ui.b64img(appcache.get('/public/app.b64'));
+
+ function displayentries(entries) {
+ if (isNil(entries))
+ return apps;
+ var entry = car(entries);
+ var title = cadr(assoc("'title", entry))
+ var name = cadr(assoc("'id", entry));
+ var author = cadr(assoc("'author", entry));
+ var updated = cadr(assoc("'updated", entry));
+
+ apps += '<div class="box">'
+ apps += '<span class="appicon">' + ui.href('appicon_' + name, '/#view=stats&app=' + name, '_view', '<img src="' + appimg + '" width="50" height="50"></img>') + '</span>';
+ apps += '<span>'
+ apps += '<span class="apptitle">' + ui.href('apptitle_' + name, '/#view=stats&app=' + name, '_view', name) + '</span>';
+ if (catname != 'myapps')
+ apps += '<br/><span>' + 'by&nbsp;' + author.split('@')[0] + '</span>';
+ apps += '</span>';
+ apps += '</div>';
+ return displayentries(cdr(entries));
+ }
+
+ displayentries(entries);
+
+ apps += '</div>';
+ $('apps').innerHTML = apps;
+ }
+
+ if (catname == 'myapps')
+ return dashboards.get('', display);
+ return store.get(catname, display);
+}
+
+/**
+ * Get and display the list of apps.
+ */
+getapps(catname);
+
+})();
+</script>
+
+</div>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/log.py b/sca-cpp/branches/lightweight-sca/hosting/server/log.py
new file mode 100644
index 0000000000..8aa3d3bd30
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/log.py
@@ -0,0 +1,24 @@
+# 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.
+
+# Log service component
+from sys import stderr
+
+# Log a message
+def log(msg):
+ print >> stderr, '[rconsole]', msg
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/logic-test b/sca-cpp/branches/lightweight-sca/hosting/server/logic-test
new file mode 100755
index 0000000000..d4767e858f
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/logic-test
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+# 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.
+
+# Run Python test cases
+here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
+python_prefix=`cat $here/../../modules/python/python.prefix`
+export LD_LIBRARY_PATH=$python_prefix/lib:$LD_LIBRARY_PATH
+
+$python_prefix/bin/python test.py 2>/dev/null
+rc=$?
+
+exit $rc
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/mkapplinks b/sca-cpp/branches/lightweight-sca/hosting/server/mkapplinks
new file mode 100755
index 0000000000..a68a2896ec
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/mkapplinks
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+# 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.
+
+aprefix=$1
+tprefix=$2
+nprefix=$3
+
+# Create app links to Nuvem and Tuscany components
+cd $1
+for n in `ls apps | awk '{ printf "apps/%s/nuvem\n", $1 }'`; do
+ if [ ! -e "$n" ]; then
+ ln -s "$nprefix/nuvem-parallel/nuvem" "$n"
+ fi
+done
+
+for n in `ls apps | awk '{ printf "apps/%s/lib\n", $1 }'`; do
+ if [ ! -e "$n" ]; then
+ ln -s "$tprefix/components" "$n"
+ fi
+done
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/pages.py b/sca-cpp/branches/lightweight-sca/hosting/server/pages.py
new file mode 100644
index 0000000000..a4f6d056f9
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/pages.py
@@ -0,0 +1,96 @@
+# 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.
+
+# App pages collection implementation
+from time import strftime
+from util import *
+from sys import debug
+
+# Convert an id to a page id
+def pageid(id):
+ return ("apps", car(id), "htdocs", "app.html")
+
+# Put a page into the page db
+def put(id, page, user, cache, apps):
+ debug('pages.py::put::id', id)
+ debug('pages.py::put::page', page)
+
+ # Get the requested app
+ app = apps.get(id);
+ if isNil(app) or app is None:
+ debug('pages.py::put', 'app not found', id)
+ return False
+
+ # Check app author
+ author = cadr(assoc("'author", car(app)))
+ if author != user.get(()):
+ debug('pages.py::put', 'different author', author)
+ return False
+
+ # Update the page in the page db
+ pageentry = (("'entry", assoc("'title", car(app)), ("'id", car(id)), ("'author", user.get(())), ("'updated", strftime('%b %d, %Y')), assoc("'content", car(page))),)
+ debug('pages.py::put::pageentry', pageentry)
+ return cache.put(pageid(id), pageentry)
+
+# Get a page from the page db
+def get(id, user, cache, apps):
+ debug('pages.py::get::id', id)
+ if isNil(id):
+ return (("'feed", ("'title", "Pages"), ("'id", "pages")),)
+
+ # Get the requested app
+ app = apps.get(id)
+ if isNil(app) or app is None:
+ debug('pages.py::get', 'app not found', id)
+
+ # Return a default new page
+ return (("'entry", ("'title", car(id)), ("'id", car(id)), ("'author", user.get(())), ("'updated", strftime('%b %d, %Y'))),)
+
+ # Get the requested page
+ page = cache.get(pageid(id))
+ if isNil(page) or page is None:
+ debug('pages.py::get', 'page not found', id)
+
+ # Return a default new page
+ return (("'entry", ("'title", car(id)), ("'id", car(id)), assoc("'author", car(app)), assoc("'updated", car(app))),)
+
+ # Return the page
+ def updated(u):
+ return assoc("'updated", car(app)) if isNil(u) or u is None else u
+ pageentry = (("'entry", assoc("'title", car(app)), ("'id", car(id)), assoc("'author", car(app)), updated(assoc("'updated", car(page))), assoc("'content", car(page))),)
+ debug('pages.py::get::pageentry', pageentry)
+ return pageentry
+
+# Delete a page from the page db
+def delete(id, user, cache, apps):
+ debug('pages.py::delete::id', id)
+
+ # Get the requested app
+ app = apps.get(id);
+ if isNil(app) or app is None:
+ debug('pages.py::delete', 'app not found', id)
+ return False
+
+ # Check app author
+ author = cadr(assoc("'author", car(app)))
+ if author != user.get(()):
+ debug('pages.py::delete', 'different author', author)
+ return False
+
+ # Delete the page
+ return cache.delete(pageid(id))
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/palettes.py b/sca-cpp/branches/lightweight-sca/hosting/server/palettes.py
new file mode 100644
index 0000000000..321db3cf46
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/palettes.py
@@ -0,0 +1,36 @@
+# 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.
+
+# Palettes collection implementation
+from util import *
+
+# Convert an id to a palette id
+def paletteid(id):
+ return ("palettes", car(id), "palette.composite")
+
+# Put a palette into the palettes db
+def put(id, palette, cache):
+ comp = cdr(cadddr(car(palette)))
+ cache.put(paletteid(id), comp)
+ return True
+
+# Get a palette from the palettes db
+def get(id, cache):
+ if isNil(id):
+ return (("'feed", ("'title", "Palettes"), ("'id", "palettes")),)
+ return (("'entry", ("'title", car(id)), ("'id", car(id)), ("'content", car(cache.get(paletteid(id))))),)
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/proxy-start b/sca-cpp/branches/lightweight-sca/hosting/server/proxy-start
new file mode 100755
index 0000000000..f06de9fc01
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/proxy-start
@@ -0,0 +1,164 @@
+#!/bin/sh
+
+# 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.
+
+# For this module to work, add the www.example.com domain to your /etc/hosts as
+# follows:
+# 127.0.0.1 www.example.com
+
+here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
+
+# Configure and start logging
+if [ -x ../../components/log/scribe-cat ]; then
+ ../../components/log/scribed-central-conf tmp
+ ../../components/log/scribed-client-conf tmp localhost
+ ../../components/log/scribed-central-start tmp
+ ../../components/log/scribed-client-start tmp
+fi
+
+# Start memcached
+../../components/cache/memcached-start tmp 11211
+../../components/cache/memcached-start tmp 11212
+
+# Configure server
+../../modules/http/httpd-conf tmp www.example.com 9090 htdocs
+../../modules/http/httpd-event-conf tmp
+
+# Configure Python component support
+../../modules/server/server-conf tmp
+../../modules/python/python-conf tmp
+
+# Configure server log streaming
+if [ -x ../../components/log/scribe-cat ]; then
+ cat >tmp/conf/log.conf <<EOF
+# Generated by: proxy-start $*
+LogLevel notice
+ErrorLog "|$here/../../components/log/scribe-cat localhost server"
+CustomLog "|$here/../../components/log/scribe-cat localhost server" combined
+
+EOF
+
+fi
+#../../modules/http/httpd-loglevel-conf tmp debug
+
+# Configure error pages
+cat >>tmp/conf/svhost.conf <<EOF
+# Generated by: proxy-start $*
+# Error pages
+ErrorDocument 404 /public/notfound/
+ErrorDocument 401 /public/notauth/
+ErrorDocument 403 /public/notauth/
+ErrorDocument 400 /public/oops/
+ErrorDocument 405 /public/oops/
+ErrorDocument 500 /public/oops/
+ErrorDocument 502 /public/oops/
+ErrorDocument 503 /public/oops/
+
+EOF
+
+# Configure SCA contributions
+cat >>tmp/conf/httpd.conf <<EOF
+# Generated by: proxy-start $*
+# Configure SCA Composite
+SCAContribution $here/
+SCAComposite server.composite
+
+# Configure SCA Composite for mass dynamic virtual Hosting
+#SCAVirtualContribution $here/data/apps/
+#SCAVirtualComposite app.composite
+SCAVirtualContributor Composites
+
+# Configure SCA wiring timeout
+SCAWiringTimeout 10
+
+EOF
+
+# Configure resource aliases
+cat >>tmp/conf/httpd.conf <<EOF
+# Generated by: proxy-start $*
+Alias /home/home.png $here/htdocs/home/home.png
+Alias /home/home.b64 $here/htdocs/home/home.b64
+Alias /proxy/public/config.js $here/htdocs/public/config.js
+Alias /proxy/public/config-min.js $here/public/config-min.js
+
+EOF
+
+# Configure app resource aliases
+cat >>tmp/conf/svhost.conf <<EOF
+# Generated by: proxy-start $*
+# Map /v/<app-name>/<path> to htdocs/app/<path>
+AliasMatch /v/([^/]+)(.*)$ $here/htdocs/app\$2
+
+EOF
+
+# Start server
+../../modules/http/httpd-start tmp
+
+# Clear document cache
+rm -rf tmp/proxy/cache
+
+# Configure proxy balancer
+../../modules/http/httpd-conf tmp/proxy www.example.com 8090 tmp/htdocs
+../../modules/http/alt-host-conf tmp/proxy ww1.example.com
+../../modules/http/alt-host-conf tmp/proxy ww2.example.com
+../../modules/http/proxy-conf tmp/proxy
+../../modules/js/js-conf tmp/proxy
+../../modules/http/httpd-event-conf tmp/proxy
+#../../modules/http/cache-conf tmp/proxy
+
+# Configure proxy balancer members
+../../modules/http/proxy-member-conf tmp/proxy localhost 9090
+
+# Configure proxy log streaming
+if [ -x ../../components/log/scribe-cat ]; then
+ cat >tmp/proxy/conf/log.conf <<EOF
+# Generated by: proxy-start $*
+ErrorLog "|$here/../../components/log/scribe-cat www.example.com proxy"
+CustomLog "|$here/../../components/log/scribe-cat www.example.com access" combined
+
+EOF
+
+fi
+#../../modules/http/httpd-loglevel-conf tmp/proxy debug
+
+# Configure resource aliases
+cat >>tmp/proxy/conf/httpd.conf <<EOF
+# Generated by: proxy-start $*
+Alias /proxy/public/config.js $here/htdocs/public/config.js
+Alias /proxy/public/config-min.js $here/htdocs/public/config-min.js
+
+EOF
+
+# Configure error pages
+cat >>tmp/proxy/conf/vhost.conf <<EOF
+# Generated by: proxy-start $*
+# Error pages
+ErrorDocument 404 /proxy/public/oops/
+ErrorDocument 401 /proxy/public/oops/
+ErrorDocument 403 /proxy/public/oops/
+ErrorDocument 400 /proxy/public/oops/
+ErrorDocument 405 /proxy/public/oops/
+ErrorDocument 500 /proxy/public/oops/
+ErrorDocument 502 /proxy/public/oops/
+ErrorDocument 503 /proxy/public/oops/
+
+EOF
+
+# Start proxy balancer
+../../modules/http/httpd-start tmp/proxy
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/put-auth b/sca-cpp/branches/lightweight-sca/hosting/server/put-auth
new file mode 100755
index 0000000000..351c9b7d7a
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/put-auth
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+# 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.
+
+here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
+mkdir -p $1
+root=`echo "import os; print os.path.realpath('$1')" | python`
+admin=$2
+apass=$3
+user=$4
+upass=$5
+
+httpd_prefix=`cat $here/../../modules/http/httpd.prefix`
+
+conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
+sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"`
+if [ "$sslconf" = "" ]; then
+ scheme="http"
+ addr=`echo $conf | awk '{ print $7 }'`
+ host=`$here/../../modules/http/httpd-addr ip $addr`
+ if [ "$host" = "" ]; then
+ host="localhost"
+ fi
+ port=`$here/../../modules/http/httpd-addr port $addr`
+else
+ scheme="https"
+ ssladdr=`echo $sslconf | awk '{ print $6 }'`
+ host=`$here/../../modules/http/httpd-addr ip $ssladdr`
+ if [ "$host" = "" ]; then
+ host="localhost"
+ fi
+ port=`$here/../../modules/http/httpd-addr port $ssladdr`
+fi
+
+# Get password hash
+rm -f $root/conf/auth.passwd
+touch $root/conf/auth.passwd
+$httpd_prefix/bin/htpasswd -b $root/conf/auth.passwd "$user" "$upass" 2>/dev/null
+hash=`cat $root/conf/auth.passwd | awk -F ":" '{ print $2 }'`
+rm -f $root/conf/auth.passwd
+
+# Compute user id
+slash=`echo $user | grep "/"`
+if [ "$slash" = "" ]; then
+ id="\"$user\""
+ upath=$user
+else
+ id=`echo $user | awk -F "/" '{ printf "\"%s\" \"%s\"", $2, $3 }'`
+ upath=`echo $user | awk -F "/" '{ printf "%s/%s", $2, $3 }'`
+fi
+
+# Put user auth
+cat >$root/conf/auth.entry <<EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">$user</title>
+ <id>$user</id>
+ <content type="application/xml">
+ <hash>$hash</hash>
+ </content>
+</entry>
+EOF
+curl -k -L -u $admin:$apass -X PUT -H "X-Forwarded-Server: $host" --data-binary @$root/conf/auth.entry $scheme://$host:$port/c/Authenticator/$upath
+rm $root/conf/auth.entry
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/selector.py b/sca-cpp/branches/lightweight-sca/hosting/server/selector.py
new file mode 100644
index 0000000000..7fcdd65a0f
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/selector.py
@@ -0,0 +1,28 @@
+# 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.
+
+# App composites collection implementation
+from util import *
+
+# Get the database to use for a particular key
+def get(id, db):
+ if isNil(id):
+ return db[0]
+ if cadr(id)[0:1].lower() < 'm':
+ return db[0]
+ return db[1]
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/server-test b/sca-cpp/branches/lightweight-sca/hosting/server/server-test
new file mode 100755
index 0000000000..4d4d06f338
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/server-test
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# 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.
+
+# Setup
+./ssl-proxy-start
+sleep 2
+
+# Test
+./client-test 2>/dev/null
+rc=$?
+
+# Cleanup
+./stop
+sleep 2
+exit $rc
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/server.composite b/sca-cpp/branches/lightweight-sca/hosting/server/server.composite
new file mode 100644
index 0000000000..7e4d7196d0
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/server.composite
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ targetNamespace="http://server"
+ name="server">
+
+ <component name="User">
+ <implementation.python script="user.py"/>
+ <property name="user">?</property>
+ <property name="email">?</property>
+ <property name="nickname">?</property>
+ <property name="fullname">?</property>
+ <property name="firstname">?</property>
+ <property name="lastname">?</property>
+ <property name="realm">?</property>
+ <property name="host">?</property>
+ </component>
+
+ <component name="Editor">
+ <implementation.widget location="/index.html"/>
+ <reference name="user" target="User"/>
+ <reference name="accounts" target="Accounts"/>
+ <reference name="dashboards" target="Dashboards"/>
+ <reference name="apps" target="Apps"/>
+ <reference name="store" target="AppStore"/>
+ <reference name="palettes" target="Palettes"/>
+ <reference name="composites" target="Composites"/>
+ <reference name="pages" target="Pages"/>
+ <reference name="log" target="Log"/>
+ </component>
+
+ <component name="App">
+ <implementation.widget location="/app/index.html"/>
+ <reference name="user" target="User"/>
+ <reference name="pages" target="Pages"/>
+ <reference name="composites" target="Composites"/>
+ <reference name="log" target="Log"/>
+ </component>
+
+ <component name="Accounts">
+ <implementation.python script="accounts.py"/>
+ <reference name="user" target="User"/>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="Authenticator">
+ <implementation.python script="authn.py"/>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="Dashboards">
+ <implementation.python script="dashboards.py"/>
+ <reference name="user" target="User"/>
+ <reference name="cache" target="Cache"/>
+ <reference name="apps" target="Apps"/>
+ </component>
+
+ <component name="AppStore">
+ <implementation.python script="store.py"/>
+ <reference name="user" target="User"/>
+ <reference name="cache" target="Cache"/>
+ <reference name="apps" target="Apps"/>
+ </component>
+
+ <component name="Apps">
+ <implementation.python script="apps.py"/>
+ <reference name="user" target="User"/>
+ <reference name="cache" target="Cache"/>
+ <reference name="dashboard" target="Dashboards"/>
+ <reference name="store" target="AppStore"/>
+ <reference name="composites" target="Composites"/>
+ <reference name="pages" target="Pages"/>
+ </component>
+
+ <component name="Composites">
+ <implementation.python script="composites.py"/>
+ <reference name="user" target="User"/>
+ <reference name="cache" target="Doccache"/>
+ <reference name="apps" target="Apps"/>
+ </component>
+
+ <component name="Pages">
+ <implementation.python script="pages.py"/>
+ <reference name="user" target="User"/>
+ <reference name="cache" target="Doccache"/>
+ <reference name="apps" target="Apps"/>
+ </component>
+
+ <component name="Palettes">
+ <implementation.python script="palettes.py"/>
+ <reference name="cache" target="Doccache"/>
+ </component>
+
+ <component name="Cache">
+ <implementation.cpp path="../../components/cache" library="libdatacache"/>
+ <reference name="l1reader" target="Memcache"/>
+ <reference name="l1writer" target="Memcache"/>
+ <reference name="l2reader" target="Database"/>
+ <reference name="l2writer" target="Database"/>
+ </component>
+
+ <component name="Doccache">
+ <implementation.cpp path="../../components/cache" library="libdatacache"/>
+ <reference name="l1reader" target="Memcache"/>
+ <reference name="l1writer" target="Memcache"/>
+ <reference name="l2reader" target="Documents"/>
+ <reference name="l2writer" target="Documents"/>
+ </component>
+
+ <component name="Memcache">
+ <implementation.cpp path="../../components/cache" library="libmemcache"/>
+ <property name="server">localhost:11211</property>
+ <property name="server">localhost:11212</property>
+ </component>
+
+ <component name="Database">
+ <implementation.cpp path="../../components/filedb" library="libfiledb"/>
+ <property name="dbname">data</property>
+ <property name="format">scheme</property>
+ </component>
+
+ <component name="Documents">
+ <implementation.cpp path="../../components/filedb" library="libfiledb"/>
+ <property name="dbname">data</property>
+ <property name="format">xml</property>
+ </component>
+
+ <component name="Log">
+ <implementation.python script="log.py"/>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/ssl-proxy-start b/sca-cpp/branches/lightweight-sca/hosting/server/ssl-proxy-start
new file mode 100755
index 0000000000..e38f54055b
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/ssl-proxy-start
@@ -0,0 +1,252 @@
+#!/bin/sh
+
+# 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.
+
+# For this module to work, add the www.example.com domain to your /etc/hosts as
+# follows:
+# 127.0.0.1 www.example.com
+
+here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
+
+# Configure and start logging
+if [ -x ../../components/log/scribe-cat ]; then
+ ../../components/log/scribed-central-conf tmp
+ ../../components/log/scribed-client-conf tmp localhost
+ ../../components/log/scribed-central-start tmp
+ ../../components/log/scribed-client-start tmp
+fi
+
+# Start memcached
+../../components/cache/memcached-start tmp 11211
+../../components/cache/memcached-start tmp 11212
+
+# Configure server
+../../modules/http/httpd-conf tmp www.example.com 9090 htdocs
+../../modules/http/httpd-event-conf tmp
+
+# Configure HTTP basic auth
+../../modules/http/basic-auth-conf tmp component
+
+# Configure OAuth authentication
+# Configure your OAuth app keys here
+../../modules/oauth/oauth-conf tmp component
+../../modules/oauth/oauth-memcached-conf tmp localhost 11212
+../../modules/oauth/oauth2-appkey-conf tmp facebook.com 12345 67890
+../../modules/oauth/oauth2-appkey-conf tmp google.com 12345 67890
+
+# Configure form-based authentication
+../../modules/http/open-auth-conf tmp component 80b67f38-b79e-4a72-bb5c-22c69fb00820
+
+# Configure authorized admins
+../../modules/http/passwd-auth-conf tmp admin admin
+
+# Configure Python component support
+../../modules/server/server-conf tmp
+../../modules/python/python-conf tmp
+
+# Configure server log streaming
+if [ -x ../../components/log/scribe-cat ]; then
+ cat >tmp/conf/log.conf <<EOF
+# Generated by: ssl-proxy-start $*
+LogLevel notice
+ErrorLog "|$here/../../components/log/scribe-cat localhost server"
+CustomLog "|$here/../../components/log/scribe-cat localhost server" combined
+
+EOF
+
+fi
+../../modules/http/httpd-loglevel-conf tmp debug
+
+# Configure error pages
+cat >>tmp/conf/svhost.conf <<EOF
+# Generated by: ssl-proxy-start $*
+# Error pages
+ErrorDocument 404 /public/notfound/
+ErrorDocument 401 /public/notauth/
+ErrorDocument 403 /public/notauth/
+ErrorDocument 400 /public/oops/
+ErrorDocument 405 /public/oops/
+ErrorDocument 500 /public/oops/
+ErrorDocument 502 /public/oops/
+ErrorDocument 503 /public/oops/
+
+EOF
+
+# Configure SCA contributions
+cat >>tmp/conf/httpd.conf <<EOF
+# Generated by: ssl-proxy-start $*
+# Configure SCA Composite
+SCAContribution $here/
+SCAComposite server.composite
+
+# Configure SCA Composite for mass dynamic virtual Hosting
+SCAVirtualContributor Composites
+
+# Configure SCA Authenticator component
+SCAAuthenticator Authenticator
+
+# Configure SCA wiring timeout
+SCAWiringTimeout 10
+
+EOF
+
+# Configure resource aliases
+cat >>tmp/conf/httpd.conf <<EOF
+# Generated by: ssl-proxy-start $*
+Alias /home/home.png $here/htdocs/home/home.png
+Alias /home/home.b64 $here/htdocs/home/home.b64
+Alias /proxy/public/config.js $here/htdocs/public/config.js
+Alias /proxy/public/config-min.js $here/public/config-min.js
+
+EOF
+
+# Configure app resource aliases
+cat >>tmp/conf/svhost-ssl.conf <<EOF
+# Generated by: ssl-proxy-start $*
+# Map /v/<app-name>/<path> to htdocs/app/<path>
+AliasMatch /v/([^/]+)(.*)$ $here/htdocs/app\$2
+
+EOF
+
+# Configure admin access to server status and info
+cat >tmp/conf/adminauth.conf <<EOF
+# Generated by: ssl-proxy-start $*
+# Allow the server admin to view the server status and info
+<Location /server-status>
+AuthType None
+Require all granted
+</Location>
+
+<Location /server-info>
+AuthType None
+Require all granted
+</Location>
+
+EOF
+
+# Configure admin access to components
+cat >>tmp/conf/locauth-ssl.conf <<EOF
+# Generated by: ssl-proxy-start $*
+# Allow the server admin to access all components
+<Location /c>
+Require user admin
+</Location>
+<Location /r>
+Require user admin
+</Location>
+<Location /r/Editor>
+Require valid-user
+</Location>
+<Location /r/App>
+Require valid-user
+</Location>
+EOF
+
+# Start server
+../../modules/http/httpd-start tmp
+sleep 2
+
+# Configure authorized users
+./put-auth tmp admin admin admin admin
+./put-auth tmp admin admin john john
+./put-auth tmp admin admin jane jane
+# Configure the email addresses associated with your OAuth ids here
+./put-auth tmp admin admin /oauth1/john@example.com password
+./put-auth tmp admin admin /oauth2/jane@example.com password
+
+# Clear document cache
+rm -rf tmp/proxy/cache
+
+# Create SSL certificates
+../../modules/http/ssl-ca-conf tmp/proxy www.example.com
+../../modules/http/ssl-cert-conf tmp/proxy www.example.com server
+
+# Configure proxy balancer
+../../modules/http/httpd-conf tmp/proxy www.example.com 8090 tmp/htdocs
+../../modules/http/alt-host-conf tmp/proxy ww1.example.com
+../../modules/http/alt-host-conf tmp/proxy ww2.example.com
+../../modules/http/proxy-conf tmp/proxy
+../../modules/js/js-conf tmp/proxy
+../../modules/http/httpd-event-conf tmp/proxy
+#../../modules/http/cache-conf tmp/proxy
+../../modules/http/httpd-ssl-conf tmp/proxy 8453
+../../modules/http/proxy-ssl-conf tmp/proxy
+#../../modules/http/cache-ssl-conf tmp/proxy
+
+# Configure password authentication
+../../modules/http/basic-auth-conf tmp/proxy file /balancer-manager
+../../modules/http/basic-auth-conf tmp/proxy file /server-status
+../../modules/http/passwd-auth-conf tmp/proxy file admin admin
+
+# Configure mod-security
+../../modules/http/mod-security-conf tmp/proxy
+#../../modules/http/mod-security-audit-conf tmp/proxy
+
+# Configure proxy balancer members
+../../modules/http/proxy-ssl-nossl-member-conf tmp/proxy localhost 9090
+
+# Configure proxy log streaming
+if [ -x ../../components/log/scribe-cat ]; then
+ cat >tmp/proxy/conf/log.conf <<EOF
+# Generated by: ssl-proxy-start $*
+ErrorLog "|$here/../../components/log/scribe-cat www.example.com proxy"
+CustomLog "|$here/../../components/log/scribe-cat www.example.com access" combined
+
+EOF
+
+ cat >tmp/proxy/conf/log-ssl.conf <<EOF
+# Generated by: ssl-proxy-start $*
+CustomLog "|$here/../../components/log/scribe-cat www.example.com access" sslcombined
+
+EOF
+
+# cat >tmp/proxy/conf/mod-security-audit-log.conf <<EOF
+## Generated by: start $*
+#SecAuditLog "|$here/../../components/log/scribe-cat $host secaudit secaudit"
+#
+#EOF
+
+fi
+../../modules/http/httpd-loglevel-conf tmp/proxy debug
+
+# Configure resource aliases
+cat >>tmp/proxy/conf/httpd.conf <<EOF
+# Generated by: ssl-proxy-start $*
+Alias /proxy/public/config.js $here/htdocs/public/config.js
+Alias /proxy/public/config-min.js $here/htdocs/public/config-min.js
+
+EOF
+
+# Configure error pages
+cat >>tmp/proxy/conf/vhost-ssl.conf <<EOF
+# Generated by: ssl-proxy-start $*
+# Error pages
+ErrorDocument 404 /proxy/public/oops/
+ErrorDocument 401 /proxy/public/oops/
+ErrorDocument 403 /proxy/public/oops/
+ErrorDocument 400 /proxy/public/oops/
+ErrorDocument 405 /proxy/public/oops/
+ErrorDocument 500 /proxy/public/oops/
+ErrorDocument 502 /proxy/public/oops/
+ErrorDocument 503 /proxy/public/oops/
+
+EOF
+
+# Start proxy balancer
+../../modules/http/httpd-start tmp/proxy
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/ssl-start b/sca-cpp/branches/lightweight-sca/hosting/server/ssl-start
new file mode 100755
index 0000000000..d699089847
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/ssl-start
@@ -0,0 +1,208 @@
+#!/bin/sh
+
+# 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.
+
+# For this module to work, add the www.example.com domain to your /etc/hosts as
+# follows:
+# 127.0.0.1 www.example.com
+
+here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
+host=`hostname`
+
+# Create SSL certificates
+../../modules/http/ssl-ca-conf tmp www.example.com
+../../modules/http/ssl-cert-conf tmp www.example.com server
+
+# Configure and start logging
+if [ -x ../../components/log/scribe-cat ]; then
+ ../../components/log/scribed-central-conf tmp
+ ../../components/log/scribed-client-conf tmp localhost
+ ../../components/log/scribed-central-start tmp
+ ../../components/log/scribed-client-start tmp
+fi
+
+# Start memcached
+../../components/cache/memcached-start tmp 11211
+../../components/cache/memcached-start tmp 11212
+
+# Clear document cache
+rm -rf tmp/cache
+
+# Configure server
+../../modules/http/httpd-conf tmp www.example.com 8090 htdocs
+../../modules/http/alt-host-conf tmp ww1.example.com
+../../modules/http/alt-host-conf tmp ww2.example.com
+../../modules/http/httpd-event-conf tmp
+#../../modules/http/cache-conf tmp
+../../modules/http/httpd-ssl-conf tmp 8453
+#../../modules/http/cache-ssl-conf tmp
+
+# Configure HTTP basic auth
+../../modules/http/basic-auth-conf tmp component
+
+# Configure OAuth authentication
+# Configure your OAuth app keys here
+../../modules/oauth/oauth-conf tmp component
+../../modules/oauth/oauth-memcached-conf tmp localhost 11212
+../../modules/oauth/oauth2-appkey-conf tmp facebook.com 12345 67890
+../../modules/oauth/oauth2-appkey-conf tmp google.com 12345 67890
+
+# Configure form-based authentication
+../../modules/http/open-auth-conf tmp component 80b67f38-b79e-4a72-bb5c-22c69fb00820
+
+# Configure authorized admins
+../../modules/http/passwd-auth-conf tmp admin admin
+
+# Configure mod-security
+#../../modules/http/mod-security-conf tmp
+
+# Configure Python component support
+../../modules/server/server-conf tmp
+../../modules/python/python-conf tmp
+
+# Configure server log streaming
+if [ -x ../../components/log/scribe-cat ]; then
+ cat >tmp/conf/log.conf <<EOF
+# Generated by: ssl-start $*
+ErrorLog "|$here/../../components/log/scribe-cat $host server"
+CustomLog "|$here/../../components/log/scribe-cat $host server" combined
+
+EOF
+
+ cat >tmp/conf/log-ssl.conf <<EOF
+# Generated by: ssl-start $*
+CustomLog "|$here/../../components/log/scribe-cat $host server" sslcombined
+
+EOF
+
+ cat >tmp/conf/mod-security-log.conf <<EOF
+# Generated by: ssl-start $*
+SecAuditLog "|$here/../../components/log/scribe-cat $host secaudit"
+
+EOF
+
+fi
+#../../modules/http/httpd-loglevel-conf tmp debug
+
+# Configure certificate mime type
+cat >>tmp/conf/svhost-ssl.conf <<EOF
+# Generated by: ssl-start $*
+# Certificate mime type
+<Location /ca.crt>
+ForceType application/x-x509-ca-cert
+</Location>
+
+EOF
+
+# Configure error pages
+cat >>tmp/conf/svhost-ssl.conf <<EOF
+# Generated by: ssl-start $*
+# Error pages
+ErrorDocument 404 /public/notfound/
+ErrorDocument 401 /public/notauth/
+ErrorDocument 403 /public/notauth/
+ErrorDocument 400 /public/oops/
+ErrorDocument 405 /public/oops/
+ErrorDocument 500 /public/oops/
+ErrorDocument 502 /public/oops/
+ErrorDocument 503 /public/oops/
+
+EOF
+
+# Configure SCA contributions
+cat >>tmp/conf/httpd.conf <<EOF
+# Generated by: ssl-start $*
+# Configure SCA Composite
+SCAContribution $here/
+SCAComposite server.composite
+
+# Configure SCA Composite for mass dynamic virtual Hosting
+SCAVirtualContributor Composites
+
+# Configure SCA Authenticator component
+SCAAuthenticator Authenticator
+
+# Configure SCA wiring timeout
+SCAWiringTimeout 10
+
+EOF
+
+# Configure resource aliases
+cat >>tmp/conf/httpd.conf <<EOF
+# Generated by: ssl-start $*
+Alias /home/home.png $here/htdocs/home/home.png
+Alias /home/home.b64 $here/htdocs/home/home.b64
+Alias /proxy/public/config.js $here/htdocs/public/config.js
+Alias /proxy/public/config-min.js $here/public/config-min.js
+
+EOF
+
+# Configure app resource aliases
+cat >>tmp/conf/svhost-ssl.conf <<EOF
+# Generated by: ssl-start $*
+# Map /v/<app-name>/<path> to htdocs/app/<path>
+AliasMatch /v/([^/]+)(.*)$ $here/htdocs/app\$2
+
+EOF
+
+# Configure admin access to server status and info
+cat >tmp/conf/adminauth.conf <<EOF
+# Generated by: ssl-start $*
+# Allow the server admin to view the server status and info
+<Location /server-status>
+AuthType None
+Require all granted
+</Location>
+
+<Location /server-info>
+AuthType None
+Require all granted
+</Location>
+
+EOF
+
+# Configure admin access to components
+cat >>tmp/conf/locauth-ssl.conf <<EOF
+# Generated by: ssl-start $*
+# Allow the server admin to access all components
+<Location /c>
+Require user admin
+</Location>
+<Location /r>
+Require user admin
+</Location>
+<Location /r/Editor>
+Require valid-user
+</Location>
+<Location /r/App>
+Require valid-user
+</Location>
+EOF
+
+# Start server
+../../modules/http/httpd-start tmp
+sleep 2
+
+# Configure authorized users
+./put-auth tmp admin admin admin admin
+./put-auth tmp admin admin john john
+./put-auth tmp admin admin jane jane
+# Configure the email addresses associated with your OAuth ids here
+./put-auth tmp admin admin /oauth1/john@example.com password
+./put-auth tmp admin admin /oauth2/jane@example.com password
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/start b/sca-cpp/branches/lightweight-sca/hosting/server/start
new file mode 100755
index 0000000000..d4443cb250
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/start
@@ -0,0 +1,126 @@
+#!/bin/sh
+
+# 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.
+
+# For this module to work, add the www.example.com domain to your /etc/hosts as
+# follows:
+# 127.0.0.1 www.example.com
+
+here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
+host=`hostname`
+
+# Configure and start logging
+if [ -x ../../components/log/scribe-cat ]; then
+ ../../components/log/scribed-central-conf tmp
+ ../../components/log/scribed-client-conf tmp localhost
+ ../../components/log/scribed-central-start tmp
+ ../../components/log/scribed-client-start tmp
+fi
+
+# Start memcached
+../../components/cache/memcached-start tmp 11211
+../../components/cache/memcached-start tmp 11212
+
+# Clear document cache
+rm -rf tmp/cache
+
+# Configure server
+../../modules/http/httpd-conf tmp www.example.com 8090 htdocs
+../../modules/http/alt-host-conf tmp ww1.example.com
+../../modules/http/alt-host-conf tmp ww2.example.com
+../../modules/http/httpd-event-conf tmp
+#../../modules/http/cache-conf tmp
+
+# Configure Python component support
+../../modules/server/server-conf tmp
+../../modules/python/python-conf tmp
+
+# Configure server log streaming
+if [ -x ../../components/log/scribe-cat ]; then
+ cat >tmp/conf/log.conf <<EOF
+# Generated by: start $*
+LogLevel notice
+ErrorLog "|$here/../../components/log/scribe-cat $host server"
+CustomLog "|$here/../../components/log/scribe-cat $host server" combined
+
+EOF
+
+else
+ cat >tmp/conf/log.conf <<EOF
+# Generated by: start $*
+ErrorLog $here/tmp/logs/error_log
+CustomLog $here/tmp/logs/access_log combined
+
+EOF
+
+fi
+#../../modules/http/httpd-loglevel-conf tmp debug
+
+# Configure error pages
+cat >>tmp/conf/svhost.conf <<EOF
+# Generated by: start $*
+# Error pages
+ErrorDocument 404 /public/notfound/
+ErrorDocument 401 /public/notauth/
+ErrorDocument 403 /public/notauth/
+ErrorDocument 400 /public/oops/
+ErrorDocument 405 /public/oops/
+ErrorDocument 500 /public/oops/
+ErrorDocument 502 /public/oops/
+ErrorDocument 503 /public/oops/
+
+EOF
+
+# Configure SCA contributions
+cat >>tmp/conf/httpd.conf <<EOF
+# Generated by: start $*
+# Configure SCA Composite
+SCAContribution $here/
+SCAComposite server.composite
+
+# Configure SCA Composite for mass dynamic virtual Hosting
+#SCAVirtualContribution $here/data/apps/
+#SCAVirtualComposite app.composite
+SCAVirtualContributor Composites
+
+# Configure SCA wiring timeout
+SCAWiringTimeout 10
+
+EOF
+
+# Configure resource aliases
+cat >>tmp/conf/httpd.conf <<EOF
+# Generated by: start $*
+Alias /home/home.png $here/htdocs/home/home.png
+Alias /home/home.b64 $here/htdocs/home/home.b64
+Alias /proxy/public/config.js $here/htdocs/public/config.js
+Alias /proxy/public/config-min.js $here/public/config-min.js
+
+EOF
+
+# Configure app resource aliases
+cat >>tmp/conf/svhost.conf <<EOF
+# Generated by: start $*
+# Map /v/<app-name>/<path> to htdocs/app/<path>
+AliasMatch /v/([^/]+)(.*)$ $here/htdocs/app\$2
+
+EOF
+
+# Start server
+../../modules/http/httpd-start tmp
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/stop b/sca-cpp/branches/lightweight-sca/hosting/server/stop
new file mode 100755
index 0000000000..82ecd101ef
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/stop
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+# 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.
+
+../../modules/http/httpd-stop tmp/proxy
+../../modules/http/httpd-stop tmp
+
+../../components/cache/memcached-stop tmp 11211
+../../components/cache/memcached-stop tmp 11212
+
+if [ -x ../../components/log/scribe-cat ]; then
+ ../../components/log/scribed-client-stop tmp
+ ../../components/log/scribed-central-stop tmp
+fi
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/store.py b/sca-cpp/branches/lightweight-sca/hosting/server/store.py
new file mode 100644
index 0000000000..054f546c2d
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/store.py
@@ -0,0 +1,112 @@
+# 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.
+
+# Stores collection implementation
+from util import *
+from sys import debug
+
+# Convert a particular store tag to a store id
+def storeid(tag):
+ return ("store", tag, "store.apps")
+
+# Get a store from the cache
+def getstore(id, cache):
+ debug('store.py::getstore::id', id)
+ val = cache.get(id)
+ if isNil(val) or val is None:
+ return ()
+ store = cdddr(car(val))
+ if not isNil(store) and isList(car(cadr(car(store)))):
+ # Expand list of entries
+ estore = tuple(map(lambda e: cons("'entry", e), cadr(car(store))))
+ debug('store.py::getstore::estore', estore)
+ return estore
+
+ debug('store.py::getstore::store', store)
+ return store
+
+# Put a store into the cache
+def putstore(id, store, cache):
+ debug('store.py::putstore::id', id)
+ debug('store.py::putstore::store', store)
+ val = ((("'feed", ("'title", "App Store"), ("'id", cadr(id))) + store),)
+ return cache.put(id, val)
+
+# Put an app into a store
+def put(id, app, user, cache, apps):
+ debug('store.py::put::id', id)
+ debug('store.py::put::app', app)
+ tag = car(id)
+ appid = cdr(id)
+
+ def putapp(appid, app, store):
+ if isNil(store):
+ return app
+ if car(appid) == cadr(assoc("'id", car(store))):
+ return cons(car(app), cdr(store))
+ return cons(car(store), putapp(appid, app, cdr(store)))
+
+ appentry = (("'entry", assoc("'title", car(app)), ("'id", car(appid)), ("'author", user.get(())), assoc("'updated", car(app)), assoc("'content", car(app))),)
+ debug('store.py::put::appentry', appentry)
+
+ store = putapp(appid, appentry, getstore(storeid(tag), cache))
+ return putstore(storeid(tag), store, cache)
+
+# Get apps from a store
+def get(id, user, cache, apps):
+ debug('store.py::get::id', id)
+ tag = car(id)
+ appid = cdr(id)
+
+ def findapp(appid, store):
+ if isNil(store):
+ return None
+ if car(appid) == cadr(assoc("'id", car(store))):
+ return (car(store),)
+ return findapp(appid, cdr(store))
+
+ if isNil(appid):
+ store = ((("'feed", ("'title", "App Store"), ("'id", tag)) + getstore(storeid(tag), cache)),)
+ debug('store.py::get::store', store)
+ return store
+
+ app = findapp(appid, getstore(storeid(tag), cache))
+ debug('store.py::get::app', app)
+ return app
+
+# Delete apps from a store
+def delete(id, user, cache, apps):
+ debug('store.py::delete::id', id)
+ tag = car(id)
+ appid = cdr(id)
+
+ if isNil(appid):
+ return cache.delete(storeid(tag))
+
+ def deleteapp(appid, store):
+ if isNil(store):
+ return ()
+ if car(appid) == cadr(assoc("'id", car(store))):
+ return cdr(store)
+ return cons(car(store), deleteapp(appid, cdr(store)))
+
+ store = getstore(storeid(tag), cache)
+ deleted = deleteapp(appid, store)
+ if deleted == store:
+ return False
+ return putstore(storeid(tag), deleted, cache)
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/test.py b/sca-cpp/branches/lightweight-sca/hosting/server/test.py
new file mode 100755
index 0000000000..2575fb7b92
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/test.py
@@ -0,0 +1,296 @@
+#!/usr/bin/python
+# 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.
+
+# Test the hosting server components
+
+import sys
+sys.debug = lambda *l: sys.stderr.write('python::debug ' + repr(l) + '\n')
+import time
+time.strftime = lambda f: 'Jan 01, 2012'
+
+import unittest
+from test.property import *
+from test.reference import *
+from test.cache import *
+
+import user
+import accounts
+import pages
+import composites
+import apps
+import store
+import dashboards
+
+def testUser():
+ # Return current user
+ assert user.get((), mkprop('user', lambda: 'johndoe'), mkprop('email', lambda: 'jdoe@example.com'), mkprop('nick', lambda: 'jdoe'), mkprop('full', lambda: 'john doe'), mkprop('first', lambda: 'john'), mkprop('last', lambda: 'doe'), mkprop('realm', lambda: 'example.com'), mkprop('host', lambda: 'localhost')) == 'jdoe@example.com'
+ return True
+
+def testAccounts():
+ # Get default account
+ defaccount = (("'entry", ("'title", 'jdoe@example.com'), ("'id", 'jdoe@example.com'), ("'updated", 'Jan 01, 2012')),)
+ assert accounts.get((), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {})) == defaccount
+
+ # Get user's account
+ jdoe = (("'entry", ("'title", 'John Doe'), ("'id", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'key", 'value'))),)
+ assert accounts.get((), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {('accounts', 'jdoe@example.com', 'user.account') : jdoe})) == jdoe
+
+ # Put and get account
+ cache1 = mkcache('cache', {})
+ assert accounts.put((), jdoe, mkref('user', lambda id: 'jdoe@example.com'), cache1) == True
+ assert accounts.get((), mkref('user', lambda id: 'jdoe@example.com'), cache1) == jdoe
+ return True
+
+def testPages():
+ # Get default page
+ defpage = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 01, 2012')),)
+ app1 = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 03, 2012'), ("'content", ())),)
+ assert pages.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {}), mkref('apps', lambda id: None)) == defpage
+ defpagefromapp = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 03, 2012')),)
+ assert pages.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {}), mkref('apps', lambda id: app1)) == defpagefromapp
+
+ # Get a page
+ page1 = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ())),)
+ assert pages.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {('apps', 'app1', 'htdocs', 'app.html') : page1}), mkref('apps', lambda id: app1)) == page1
+
+ # Put and get a page
+ cache1 = mkcache('cache', {})
+ page1updated = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 01, 2012'), ("'content", ())),)
+ assert pages.put(('app1',), page1, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1)) == True
+ assert pages.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1)) == page1updated
+
+ # Reject put from user other than the author
+ app1otherauthor = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jane@example.com'), ("'updated", 'Jan 03, 2012'), ("'content", ())),)
+ page1otherauthor = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jane@example.com'), ("'updated", 'Jan 02, 2012')),)
+ assert pages.put(('app1',), page1, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1otherauthor)) == False
+ assert pages.put(('app1',), page1otherauthor, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1otherauthor)) == False
+ assert pages.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1)) == page1updated
+
+ # Reject delete from user other than the author
+ assert pages.delete(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1otherauthor)) == False
+ assert pages.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1)) == page1updated
+
+ # Delete a page
+ assert pages.delete(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1)) == True
+ assert pages.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1)) == defpagefromapp
+ return True
+
+def testComposites():
+ # Get default composite
+ defcomposite = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 01, 2012')),)
+ app1 = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 03, 2012'), ("'content", ())),)
+ assert composites.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {}), mkref('apps', lambda id: None)) == defcomposite
+ defcompositefromapp = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 03, 2012')),)
+ assert composites.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {}), mkref('apps', lambda id: app1)) == defcompositefromapp
+
+ # Get a composite
+ composite1 = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ())),)
+ assert composites.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {('apps', 'app1', 'app.composite') : composite1}), mkref('apps', lambda id: app1)) == composite1
+
+ # Put and get a composite
+ cache1 = mkcache('cache', {})
+ composite1updated = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 01, 2012'), ("'content", ())),)
+ assert composites.put(('app1',), composite1, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1)) == True
+ assert composites.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1)) == composite1updated
+
+ # Reject put from user other than the author
+ app1otherauthor = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jane@example.com'), ("'updated", 'Jan 03, 2012'), ("'content", ())),)
+ composite1otherauthor = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jane@example.com'), ("'updated", 'Jan 02, 2012')),)
+ assert composites.put(('app1',), composite1, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1otherauthor)) == False
+ assert composites.put(('app1',), composite1otherauthor, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1otherauthor)) == False
+ assert composites.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1)) == composite1updated
+
+ # Reject delete from user other than the author
+ assert composites.delete(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1otherauthor)) == False
+ assert composites.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1)) == composite1updated
+
+ # Delete a composite
+ assert composites.delete(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1)) == True
+ assert composites.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1)) == defcompositefromapp
+ return True
+
+def testApps():
+ # Get default app
+ defapp = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 01, 2012'), ("'content", ("'stats", ("'description", '')))),)
+ assert apps.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {}), mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None)) == defapp
+
+ # Get an app
+ app1 = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 01, 2012'), ("'content", ("'stats", ("'description", '')))),)
+ assert apps.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {('apps', 'app1', 'app.stats') : app1}), mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None)) == app1
+
+ # Put and get an app
+ cache1 = mkcache('cache', {})
+ assert apps.put(('app1',), app1, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('dashboard', lambda id, app: True), mkref('store', lambda id, app: True), mkref('composites', lambda id, app: True), mkref('pages', lambda id, app: True)) == True
+ assert apps.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None)) == app1
+ return True
+
+ # Reject put from user other than the author
+ app1otherauthor = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jane@example.com'), ("'updated", 'Jan 03, 2012'), ("'content", ())),)
+ assert apps.put(('app1',), app1, mkref('user', lambda id: 'jane@example.com'), cache1, mkref('dashboard', lambda id, app: True), mkref('store', lambda id, app: True), mkref('composites', lambda id, app: True), mkref('pages', lambda id, app: True)) == false
+ assert apps.get(('app1',), mkref('user', lambda id: 'jane@example.com'), cache1, mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None)) == app1
+
+ # Reject delete from user other than the author
+ assert apps.delete(('app1',), mkref('user', lambda id: 'jane@example.com'), cache1, mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None)) == False
+ assert apps.get(('app1',), mkref('user', lambda id: 'jane@example.com'), cache1, mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None)) == app1
+
+ # Delete an app
+ assert apps.delete(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None)) == True
+ assert apps.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {}), mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None)) == defapp
+ return True
+
+def testStore():
+ # Get default store
+ defstore = (("'feed", ("'title", 'App Store'), ("'id", 'top')),)
+ assert store.get(('top',), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {}), mkref('apps', lambda id: None)) == defstore
+
+ # Get a store
+ store1= (("'feed", ("'title", 'App Store'), ("'id", 'top'), ("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app1')))), ("'entry", ("'title", 'app2'), ("'id", 'app2'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app2'))))),)
+ assert store.get(('top',), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {('store', 'top', 'store.apps') : store1}), mkref('apps', lambda id: None)) == store1
+
+ store1compact = (("'feed", ("'title", 'App Store'), ("'id", 'top'), ("'entry", ((("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app1')))), (("'title", 'app2'), ("'id", 'app2'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app2'))))))),)
+ assert store.get(('top',), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {('store', 'top', 'store.apps') : store1compact}), mkref('apps', lambda id: None)) == store1
+
+ # Put an app in an empty store
+ cache1 = mkcache('cache', {})
+ app1 = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app1')))),)
+ store1withapp1 = (("'feed", ("'title", 'App Store'), ("'id", 'top'), ("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app1'))))),)
+ assert store.put(('top', 'app1'), app1, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert store.get(('top',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == store1withapp1
+ assert store.put(('top', 'app1'), app1, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert store.get(('top',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == store1withapp1
+
+ # Put a second app in the store
+ app2 = (("'entry", ("'title", 'app2'), ("'id", 'app2'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app2')))),)
+ store1withapp2 = (("'feed", ("'title", 'App Store'), ("'id", 'top'), ("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app1')))), ("'entry", ("'title", 'app2'), ("'id", 'app2'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app2'))))),)
+ assert store.put(('top', 'app2'), app2, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert store.get(('top',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == store1withapp2
+ assert store.put(('top', 'app1'), app1, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert store.get(('top',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == store1withapp2
+ assert store.put(('top', 'app2'), app2, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert store.get(('top',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == store1withapp2
+
+ # Put a third app in the store
+ app3 = (("'entry", ("'title", 'app3'), ("'id", 'app3'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app3')))),)
+ store1withapp3 = (("'feed", ("'title", 'App Store'), ("'id", 'top'), ("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app1')))), ("'entry", ("'title", 'app2'), ("'id", 'app2'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app2')))), ("'entry", ("'title", 'app3'), ("'id", 'app3'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app3'))))),)
+ assert store.put(('top', 'app3'), app3, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert store.get(('top',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == store1withapp3
+ assert store.put(('top', 'app1'), app1, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert store.get(('top',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == store1withapp3
+ assert store.put(('top', 'app2'), app2, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert store.get(('top',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == store1withapp3
+ assert store.put(('top', 'app3'), app3, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert store.get(('top',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == store1withapp3
+
+ # Get an app from the store
+ assert store.get(('top','app1'), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == app1
+ assert store.get(('top','app2'), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == app2
+ assert store.get(('top','app3'), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == app3
+
+ # Put a third app in the store, starting from a compacted list
+ cache2 = mkcache('cache', {('store', 'top', 'store.apps') : store1compact})
+ assert store.put(('top', 'app3'), app3, mkref('user', lambda id: 'jdoe@example.com'), cache2, mkref('apps', lambda id: None)) == True
+ assert store.get(('top',), mkref('user', lambda id: 'jdoe@example.com'), cache2, mkref('apps', lambda id: None)) == store1withapp3
+
+ # Delete the apps
+ assert store.delete(('top', 'app2'), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert store.delete(('top', 'app4'), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == False
+ assert store.delete(('top', 'app1'), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert store.delete(('top', 'app3'), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert store.get(('top',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == defstore
+
+ # Delete a store
+ assert store.delete(('top',), mkref('user', lambda id: 'jdoe@example.com'), cache2, mkref('apps', lambda id: None)) == True
+ assert store.get(('top',), mkref('user', lambda id: 'jdoe@example.com'), cache2, mkref('apps', lambda id: None)) == defstore
+ return True
+
+def testDashboards():
+ # Get default dashboard
+ defdashboard = (("'feed", ("'title", 'Your Apps'), ("'id", 'jdoe@example.com')),)
+ assert dashboards.get((), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {}), mkref('apps', lambda id: None)) == defdashboard
+
+ # Get the user's dashboard
+ dash1= (("'feed", ("'title", 'Your Apps'), ("'id", 'jdoe@example.com'), ("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app1')))), ("'entry", ("'title", 'app2'), ("'id", 'app2'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app2'))))),)
+ assert dashboards.get((), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {('dashboards', 'jdoe@example.com', 'user.apps') : dash1}), mkref('apps', lambda id: None)) == dash1
+
+ dash1compact = (("'feed", ("'title", 'Your Apps'), ("'id", 'jdoe@example.com'), ("'entry", ((("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app1')))), (("'title", 'app2'), ("'id", 'app2'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app2'))))))),)
+ assert dashboards.get((), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {('dashboards', 'jdoe@example.com', 'user.apps') : dash1compact}), mkref('apps', lambda id: None)) == dash1
+
+ # Put an app in an empty dashboard
+ cache1 = mkcache('cache', {})
+ app1 = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app1')))),)
+ dash1withapp1 = (("'feed", ("'title", 'Your Apps'), ("'id", 'jdoe@example.com'), ("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app1'))))),)
+ assert dashboards.put(('app1',), app1, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert dashboards.get((), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == dash1withapp1
+ assert dashboards.put(('app1',), app1, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert dashboards.get((), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == dash1withapp1
+
+ # Put a second app in the dashboard
+ app2 = (("'entry", ("'title", 'app2'), ("'id", 'app2'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app2')))),)
+ dash1withapp2 = (("'feed", ("'title", 'Your Apps'), ("'id", 'jdoe@example.com'), ("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app1')))), ("'entry", ("'title", 'app2'), ("'id", 'app2'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app2'))))),)
+ assert dashboards.put(('app2',), app2, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert dashboards.get((), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == dash1withapp2
+ assert dashboards.put(('app1',), app1, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert dashboards.get((), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == dash1withapp2
+ assert dashboards.put(('app2',), app2, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert dashboards.get((), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == dash1withapp2
+
+ # Put a third app in the dashboard
+ app3 = (("'entry", ("'title", 'app3'), ("'id", 'app3'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app3')))),)
+ dash1withapp3 = (("'feed", ("'title", 'Your Apps'), ("'id", 'jdoe@example.com'), ("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app1')))), ("'entry", ("'title", 'app2'), ("'id", 'app2'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app2')))), ("'entry", ("'title", 'app3'), ("'id", 'app3'), ("'author", 'jdoe@example.com'), ("'updated", 'Jan 02, 2012'), ("'content", ("'stats", ("'description", 'app3'))))),)
+ assert dashboards.put(('app3',), app3, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert dashboards.get((), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == dash1withapp3
+ assert dashboards.put(('app1',), app1, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert dashboards.get((), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == dash1withapp3
+ assert dashboards.put(('app2',), app2, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert dashboards.get((), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == dash1withapp3
+ assert dashboards.put(('app3',), app3, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert dashboards.get((), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == dash1withapp3
+
+ # Get an app from the user's dashboard
+ assert dashboards.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == app1
+ assert dashboards.get(('app2',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == app2
+ assert dashboards.get(('app3',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == app3
+
+ # Put a third app in the dashboard, starting from a compacted list
+ cache2 = mkcache('cache', {('dashboards', 'jdoe@example.com', 'user.apps') : dash1compact})
+ assert dashboards.put(('app3',), app3, mkref('user', lambda id: 'jdoe@example.com'), cache2, mkref('apps', lambda id: None)) == True
+ assert dashboards.get((), mkref('user', lambda id: 'jdoe@example.com'), cache2, mkref('apps', lambda id: None)) == dash1withapp3
+
+ # Delete the apps
+ assert dashboards.delete(('app2',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert dashboards.delete(('app4',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == False
+ assert dashboards.delete(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert dashboards.delete(('app3',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == True
+ assert dashboards.get((), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: None)) == defdashboard
+
+ # Delete the dashboard
+ assert dashboards.delete((), mkref('user', lambda id: 'jdoe@example.com'), cache2, mkref('apps', lambda id: None)) == True
+ assert dashboards.get((), mkref('user', lambda id: 'jdoe@example.com'), cache2, mkref('apps', lambda id: None)) == defdashboard
+ return True
+
+if __name__ == '__main__':
+ print 'Testing...'
+ testUser()
+ testAccounts()
+ testPages()
+ testComposites()
+ testApps()
+ testStore()
+ testDashboards()
+ print 'OK'
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/test/__init__.py b/sca-cpp/branches/lightweight-sca/hosting/server/test/__init__.py
new file mode 100644
index 0000000000..de5c2d1b1e
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/test/__init__.py
@@ -0,0 +1,17 @@
+# 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.
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/test/cache.py b/sca-cpp/branches/lightweight-sca/hosting/server/test/cache.py
new file mode 100644
index 0000000000..98fa174c00
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/test/cache.py
@@ -0,0 +1,48 @@
+# 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.
+
+# Mockup cache for testing
+
+class cache:
+ def __init__(self, name, values):
+ self.name = name
+ self.values = values
+
+ def get(self, id):
+ if id in self.values:
+ return self.values[id]
+ return None
+
+ def put(self, id, value):
+ self.values[id] = value
+ return True
+
+ def post(self, id):
+ return self.put(id)
+
+ def delete(self, id):
+ if id in self.values:
+ del self.values[id]
+ return True
+ return False
+
+ def __repr__(self):
+ return repr((self.name, self.values))
+
+def mkcache(name, values = {}):
+ return cache(name, values)
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/test/property.py b/sca-cpp/branches/lightweight-sca/hosting/server/test/property.py
new file mode 100644
index 0000000000..1cbb4b2cab
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/test/property.py
@@ -0,0 +1,38 @@
+# 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.
+
+# Mockup component properties for testing
+
+class property:
+ def __init__(self, name, l):
+ self.name = name
+ self.l = l
+
+ def __call__(self, *args):
+ return self.l(*args)
+
+ def __getattr__(self, name):
+ if name == "eval":
+ return self
+ raise AttributeError()
+
+ def __repr__(self):
+ return repr((self.name, self.l()))
+
+def mkprop(name, l):
+ return property(name, l)
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/test/reference.py b/sca-cpp/branches/lightweight-sca/hosting/server/test/reference.py
new file mode 100644
index 0000000000..fe4a66a087
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/test/reference.py
@@ -0,0 +1,38 @@
+# 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.
+
+# Mockup component references for testing
+
+class reference:
+ def __init__(self, name, l):
+ self.name = name
+ self.l = l
+
+ def __call__(self, *args):
+ return self.l(*args)
+
+ def __getattr__(self, name):
+ if name == "get" or name == "put":
+ return self
+ raise AttributeError()
+
+ def __repr__(self):
+ return repr((self.name, self.l))
+
+def mkref(name, l):
+ return reference(name, l)
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/user.py b/sca-cpp/branches/lightweight-sca/hosting/server/user.py
new file mode 100644
index 0000000000..8038e43563
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/user.py
@@ -0,0 +1,27 @@
+# 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.
+
+# User info service component
+
+# Return the current user id
+def get(i, user, email, nick, full, first, last, realm, host):
+ if email.eval() != '?':
+ return email.eval()
+ if user.eval() != '?':
+ return user.eval()
+ return 'anonymous'
+
diff --git a/sca-cpp/branches/lightweight-sca/hosting/server/util.py b/sca-cpp/branches/lightweight-sca/hosting/server/util.py
new file mode 100644
index 0000000000..24467fd2cb
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/hosting/server/util.py
@@ -0,0 +1,164 @@
+# 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.
+
+# Simple utility functions
+from sys import maxint
+
+# Scheme-like lists
+def cons(a, b):
+ return (a,) + b
+
+def car(l):
+ return l[0]
+
+def first(l):
+ return car(l)
+
+def cdr(l):
+ return l[1:]
+
+def rest(l):
+ return cdr(l)
+
+def cadr(l):
+ return car(cdr(l))
+
+def cddr(l):
+ return cdr(cdr(l))
+
+def caddr(l):
+ return car(cddr(l))
+
+def cdddr(l):
+ return cdr(cdr(cdr(l)))
+
+def cadddr(l):
+ return car(cdddr(l))
+
+def append(a, b):
+ return a + b
+
+def reverse(l):
+ r = list(l)
+ r.reverse()
+ return tuple(r)
+
+def isNil(l):
+ if isinstance(l, streampair):
+ return l.isNil()
+ return l == ()
+
+def isSymbol(v):
+ return isinstance(v, basestring) and v[0:1] == "'"
+
+def isString(v):
+ return isinstance(v, basestring) and v[0:1] != "'"
+
+def isList(v):
+ if getattr(v, '__iter__', False) == False:
+ return False
+ if isinstance(v, basestring) or isinstance(v, dict):
+ return False
+ return True
+
+def isTaggedList(v, t):
+ return isList(v) and not isNil(v) and car(v) == t
+
+
+# Scheme-like streams
+class streampair(object):
+ def __init__(self, car, cdr):
+ self.car = car
+ self.cdr = cdr
+
+ def __repr__(self):
+ return repr(self[0:len(self)])
+
+ def isNil(self):
+ return self.cdr == ()
+
+ def __len__(self):
+ if self.cdr == ():
+ return 0
+ return 1 + len(self.cdr())
+
+ def __getitem__(self, i):
+ if i == 0:
+ return self.car
+ return self.cdr()[i - 1]
+
+ def __getslice__(self, i, j):
+ if isNil(self):
+ return ()
+ if i > 0:
+ if j == maxint:
+ return self.cdr()[i - 1: j]
+ return self.cdr()[i - 1: j - 1]
+ if j == maxint:
+ return self
+ if j == 0:
+ return (self.car,)
+ return (self.car,) + self.cdr()[: j - 1]
+
+ def __eq__(self, other):
+ sl = len(self)
+ ol = len(other)
+ if sl != ol:
+ return False
+ return self[0: sl] == other[0: ol]
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+def cons_stream(car, cdr):
+ return streampair(car, cdr)
+
+
+# Scheme-like associations
+def assoc(k, l):
+ if l == ():
+ return None
+
+ if k == car(car(l)):
+ return car(l)
+ return assoc(k, cdr(l))
+
+# Currying / partial function application
+def curry(f, *args):
+ return lambda *a: f(*(args + a))
+
+# Convert a path represented as a list of values to a string
+def path(p):
+ if isNil(p):
+ return ""
+ return "/" + car(p) + path(cdr(p))
+
+# Split a path into a list of segments
+def tokens(path):
+ return tuple(filter(lambda s: len(s) != 0, path.split("/")))
+
+# Return true if s1 contains s2
+def contains(s1, s2):
+ return s1.find(s2) != -1
+
+# Write a list of strings to a stream
+def writeStrings(l, os):
+ if l == ():
+ return os
+ os.write(car(l))
+ return writeStrings(cdr(l), os)
+