summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-04-17 05:00:18 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-04-17 05:00:18 +0000
commit5e5a4c9daa1bc9da5ee0d6121e51e067d9017037 (patch)
tree97836c5a49ffee90f8f707cab8efbf55c0c45cd3
parent45629fcf8a2f5d6048868e16292d28fe73808ebd (diff)
Copy trunk into gcc-4.4 branch before porting to gcc-4.5.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@935127 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--sca-cpp/branches/gcc-4.4/AUTHORS5
-rw-r--r--sca-cpp/branches/gcc-4.4/COPYING203
-rw-r--r--sca-cpp/branches/gcc-4.4/ChangeLog12
-rw-r--r--sca-cpp/branches/gcc-4.4/INSTALL284
-rw-r--r--sca-cpp/branches/gcc-4.4/LICENSE323
-rw-r--r--sca-cpp/branches/gcc-4.4/Makefile.am45
-rw-r--r--sca-cpp/branches/gcc-4.4/NEWS13
-rw-r--r--sca-cpp/branches/gcc-4.4/NOTICE42
-rw-r--r--sca-cpp/branches/gcc-4.4/README81
-rwxr-xr-xsca-cpp/branches/gcc-4.4/bootstrap31
-rw-r--r--sca-cpp/branches/gcc-4.4/components/Makefile.am22
-rw-r--r--sca-cpp/branches/gcc-4.4/components/cache/Makefile.am35
-rw-r--r--sca-cpp/branches/gcc-4.4/components/cache/client-test.cpp130
-rw-r--r--sca-cpp/branches/gcc-4.4/components/cache/memcache-test.cpp82
-rw-r--r--sca-cpp/branches/gcc-4.4/components/cache/memcache.composite32
-rw-r--r--sca-cpp/branches/gcc-4.4/components/cache/memcache.cpp133
-rw-r--r--sca-cpp/branches/gcc-4.4/components/cache/memcache.hpp175
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/cache/memcached-start25
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/cache/memcached-stop26
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/cache/memcached-test30
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/cache/server-test41
-rw-r--r--sca-cpp/branches/gcc-4.4/components/chat/Makefile.am54
-rw-r--r--sca-cpp/branches/gcc-4.4/components/chat/chat.composite52
-rw-r--r--sca-cpp/branches/gcc-4.4/components/chat/chatter.cpp162
-rw-r--r--sca-cpp/branches/gcc-4.4/components/chat/client-test.cpp111
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/chat/echo-test31
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/chat/server-test39
-rw-r--r--sca-cpp/branches/gcc-4.4/components/chat/server-test.scm20
-rw-r--r--sca-cpp/branches/gcc-4.4/components/chat/test/TestVysperServer.java79
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/chat/vysper-classpath29
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/chat/vysper-start25
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/chat/vysper-stop25
-rw-r--r--sca-cpp/branches/gcc-4.4/components/chat/xmpp-test.cpp103
-rw-r--r--sca-cpp/branches/gcc-4.4/components/chat/xmpp.hpp330
-rw-r--r--sca-cpp/branches/gcc-4.4/components/log/Makefile.am17
-rw-r--r--sca-cpp/branches/gcc-4.4/components/log/log.composite33
-rw-r--r--sca-cpp/branches/gcc-4.4/components/queue/Makefile.am46
-rw-r--r--sca-cpp/branches/gcc-4.4/components/queue/client-test.cpp99
-rw-r--r--sca-cpp/branches/gcc-4.4/components/queue/qpid-test.cpp97
-rw-r--r--sca-cpp/branches/gcc-4.4/components/queue/qpid.hpp260
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/queue/qpidd-start24
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/queue/qpidd-stop26
-rw-r--r--sca-cpp/branches/gcc-4.4/components/queue/queue-listener.cpp158
-rw-r--r--sca-cpp/branches/gcc-4.4/components/queue/queue-sender.cpp72
-rw-r--r--sca-cpp/branches/gcc-4.4/components/queue/queue.composite56
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/queue/send-test31
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/queue/server-test43
-rw-r--r--sca-cpp/branches/gcc-4.4/components/queue/server-test.scm20
-rw-r--r--sca-cpp/branches/gcc-4.4/components/sqldb/Makefile.am43
-rw-r--r--sca-cpp/branches/gcc-4.4/components/sqldb/client-test.cpp130
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/sqldb/pgsql25
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/sqldb/pgsql-start37
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/sqldb/pgsql-stop28
-rw-r--r--sca-cpp/branches/gcc-4.4/components/sqldb/pgsql-test.cpp82
-rw-r--r--sca-cpp/branches/gcc-4.4/components/sqldb/pgsql.hpp227
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/sqldb/server-test43
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/sqldb/sqldb-test31
-rw-r--r--sca-cpp/branches/gcc-4.4/components/sqldb/sqldb.composite34
-rw-r--r--sca-cpp/branches/gcc-4.4/components/sqldb/sqldb.cpp135
-rw-r--r--sca-cpp/branches/gcc-4.4/components/store/Makefile.am20
-rw-r--r--sca-cpp/branches/gcc-4.4/components/store/store.composite32
-rw-r--r--sca-cpp/branches/gcc-4.4/components/webservice/Makefile.am53
-rw-r--r--sca-cpp/branches/gcc-4.4/components/webservice/axiom-test.cpp85
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/webservice/axis2-conf55
-rw-r--r--sca-cpp/branches/gcc-4.4/components/webservice/axis2-dispatcher.cpp138
-rw-r--r--sca-cpp/branches/gcc-4.4/components/webservice/axis2-service.cpp151
-rw-r--r--sca-cpp/branches/gcc-4.4/components/webservice/axis2-test.cpp71
-rw-r--r--sca-cpp/branches/gcc-4.4/components/webservice/axis2.hpp194
-rw-r--r--sca-cpp/branches/gcc-4.4/components/webservice/axis2.xml148
-rw-r--r--sca-cpp/branches/gcc-4.4/components/webservice/client-test.cpp94
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/webservice/echo-test37
-rw-r--r--sca-cpp/branches/gcc-4.4/components/webservice/module.xml25
-rwxr-xr-xsca-cpp/branches/gcc-4.4/components/webservice/server-test49
-rw-r--r--sca-cpp/branches/gcc-4.4/components/webservice/server-test.scm21
-rw-r--r--sca-cpp/branches/gcc-4.4/components/webservice/services.xml25
-rw-r--r--sca-cpp/branches/gcc-4.4/components/webservice/webservice-client.cpp65
-rw-r--r--sca-cpp/branches/gcc-4.4/components/webservice/webservice-listener.cpp86
-rw-r--r--sca-cpp/branches/gcc-4.4/components/webservice/webservice.composite48
-rw-r--r--sca-cpp/branches/gcc-4.4/configure.ac712
-rw-r--r--sca-cpp/branches/gcc-4.4/doc/Doxyfile.in1541
-rw-r--r--sca-cpp/branches/gcc-4.4/doc/Makefile.am30
-rw-r--r--sca-cpp/branches/gcc-4.4/etc/git-exclude99
-rwxr-xr-xsca-cpp/branches/gcc-4.4/etc/httpd-ipcrm23
-rwxr-xr-xsca-cpp/branches/gcc-4.4/etc/memgrind23
-rw-r--r--sca-cpp/branches/gcc-4.4/etc/svn-config136
-rw-r--r--sca-cpp/branches/gcc-4.4/etc/svn-ignore55
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/Makefile.am45
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/config.hpp76
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/dynlib-test.cpp48
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/dynlib.hpp91
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/element.hpp304
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/fstream.hpp162
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/function.hpp238
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/gc.hpp276
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/hash-test.cpp135
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/hash.hpp207
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/kernel-test.cpp594
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/list.hpp559
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/mem-test.cpp162
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/monad.hpp486
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/parallel-test.cpp166
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/parallel.hpp319
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/perf.hpp68
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/sstream.hpp240
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/stream.hpp200
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/string-test.cpp196
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/string.hpp291
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/tree.hpp125
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/value.hpp593
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/xml-test.cpp180
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/xml.hpp369
-rw-r--r--sca-cpp/branches/gcc-4.4/kernel/xsd-test.cpp107
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/Makefile.am22
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/atom/Makefile.am22
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/atom/atom-test.cpp192
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/atom/atom.hpp178
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/http/Makefile.am34
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/http/conf/mime.types607
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/http/curl-test.cpp91
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/http/curl.hpp441
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/http/htdocs/index.html21
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/http/http-test32
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/http/httpd-ca-conf89
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/http/httpd-cert-conf58
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/http/httpd-conf93
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/http/httpd-restart25
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/http/httpd-ssl-conf94
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/http/httpd-start25
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/http/httpd-stop25
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/http/httpd-test40
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/http/httpd.hpp404
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/Makefile.am64
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/client-test.cpp39
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/domain-test.composite42
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/driver.hpp61
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/eval.hpp567
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/java/java-conf29
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/java-shell.cpp40
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/java-test.cpp138
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/jni-test.cpp80
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/mod-java.cpp80
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/mod-java.hpp77
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/ClassLoader.java76
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/InvocationHandler.java59
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/IterableUtil.java368
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/Service.java53
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/UUIDUtil.java32
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/java/server-test41
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/test/Adder.java26
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/test/AdderImpl.java28
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/test/CalcImpl.java52
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/test/Client.java34
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/test/ClientImpl.java44
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/test/Server.java34
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/java/test/ServerImpl.java51
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/java/wiring-test80
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/json/Makefile.am22
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/json/json-test.cpp176
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/json/json.hpp403
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/python/Makefile.am54
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/python/client-test.cpp39
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/python/client-test.py35
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/python/domain-test.composite42
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/python/driver.hpp63
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/python/eval.hpp300
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/python/mod-python.cpp66
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/python/mod-python.hpp79
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/python/python-conf28
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/python/python-shell.cpp40
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/python/python-test.cpp109
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/python/server-test39
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/python/server-test.py42
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/python/tuscany-sca-1.1-implementation-python.xsd43
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/python/wiring-test78
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/scdl/Makefile.am22
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/scdl/scdl-test.cpp124
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/scdl/scdl.hpp178
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/scdl/test.composite64
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/scheme/Makefile.am26
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/scheme/driver.hpp76
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/scheme/environment.hpp179
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/scheme/eval-shell.cpp36
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/scheme/eval-test.cpp231
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/scheme/eval.hpp290
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/scheme/io.hpp217
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/scheme/primitive.hpp285
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/scheme/tuscany-sca-1.1-implementation-scheme.xsd43
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/Makefile.am46
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/client-test.cpp39
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/client-test.hpp350
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/client-test.scm38
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/server/cpp-conf28
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/domain-test.composite49
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/htdocs/entry.xml2
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/htdocs/feed.xml2
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/htdocs/index.html21
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/htdocs/json-request.txt1
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/htdocs/json-result.txt1
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/server/httpd-test78
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/impl-test.cpp76
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/mod-cpp.hpp102
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/mod-eval.cpp62
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/mod-eval.hpp615
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/mod-scheme.hpp89
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/mod-wiring.cpp379
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/server/scheme-conf28
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/server/server-conf47
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/server/server-test39
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/server/server-test.scm44
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/server/wiring-test78
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/Makefile.am52
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/app.yaml50
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/wsgi/atom-test.py153
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/atomutil.py103
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/client-test.cpp40
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/client-test.py35
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/wsgi/composite.py220
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/domain-test.composite42
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/elemutil.py168
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/wsgi/gae-start29
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/wsgi/gae-stop29
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/wsgi/gae-test30
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/entry.xml2
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/feed.xml2
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/index.html1
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/json-request.txt1
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/json-result.txt1
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/wsgi/http-test39
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/wsgi/http-test.py32
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/httputil.py78
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/wsgi/json-test.py59
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/jsonutil.py140
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/scdl.py167
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/wsgi/server-test30
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/server-test.py44
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/wsgi/util-test35
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/util.py83
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/wsgi/wiring-test75
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/wsgi/wsgi-start28
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/wsgi/wsgi-stop28
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/wsgi/wsgi-test71
-rwxr-xr-xsca-cpp/branches/gcc-4.4/modules/wsgi/xml-test.py74
-rw-r--r--sca-cpp/branches/gcc-4.4/modules/wsgi/xmlutil.py114
-rw-r--r--sca-cpp/branches/gcc-4.4/samples/Makefile.am17
-rw-r--r--sca-cpp/branches/gcc-4.4/samples/README3
-rw-r--r--sca-cpp/branches/gcc-4.4/test/Makefile.am19
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-cpp/Makefile.am27
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-cpp/currency-converter.cpp67
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-cpp/fruits-catalog.cpp85
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-cpp/htdocs/.htaccess19
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-cpp/htdocs/store.html169
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-cpp/htdocs/store.js661
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-cpp/server-test40
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-cpp/shopping-cart.cpp152
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-cpp/ssl-start34
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-cpp/start31
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-cpp/stop21
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-cpp/store.composite59
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-gae/Makefile.am35
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-gae/app.yaml52
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-gae/currency-converter.py29
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-gae/domain-backend.composite32
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-gae/domain-frontend.composite70
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-gae/domain-single.composite69
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-gae/domain.composite69
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-gae/fruits-catalog.py34
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-gae/gmemcache.py45
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-gae/htdocs/store.html169
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-gae/htdocs/store.js661
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-gae/htpasswd.py21
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-gae/server-test41
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-gae/shopping-cart.py77
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-gae/start21
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-gae/stop21
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-gae/store.py44
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-java/Makefile.am30
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-java/htdocs/.htaccess19
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-java/htdocs/store.html169
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-java/htdocs/store.js661
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-java/server-test40
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-java/ssl-start36
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-java/start33
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-java/stop23
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-java/store.composite59
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-java/store/CurrencyConverter.java28
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-java/store/CurrencyConverterImpl.java45
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-java/store/FruitsCatalogImpl.java58
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-java/store/ShoppingCartImpl.java119
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-python/Makefile.am22
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-python/currency-converter.py29
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-python/fruits-catalog.py34
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-python/htdocs/.htaccess19
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-python/htdocs/store.html169
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-python/htdocs/store.js661
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-python/server-test40
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-python/shopping-cart.py78
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-python/ssl-start34
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-python/start31
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-python/stop21
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-python/store.composite69
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-python/store.py44
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-scheme/Makefile.am23
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-scheme/currency-converter.scm27
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-scheme/fruits-catalog.scm33
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-scheme/htdocs/.htaccess19
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-scheme/htdocs/store.html169
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-scheme/htdocs/store.js661
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-scheme/script-test.cpp96
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-scheme/script-test.scm140
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-scheme/server-test40
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-scheme/shopping-cart.scm84
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-scheme/ssl-start34
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-scheme/start31
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-scheme/stop21
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-scheme/store.composite69
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-scheme/store.scm50
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-sql/Makefile.am19
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-sql/currency-converter.scm27
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-sql/fruits-catalog.scm33
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-sql/htdocs/.htaccess19
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-sql/htdocs/store.html169
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-sql/htdocs/store.js661
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-sql/server-test40
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-sql/shopping-cart.scm84
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-sql/ssl-start35
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-sql/start32
-rwxr-xr-xsca-cpp/branches/gcc-4.4/test/store-sql/stop21
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-sql/store.composite71
-rw-r--r--sca-cpp/branches/gcc-4.4/test/store-sql/store.scm50
-rwxr-xr-xsca-cpp/branches/gcc-4.4/ubuntu/ubuntu-bin-image66
-rwxr-xr-xsca-cpp/branches/gcc-4.4/ubuntu/ubuntu-dev-image38
-rwxr-xr-xsca-cpp/branches/gcc-4.4/ubuntu/ubuntu-gcc-4.552
-rwxr-xr-xsca-cpp/branches/gcc-4.4/ubuntu/ubuntu-install228
-rwxr-xr-xsca-cpp/branches/gcc-4.4/ubuntu/uec2-bin-image23
-rwxr-xr-xsca-cpp/branches/gcc-4.4/ubuntu/uec2-conf39
-rwxr-xr-xsca-cpp/branches/gcc-4.4/ubuntu/uec2-setenv34
-rwxr-xr-xsca-cpp/branches/gcc-4.4/ubuntu/uec2-start29
-rwxr-xr-xsca-cpp/branches/gcc-4.4/ubuntu/uec2-status23
-rwxr-xr-xsca-cpp/branches/gcc-4.4/ubuntu/uec2-stop24
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/external/XMLSchema.dtd402
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/external/datatypes.dtd204
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/external/oasis-200401-wss-wssecurity-secext-1.0.xsd195
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/external/oasis-200401-wss-wssecurity-utility-1.0.xsd108
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/external/ws-addr.xsd137
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/external/ws-policy.xsd141
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/external/wsdli.xsd35
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/external/xml.xsd117
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/external/xmldsig-core-schema.xsd318
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-1.1-cd04.xsd39
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-binding-ejb-1.1-cd01.xsd34
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-binding-jca-1.1-cd04.xsd173
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-binding-jms-1.1-cd04.xsd183
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-binding-sca-1.1-cd04.xsd20
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-binding-ws-1.1-cd04.xsd35
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-binding-ws-callback-1.1-cd04.xsd18
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-contribution-1.1-cd04.xsd90
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-contribution-c-1.1-cd04.xsd35
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-contribution-cpp-1.1-cd04.xsd35
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-contribution-java-1.1-cd02.xsd33
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-core-1.1-cd04.xsd534
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-definitions-1.1-cd04.xsd31
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-implementation-bpel-1.1-cd03.xsd32
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-implementation-c-1.1-cd04.xsd57
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-implementation-composite-1.1-cd04.xsd26
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-implementation-cpp-1.1-cd04.xsd54
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-implementation-java-1.1-cd03.xsd27
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-implementation-spring-1.1-cd01.xsd21
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-interface-c-1.1-cd04.xsd43
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-interface-cpp-1.1-cd04.xsd44
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-interface-java-1.1-cd04.xsd29
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-interface-wsdl-1.1-cd04.xsd29
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-jee-1.1-wd03.xsd52
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/sca-policy-1.1-cd04.xsd104
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-dwr.xsd41
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-http.xsd41
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-jsonrpc.xsd41
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-rmi.xsd40
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-implementation-osgi.xsd53
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-implementation-widget.xsd42
-rw-r--r--sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1.xsd35
380 files changed, 39773 insertions, 0 deletions
diff --git a/sca-cpp/branches/gcc-4.4/AUTHORS b/sca-cpp/branches/gcc-4.4/AUTHORS
new file mode 100644
index 0000000000..b06da1bf3a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/AUTHORS
@@ -0,0 +1,5 @@
+Apache Tuscany SCA Runtime
+==========================
+
+The Apache Software Foundation (http://www.apache.org/)
+
diff --git a/sca-cpp/branches/gcc-4.4/COPYING b/sca-cpp/branches/gcc-4.4/COPYING
new file mode 100644
index 0000000000..6b0b1270ff
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/COPYING
@@ -0,0 +1,203 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
diff --git a/sca-cpp/branches/gcc-4.4/ChangeLog b/sca-cpp/branches/gcc-4.4/ChangeLog
new file mode 100644
index 0000000000..a4151dc22a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/ChangeLog
@@ -0,0 +1,12 @@
+Apache Tuscany SCA Runtime
+==========================
+
+For a log of all changes see the Tuscany commits mailing list:
+commits@tuscany.apache.org
+
+Archives:
+http://www.mail-archive.com/commits@tuscany.apache.org
+
+To subscribe send an email to:
+commits-subscribe@tuscany.apache.org
+
diff --git a/sca-cpp/branches/gcc-4.4/INSTALL b/sca-cpp/branches/gcc-4.4/INSTALL
new file mode 100644
index 0000000000..6eab022d76
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/INSTALL
@@ -0,0 +1,284 @@
+Apache Tuscany SCA Runtime
+==========================
+
+Automated installation from scratch on Ubuntu 9.10
+==================================================
+
+Tuscany provides an automated install script for Ubuntu 9.10. You can start
+with a fresh Ubuntu Server 9.10 system, the ubuntu-install script takes care
+of all the download, build and installation steps for you.
+
+The required system tools and libraries are downloaded and installed using
+apt-get. The Tuscany project and its dependencies (Apache HTTPD server, Apache
+Axis2/C etc) are downloaded, built and installed in the current directory.
+
+To run the automated installation:
+mkdir tuscany
+cd tuscany
+wget http://svn.apache.org/repos/asf/tuscany/sca-cpp/trunk/ubuntu/ubuntu-install
+chmod +x ./ubuntu-install
+./ubuntu-install
+
+The script will display each command as it's executed.
+
+That's all you need to do to build and install the Tuscany SCA runtime on
+Ubuntu 9.10.
+
+
+For manual build and install steps on other systems or if you need to customize
+your installation, read on...
+
+
+Building
+========
+
+The Tuscany SCA Linux build uses the GNU Autotools tool chain.
+
+First install the following development tools:
+autoconf-2.64
+automake-1.11
+g++-4.4.1
+libtool-2.2.6
+doxygen-1.6.1
+
+Install the following binaries:
+curl-7-19-5
+
+
+Then install the following development dependencies:
+
+Apache HTTP server and APR:
+httpd-2.2-15 (http://httpd.apache.org/)
+with included libapr and libaprutil
+built with OpenSSL libssl-0.9.8g
+
+Memcached:
+memcached-1.4.4 (http://memcached.org/)
+built with libevent-1.4.11
+
+XML:
+libxml2-2.7.7 (http://xmlsoft.org/)
+
+CURL:
+libcurl4-openssl-7.19.5
+
+JSON:
+Mozilla TraceMonkey libmozjs (https://wiki.mozilla.org/JavaScript:TraceMonkey)
+also included in xulrunner-1.9.1.8
+
+Key/value store:
+tinycdb-0.77 (http://www.corpit.ru/mjt/tinycdb.html)
+
+Optional dependencies:
+
+Web Services:
+Apache Axis2/C 1.6.0 (http://ws.apache.org/axis2/c/)
+
+Queueing:
+Apache Qpid/C++ 0.6 (http://qpid.apache.org/)
+built with libuuid-2.16, libboost-1.38.1, libboost-program-options-1.38.1 and
+libboost-filesystem-1.38.1
+
+Python:
+Python 2.6.4 (http://www.python.org/)
+Google AppEngine 1.3.2 (http://code.google.com/appengine/)
+
+Java:
+a Java 5+ JDK (http://openjdk.java.net/, http://harmony.apache.org/)
+
+XMPP Chat:
+Apache Vysper 0.5 (http://mina.apache.org/)
+
+Libstrophe (http://code.stanziq.com/cgit/strophe/libstrophe/)
+build it from source at git://code.stanziq.com//libstrophe
+requires libcheck-0.9.6
+
+SQL Database:
+postgresql-9.0 (http://www.postgresql.org/)
+
+
+To configure the Tuscany SCA build do this:
+./bootstrap
+./configure --prefix=<install dir>
+
+To enable debugging and strict warning compile options, add:
+--enable-maintainer-mode
+
+To enable gprof profiling, add:
+--enable-profiling
+
+To enable multi-threading (required by the Queue and Chat components and
+for running with the HTTPD worker or event multi-threaded MPMs):
+--enable-threads
+
+To enable support for Python component implementations:
+--enable-python
+
+To enable support for Java component implementations:
+--enable-java
+
+To build the Web service utility component (requires Apache Axis2/C):
+--enable-webservice
+
+To build the Queue utility component (requires Apache Qpid/C++):
+--enable-queue
+
+To build the Chat utility component (requires Libstrophe and optionally Apache
+Vysper if you want to run the tests with a local Vysper XMPP server):
+--enable-chat
+
+To build the SQL Database utility component (requires PostgreSQL):
+--enable-sqldb
+
+To generate doxygen documentation, add:
+--enable-doxygen
+
+To configure where to find dependencies, see the --with-* options described
+in the configure help:
+./configure --help
+
+
+Here's an example configuration, tested on Ubuntu 9.10, with the system
+dependencies installed in the standard system directories and some of the
+dependencies installed under $HOME:
+
+./configure --prefix=$HOME/tuscany-sca-cpp-bin \
+--with-apr=$HOME/httpd-2.2.13-bin --with-httpd=$HOME/httpd-2.2.13-bin \
+--with-memcached=$HOME/memcached-1.4.4-bin \
+--with-tinycdb=$HOME/tinycdb-0.77-bin \
+--with-curl=$HOME/curl-7.19.5-bin --with-libxml2=/usr \
+--with-js-include=/usr/include/xulrunner-1.9.1.8/unstable \
+--with-js-lib=/usr/lib/xulrunner-1.9.1.8 \
+--enable-threads \
+--enable-python --with-python=/usr \
+--enable-gae --with-gae=$HOME/google_appengine \
+--enable-java --with-java=/usr/lib/jvm/default-java \
+--enable-webservice --with-axis2c=$HOME/axis2c-1.6.0-bin \
+--with-libxml2=$HOME/libxml2-2.7.7-bin \
+--enable-queue --with-qpidc=$HOME/qpidc-0.6-bin \
+--enable-chat --with-libstrophe=$HOME/libstrophe-bin \
+--with-vysper=$HOME/vysper-0.5 \
+--enable-sqldb --with-pgsql=$HOME/postgresql-9.0-bin \
+--enable-maintainer-mode
+
+
+To build the Tuscany SCA runtime, do this:
+make
+
+To run the tests, do this:
+make check
+
+To build ctags for the source, do this:
+make ctags
+
+To build a source distribution, do this:
+make dist
+
+To build a binary distribution, do this:
+make bindist
+
+
+Installing
+==========
+
+To install the Tuscany SCA binaries, do this:
+make install
+
+
+Building dependencies from source
+=================================
+
+Here are example build and install steps for some of the dependencies.
+
+Apache HTTPD, including APR, using the HTTP prefork MPM (recommended):
+wget http://www.apache.org/dist/httpd/httpd-2.2.15.tar.gz
+tar xzf httpd-2.2.15.tar.gz
+cd httpd-2.2.15
+./configure --enable-ssl --enable-proxy --enable-rewrite --with-included-apr \
+--with-mpm=prefork --prefix=$HOME/httpd-2.2.15-bin
+make
+make install
+export PATH=$HOME/httpd-2-2.15-bin/bin:$PATH
+
+Memcached:
+wget http://memcached.googlecode.com/files/memcached-1.4.4.tar.gz
+tar xzf memcached-1.4.4.tar.gz
+cd memcached-1.4.4
+./configure --prefix=$HOME/memcached-1.4.4-bin
+make
+make install
+
+TinyCDB:
+wget http://www.corpit.ru/mjt/tinycdb/tinycdb_0.77.tar.gz
+tar xzf tinycdb_0.77.tar.gz
+cd tinycdb-0.77
+make
+make prefix=$HOME/tinycdb-0.77-bin install
+
+CURL:
+wget http://curl.haxx.se/download/curl-7.19.5.tar.gz
+tar xzf curl-7.19.5.tar.gz
+cd curl-7.19.5
+./configure --prefix=$HOME/curl-7.19.5-bin
+make
+make install
+
+Libxml2:
+wget ftp://xmlsoft.org/libxml2/libxml2-sources-2.7.7.tar.gz
+tar xzf libxml2-sources-2.7.7.tar.gz
+cd libxml2-2.7.7
+./configure --prefix=$HOME/libxml2-2.7.7-bin
+make
+make install
+
+TraceMonkey:
+wget http://hg.mozilla.org/tracemonkey/archive/e4364736e170.tar.gz
+tar xzf tracemonkey-e4364736e170.tar.gz
+cd tracemonkey-e4364736e170/js/src
+autoconf2.13
+./configure --prefix=$HOME/tracemonkey-bin
+make
+make install
+
+Apache Axis2/C:
+wget http://www.apache.org/dist/ws/axis2-c/1_6_0/axis2c-src-1.6.0.tar.gz
+tar xzf axis2c-src-1.6.0.tar.gz
+cd axis2c-src-1.6.0
+./configure --enable-libxml2 --enable-openssl \
+--with-apache2=$HOME/httpd-2.2.15-bin/include --prefix=$HOME/axis2c-1.6.0-bin
+make
+make install
+export AXIS2C_HOME=$HOME/axis2c-1.6.0-bin
+
+Apache Qpid/C++:
+wget http://www.apache.org/dist/qpid/0.6/qpid-cpp-0.6.tar.gz
+tar xzf qpid-cpp-0.6.tar.gz
+cd qpidc-0.6
+./configure --prefix=$HOME/qpidc-0.6-bin
+make
+make install
+
+Libstrophe:
+git clone git://code.stanziq.com/libstrophe
+cd libstrophe
+git submodule init
+git submodule update
+aclocal
+automake --add-missing --foreign --copy
+autoconf
+./configure --prefix=$HOME/libstrophe-bin
+make
+make install
+cd ..
+mkdir -p libstrophe-bin/include
+cp libstrophe/*.h libstrophe-bin/include
+cp libstrophe/src/*.h libstrophe-bin/include
+
+PostgreSQL:
+wget http://wwwmaster.postgresql.org/download/mirrors-ftp/source/9.0alpha5/postgresql-9.0alpha5.tar.gz
+tar xzf postgresql-9.0alpha5.tar.gz
+cd postgresql-9.0alpha5
+./configure --prefix=$HOME/postgresql-9.0-bin
+make
+make install
+
diff --git a/sca-cpp/branches/gcc-4.4/LICENSE b/sca-cpp/branches/gcc-4.4/LICENSE
new file mode 100644
index 0000000000..e0962b23e3
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/LICENSE
@@ -0,0 +1,323 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+================================================================================
+
+Apache Tuscany SCA C++ Subcomponents:
+
+The Tuscany SCA C++ release includes a number of subcomponents with separate
+copyright notices and license terms. Your use of the source code for these
+subcomponents is subject to the terms and conditions of the following licenses.
+
+================================================================================
+
+The xsd component includes XML files under the following license:
+
+Copyright OASIS 2005, 2009. All Rights Reserved.
+All capitalized terms in the following text have the meanings assigned to them in the OASIS Intellectual
+Property Rights Policy (the "OASIS IPR Policy"). The full Policy may be found at the OASIS website.
+This document and translations of it may be copied and furnished to others, and derivative works that
+comment on or otherwise explain it or assist in its implementation may be prepared, copied, published,
+and distributed, in whole or in part, without restriction of any kind, provided that the above copyright
+notice and this section are included on all such copies and derivative works. However, this document
+itself may not be modified in any way, including by removing the copyright notice or references to OASIS,
+except as needed for the purpose of developing any document or deliverable produced by an OASIS
+Technical Committee (in which case the rules applicable to copyrights, as set forth in the OASIS IPR
+Policy, must be followed) or as required to translate it into languages other than English.
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors
+or assigns.
+This document and the information contained herein is provided on an "AS IS" basis and OASIS
+DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY
+WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP
+RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+PURPOSE.
+OASIS requests that any OASIS Party or any other party that believes it has patent claims that would
+necessarily be infringed by implementations of this OASIS Committee Specification or OASIS Standard,
+to notify OASIS TC Administrator and provide an indication of its willingness to grant patent licenses to
+such patent claims in a manner consistent with the IPR Mode of the OASIS Technical Committee that
+produced this specification.
+OASIS invites any party to contact the OASIS TC Administrator if it is aware of a claim of ownership of
+any patent claims that would necessarily be infringed by implementations of this specification by a patent
+holder that is not willing to provide a license to such patent claims in a manner consistent with the IPR
+Mode of the OASIS Technical Committee that produced this specification. OASIS may include such
+claims on its website, but disclaims any obligation to do so.
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that
+might be claimed to pertain to the implementation or use of the technology described in this document or
+the extent to which any license under such rights might or might not be available; neither does it represent
+that it has made any effort to identify any such rights. Information on OASIS' procedures with respect to
+rights in any document or deliverable produced by an OASIS Technical Committee can be found on the
+OASIS website. Copies of claims of rights made available for publication and any assurances of licenses
+to be made available, or the result of an attempt made to obtain a general license or permission for the use
+of such proprietary rights by implementers or users of this OASIS Committee Specification or OASIS
+Standard, can be obtained from the OASIS TC Administrator. OASIS makes no representation that any
+information or list of intellectual property rights will at any time be complete, or that any claims in such list
+are, in fact, Essential Claims.
+The names "OASIS", are trademarks of OASIS, the owner and developer of this specification, and should
+be used only to refer to the organization and its official outputs. OASIS welcomes reference to, and
+implementation and use of, specifications, while reserving the right to enforce its marks against misleading
+uses. Please see http://www.oasis-open.org/who/trademark.php for above guidance.
+
+================================================================================
+
+The xsd component includes XML files under the following license:
+
+http://www.w3.org/Consortium/Legal/copyright-software-19980720
+
+W3C® SOFTWARE NOTICE AND LICENSE
+Copyright (c) 1994-2002 World Wide Web Consortium, (Massachusetts Institute of Technology, Institut National de Recherche
+en Informatique et en Automatique, Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/
+
+This W3C work (including software, documents, or other related items) is being provided by the copyright holders under
+the following license. By obtaining, using and/or copying this work, you (the licensee) agree that you have read, understood,
+and will comply with the following terms and conditions:
+
+Permission to use, copy, modify, and distribute this software and its documentation, with or without modification,
+for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies
+of the software and documentation or portions thereof, including modifications, that you make:
+
+ 1. The full text of this NOTICE in a location viewable to users of the redistributed or derivative work.
+ 2. Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, a short
+notice of the following form (hypertext is preferred, text is permitted) should be used within the body of any redistributed
+or derivative code: "Copyright (c) [$date-of-software] World Wide Web Consortium, (Massachusetts Institute of Technology,
+Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/"
+ 3. Notice of any changes or modifications to the W3C files, including the date changes were made. (We recommend you provide URIs
+to the location from which the code is derived.)
+
+THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE
+OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE
+OF THE SOFTWARE OR DOCUMENTATION.
+
+The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software
+without specific, written prior permission. Title to copyright in this software and any associated documentation will
+at all times remain with copyright holders.
+
+================================================================================
+
+The components/chat component includes the Libstrophe library under the
+following MIT license:
+
+Copyright (c) 2005-2009 Collecta, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+================================================================================
+
diff --git a/sca-cpp/branches/gcc-4.4/Makefile.am b/sca-cpp/branches/gcc-4.4/Makefile.am
new file mode 100644
index 0000000000..3ca481b75c
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/Makefile.am
@@ -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.
+
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = kernel modules components test doc samples
+
+datadir=$(prefix)
+data_DATA = INSTALL README LICENSE COPYING NOTICE
+nobase_data_DATA = xsd/*.xsd xsd/external/*.xsd xsd/external/*.dtd
+
+install-data-hook:
+ rm -rf $(prefix)/doc
+ cp -r doc $(prefix)
+ rm -f $(prefix)/doc/Makefile* $(prefix)/doc/Doxyfile*
+ rm -rf `find $(prefix)/doc -type d -name .svn`
+ rm -rf `find $(prefix)/doc -type d -name .deps`
+ rm -rf $(prefix)/test
+
+dist-hook:
+ rm -rf `find $(distdir)/ -type d -name .svn`
+ rm -rf `find $(distdir)/ -type d -name .deps`
+
+bindist: install
+ rm -rf ${PACKAGE}-${PACKAGE_VERSION}-bin
+ mkdir ${PACKAGE}-${PACKAGE_VERSION}-bin
+ cp -r $(prefix)/* ${PACKAGE}-${PACKAGE_VERSION}-bin
+ rm -rf ${PACKAGE}-${PACKAGE_VERSION}-bin/test
+ tar -cf - ${PACKAGE}-${PACKAGE_VERSION}-bin | gzip -c > ${PACKAGE}-${PACKAGE_VERSION}-bin.tar.gz
+ rm -rf ${PACKAGE}-${PACKAGE_VERSION}-bin
+
diff --git a/sca-cpp/branches/gcc-4.4/NEWS b/sca-cpp/branches/gcc-4.4/NEWS
new file mode 100644
index 0000000000..dea502fcae
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/NEWS
@@ -0,0 +1,13 @@
+Apache Tuscany SCA Runtime
+==========================
+
+For any news see the Tuscany development mailing list:
+dev@tuscany.apache.org
+
+Archives:
+http://www.mail-archive.com/dev@tuscany.apache.org
+http://marc.info/?l=tuscany-dev
+
+To subscribe send an email to:
+dev-subscribe@tuscany.apache.org
+
diff --git a/sca-cpp/branches/gcc-4.4/NOTICE b/sca-cpp/branches/gcc-4.4/NOTICE
new file mode 100644
index 0000000000..d91c24207e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/NOTICE
@@ -0,0 +1,42 @@
+Apache Tuscany SCA C++
+Copyright 2005, 2010 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/)
+
+This product includes software under the OASIS Specification License
+with the following copyright:
+
+Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+OASIS trademark, IPR and other policies apply.
+
+This product includes software under the W3C(c) Software License
+with the following copyright:
+
+Copyright (c) 2008 World Wide Web Consortium, (Massachusetts Institute of Technology,
+European Research Consortium for Informatics and Mathematics, Keio University).
+All Rights Reserved. This work is distributed under the W3C(c) Software License [1] in
+the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+[1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+
+This product includes software under the W3C(c) Software License
+with the following copyright:
+
+Copyright 2001 The Internet Society and W3C (Massachusetts Institute
+of Technology, Institut National de Recherche en Informatique et en
+Automatique, Keio University). All Rights Reserved.
+http://www.w3.org/Consortium/Legal/
+
+This document is governed by the W3C Software License [1] as described
+in the FAQ [2].
+
+[1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
+[2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
+
+This product includes software under the MIT license
+with the following copyright:
+
+Copyright (c) 2005-2009 Collecta, Inc.
+
diff --git a/sca-cpp/branches/gcc-4.4/README b/sca-cpp/branches/gcc-4.4/README
new file mode 100644
index 0000000000..720b785e47
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/README
@@ -0,0 +1,81 @@
+Apache Tuscany SCA Runtime
+==========================
+
+Getting the source code
+=======================
+
+To checkout the source code with commit access, do this:
+git svn init -s https://svn.apache.org/repos/asf/tuscany/sca-cpp tuscany-sca-cpp
+cd tuscany-sca-cpp
+wget -P .git http://git.apache.org/authors.txt
+git config svn.authorsfile .git/authors.txt
+git config user.email <you>@apache.org
+git config svn.rmdir true
+git svn fetch --log-window-size 10000
+
+To checkout the source without commit access, do this:
+git clone git://git.apache.org/tuscany-sca-cpp
+or
+svn checkout http://svn.apache.org/repos/asf/tuscany/sca-cpp tuscany-sca-cpp
+
+
+Layout
+======
+
+Here's a rough guide to the Tuscany SCA source tree:
+
+ /
+ |-- trunk Master development branch
+ | |
+ | |-- kernel SCA runtime kernel
+ | |
+ | |-- modules Modules that plug into the runtime
+ | | |-- atom AtomPub encoding
+ | | |-- json JSON-RPC encoding
+ | | |-- http HTTP protocol
+ | | |-- java Support for Java components
+ | | |-- python Support for Python components
+ | | |-- scheme Support for Scheme components
+ | | |-- server Apache HTTPD server integration
+ | | |-- wsgi Python WSGI server integration
+ | |
+ | |-- components Useful SCA components
+ | | |-- cache Key/value memory cache
+ | | |-- chat XMPP chat
+ | | |-- log Logger
+ | | |-- queue AMQP message queue
+ | | |-- sqldb SQL database
+ | | |-- store Key/value persistent store
+ | | |-- webservice Web service gateway
+ | |
+ | |-- test Integration tests
+ | |
+ | |-- samples Sample Applications
+ | |
+ | |-- ubuntu Automated install on Ubuntu 9.10
+ |
+ |-- branches Topic and release branches
+ |
+ |-- tags Release tags
+
+
+Building
+========
+
+See the INSTALL file.
+
+
+Contributing to the project
+===========================
+
+To contribute to the project or report issues see the Tuscany development
+mailing list:
+dev@tuscany.apache.org
+
+Archives:
+http://www.mail-archive.com/dev@tuscany.apache.org
+http://marc.info/?l=tuscany-dev
+
+To subscribe send an email to:
+dev-subscribe@tuscany.apache.org
+
diff --git a/sca-cpp/branches/gcc-4.4/bootstrap b/sca-cpp/branches/gcc-4.4/bootstrap
new file mode 100755
index 0000000000..af38864985
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/bootstrap
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+# 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 i in "libtoolize --force" aclocal autoconf autoheader
+do
+ echo -n "Running $i..."
+ $i || exit 1
+ echo 'done.'
+done
+
+echo -n 'Running automake...'
+automake --add-missing
+echo 'done.'
+exit 0
+
diff --git a/sca-cpp/branches/gcc-4.4/components/Makefile.am b/sca-cpp/branches/gcc-4.4/components/Makefile.am
new file mode 100644
index 0000000000..c07ebb1468
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/Makefile.am
@@ -0,0 +1,22 @@
+# 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.
+
+SUBDIRS = cache chat log queue sqldb store webservice
+
+includedir = $(prefix)/include/components
+nobase_include_HEADERS = */*.hpp
+
diff --git a/sca-cpp/branches/gcc-4.4/components/cache/Makefile.am b/sca-cpp/branches/gcc-4.4/components/cache/Makefile.am
new file mode 100644
index 0000000000..0a41f56dbe
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/cache/Makefile.am
@@ -0,0 +1,35 @@
+# 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.
+
+comp_SCRIPTS = memcached-start memcached-stop
+compdir=$(prefix)/components/cache
+
+comp_DATA = memcached.prefix
+memcached.prefix: $(top_builddir)/config.status
+ echo ${MEMCACHED_PREFIX} >memcached.prefix
+
+comp_LTLIBRARIES = libmemcache.la
+libmemcache_la_SOURCES = memcache.cpp
+
+memcache_test_SOURCES = memcache-test.cpp
+memcache_test_LDFLAGS = -lxml2
+
+client_test_SOURCES = client-test.cpp
+client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+
+noinst_PROGRAMS = memcache-test client-test
+TESTS = memcached-test server-test
diff --git a/sca-cpp/branches/gcc-4.4/components/cache/client-test.cpp b/sca-cpp/branches/gcc-4.4/components/cache/client-test.cpp
new file mode 100644
index 0000000000..e3ec449e69
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/cache/client-test.cpp
@@ -0,0 +1,130 @@
+/*
+ * 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 cache component.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "perf.hpp"
+#include "../../modules/http/curl.hpp"
+
+namespace tuscany {
+namespace cache {
+
+const string uri("http://localhost:8090/memcache");
+
+bool testCache() {
+ http::CURLSession cs;
+
+ const list<value> i = list<value>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99"));
+ const list<value> a = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
+
+ const failable<value> id = http::post(a, uri, cs);
+ assert(hasContent(id));
+
+ const string p = path(content(id));
+ {
+ const failable<value> val = http::get(uri + p, cs);
+ assert(hasContent(val));
+ assert(content(val) == a);
+ }
+
+ const list<value> j = list<value>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$3.55"));
+ const list<value> b = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), j);
+
+ {
+ const failable<value> r = http::put(b, uri + p, cs);
+ assert(hasContent(r));
+ assert(content(r) == value(true));
+ }
+ {
+ const failable<value> val = http::get(uri + p, cs);
+ assert(hasContent(val));
+ assert(content(val) == b);
+ }
+ {
+ const failable<value> r = http::del(uri + p, cs);
+ assert(hasContent(r));
+ assert(content(r) == value(true));
+ }
+ {
+ const failable<value> val = http::get(uri + p, cs);
+ assert(!hasContent(val));
+ }
+
+ return true;
+}
+
+struct getLoop {
+ const string path;
+ const value entry;
+ http::CURLSession cs;
+ getLoop(const string& path, const value& entry, http::CURLSession cs) : path(path), entry(entry), cs(cs) {
+ }
+ const bool operator()() const {
+ const failable<value> val = http::get(uri + path, cs);
+ assert(hasContent(val));
+ assert(content(val) == entry);
+ return true;
+ }
+};
+
+bool testGetPerf() {
+ const list<value> i = list<value>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$4.55"));
+ const value a = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
+
+ http::CURLSession cs;
+ const failable<value> id = http::post(a, uri, cs);
+ assert(hasContent(id));
+ const string p = path(content(id));
+
+ const lambda<bool()> gl = getLoop(p, a, cs);
+ cout << "Cache get test " << time(gl, 5, 200) << " ms" << endl;
+
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::cache::testCache();
+ tuscany::cache::testGetPerf();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/cache/memcache-test.cpp b/sca-cpp/branches/gcc-4.4/components/cache/memcache-test.cpp
new file mode 100644
index 0000000000..ea9e9883dc
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/cache/memcache-test.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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 Memcached access functions.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "perf.hpp"
+#include "memcache.hpp"
+
+namespace tuscany {
+namespace memcache {
+
+bool testMemCached() {
+ MemCached ch("127.0.0.1", 11211);
+ const value k = mklist<value>("a");
+
+ assert(hasContent(post(k, string("AAA"), ch)));
+ assert((get(k, ch)) == value(string("AAA")));
+ assert(hasContent(put(k, string("aaa"), ch)));
+ assert((get(k, ch)) == value(string("aaa")));
+ assert(hasContent(del(k, ch)));
+ assert(!hasContent(get(k, ch)));
+
+ return true;
+}
+
+struct getLoop {
+ const value k;
+ MemCached& ch;
+ getLoop(const value& k, MemCached& ch) : k(k), ch(ch) {
+ }
+ const bool operator()() const {
+ assert((get(k, ch)) == value(string("CCC")));
+ return true;
+ }
+};
+
+bool testGetPerf() {
+ const value k = mklist<value>("c");
+ MemCached ch("127.0.0.1", 11211);
+ assert(hasContent(post(k, string("CCC"), ch)));
+
+ const lambda<bool()> gl = getLoop(k, ch);
+ cout << "Memcached get test " << time(gl, 5, 200) << " ms" << endl;
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::memcache::testMemCached();
+ tuscany::memcache::testGetPerf();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/cache/memcache.composite b/sca-cpp/branches/gcc-4.4/components/cache/memcache.composite
new file mode 100644
index 0000000000..c9a147960e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/cache/memcache.composite
@@ -0,0 +1,32 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/components"
+ name="memcache">
+
+ <component name="memcache">
+ <implementation.cpp path=".libs" library="libmemcache"/>
+ <service name="memcache">
+ <t:binding.http uri="memcache"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/components/cache/memcache.cpp b/sca-cpp/branches/gcc-4.4/components/cache/memcache.cpp
new file mode 100644
index 0000000000..247e38d517
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/cache/memcache.cpp
@@ -0,0 +1,133 @@
+/*
+ * 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$ */
+
+/**
+ * Memcached-based cache component implementation.
+ */
+
+#include <apr_uuid.h>
+
+#include "string.hpp"
+
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "memcache.hpp"
+
+namespace tuscany {
+namespace cache {
+
+/**
+ * Get an item from the cache.
+ */
+const failable<value> get(const list<value>& params, memcache::MemCached& ch) {
+ return memcache::get(car(params), ch);
+}
+
+/**
+ * Post an item to the cache.
+ */
+const value uuidValue() {
+ apr_uuid_t uuid;
+ apr_uuid_get(&uuid);
+ char buf[APR_UUID_FORMATTED_LENGTH];
+ apr_uuid_format(buf, &uuid);
+ return value(string(buf, APR_UUID_FORMATTED_LENGTH));
+}
+
+const failable<value> post(const list<value>& params, memcache::MemCached& ch) {
+ const value id = append<value>(car(params), mklist(uuidValue()));
+ const failable<bool> val = memcache::post(id, cadr(params), ch);
+ if (!hasContent(val))
+ return mkfailure<value>(reason(val));
+ return id;
+}
+
+/**
+ * Put an item into the cache.
+ */
+const failable<value> put(const list<value>& params, memcache::MemCached& ch) {
+ const failable<bool> val = memcache::put(car(params), cadr(params), ch);
+ if (!hasContent(val))
+ return mkfailure<value>(reason(val));
+ return value(content(val));
+}
+
+/**
+ * Delete an item from the cache.
+ */
+const failable<value> del(const list<value>& params, memcache::MemCached& ch) {
+ const failable<bool> val = memcache::del(car(params), ch);
+ if (!hasContent(val))
+ return mkfailure<value>(reason(val));
+ return value(content(val));
+}
+
+/**
+ * Component implementation lambda function.
+ */
+class applyCache {
+public:
+ applyCache(memcache::MemCached& ch) : ch(ch) {
+ }
+
+ const value operator()(const list<value>& params) const {
+ const value func(car(params));
+ if (func == "get")
+ return get(cdr(params), ch);
+ if (func == "post")
+ return post(cdr(params), ch);
+ if (func == "put")
+ return put(cdr(params), ch);
+ if (func == "delete")
+ return del(cdr(params), ch);
+ return tuscany::mkfailure<tuscany::value>();
+ }
+
+private:
+ memcache::MemCached& ch;
+};
+
+/**
+ * Start the component.
+ */
+const failable<value> start(unused const list<value>& params) {
+ // Connect to memcached
+ memcache::MemCached& ch = *(new (gc_new<memcache::MemCached>()) memcache::MemCached("127.0.0.1", 11211));
+
+ // Return the component implementation lambda function
+ return value(lambda<value(const list<value>&)>(applyCache(ch)));
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+ const tuscany::value func(car(params));
+ if (func == "start")
+ return tuscany::cache::start(cdr(params));
+ return tuscany::mkfailure<tuscany::value>();
+}
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/cache/memcache.hpp b/sca-cpp/branches/gcc-4.4/components/cache/memcache.hpp
new file mode 100644
index 0000000000..d410b90767
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/cache/memcache.hpp
@@ -0,0 +1,175 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_memcache_hpp
+#define tuscany_memcache_hpp
+
+/**
+ * Memcached access functions.
+ */
+
+#include "apr.h"
+#include "apu.h"
+#include "apr_general.h"
+#include "apr_strings.h"
+#include "apr_hash.h"
+#include "apr_memcache.h"
+#include "apr_network_io.h"
+
+#include "string.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "../../modules/scheme/eval.hpp"
+
+namespace tuscany {
+namespace memcache {
+
+/**
+ * Represents a memcached context.
+ */
+class MemCached {
+public:
+ MemCached() : owner(false) {
+ }
+
+ MemCached(const string host, const int port) : owner(true) {
+ apr_pool_create(&pool, NULL);
+ apr_memcache_create(pool, 1, 0, &mc);
+ init(host, port);
+ }
+
+ MemCached(const MemCached& c) : owner(false) {
+ pool = c.pool;
+ mc = c.mc;
+ }
+
+ ~MemCached() {
+ if (!owner)
+ return;
+ apr_pool_destroy(pool);
+ }
+
+private:
+ bool owner;
+ apr_pool_t* pool;
+ apr_memcache_t* mc;
+
+ friend const failable<bool> post(const value& key, const value& val, const MemCached& cache);
+ friend const failable<bool> put(const value& key, const value& val, const MemCached& cache);
+ friend const failable<value> get(const value& key, const MemCached& cache);
+ friend const failable<bool> del(const value& key, const MemCached& cache);
+
+ /**
+ * Initialize the memcached context.
+ */
+ const failable<bool> init(const string& host, const int port) {
+ apr_memcache_server_t *server;
+ const apr_status_t sc = apr_memcache_server_create(pool, c_str(host), (apr_port_t)port, 0, 1, 1, 60, &server);
+ if (sc != APR_SUCCESS)
+ return mkfailure<bool>("Could not create server");
+ const apr_status_t as = apr_memcache_add_server(mc, server);
+ if (as != APR_SUCCESS)
+ return mkfailure<bool>("Could not add server");
+ return true;
+ }
+};
+
+/**
+ * Post a new item to the cache.
+ */
+const failable<bool> post(const value& key, const value& val, const MemCached& cache) {
+ debug(key, "memcache::post::key");
+ debug(val, "memcache::post::value");
+
+ const string ks(scheme::writeValue(key));
+ const string vs(scheme::writeValue(val));
+ const apr_status_t rc = apr_memcache_add(cache.mc, c_str(ks), const_cast<char*>(c_str(vs)), length(vs), 0, 27);
+ if (rc != APR_SUCCESS)
+ return mkfailure<bool>("Could not add entry");
+
+ debug(true, "memcache::post::result");
+ return true;
+}
+
+/**
+ * Update an item in the cache. If the item doesn't exist it is added.
+ */
+const failable<bool> put(const value& key, const value& val, const MemCached& cache) {
+ debug(key, "memcache::put::key");
+ debug(val, "memcache::put::value");
+
+ const string ks(scheme::writeValue(key));
+ const string vs(scheme::writeValue(val));
+ const apr_status_t rc = apr_memcache_set(cache.mc, c_str(ks), const_cast<char*>(c_str(vs)), length(vs), 0, 27);
+ if (rc != APR_SUCCESS)
+ return mkfailure<bool>("Could not set entry");
+
+ debug(true, "memcache::put::result");
+ return true;
+}
+
+/**
+ * Get an item from the cache.
+ */
+const failable<value> get(const value& key, const MemCached& cache) {
+ debug(key, "memcache::get::key");
+
+ const string ks(scheme::writeValue(key));
+ apr_pool_t* vpool;
+ const apr_status_t pc = apr_pool_create(&vpool, cache.pool);
+ if (pc != APR_SUCCESS)
+ return mkfailure<value>("Could not allocate memory");
+
+ char *data;
+ apr_size_t size;
+ const apr_status_t rc = apr_memcache_getp(cache.mc, cache.pool, c_str(ks), &data, &size, NULL);
+ if (rc != APR_SUCCESS) {
+ apr_pool_destroy(vpool);
+ return mkfailure<value>("Could not get entry");
+ }
+
+ const value val(scheme::readValue(string(data, size)));
+ apr_pool_destroy(vpool);
+
+ debug(val, "memcache::get::result");
+ return val;
+}
+
+/**
+ * Delete an item from the cache
+ */
+const failable<bool> del(const value& key, const MemCached& cache) {
+ debug(key, "memcache::delete::key");
+
+ const string ks(scheme::writeValue(key));
+ const apr_status_t rc = apr_memcache_delete(cache.mc, c_str(ks), 0);
+ if (rc != APR_SUCCESS)
+ return mkfailure<bool>("Could not delete entry");
+
+ debug(true, "memcache::delete::result");
+ return true;
+}
+
+}
+}
+
+#endif /* tuscany_memcache_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/components/cache/memcached-start b/sca-cpp/branches/gcc-4.4/components/cache/memcached-start
new file mode 100755
index 0000000000..b10d7f3fe8
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/cache/memcached-start
@@ -0,0 +1,25 @@
+#!/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.
+
+# Start memcached
+here=`readlink -f $0`; here=`dirname $here`
+
+memcached_prefix=`cat $here/memcached.prefix`
+$memcached_prefix/bin/memcached -d -l 127.0.0.1 -m 4 -p 11211
+
diff --git a/sca-cpp/branches/gcc-4.4/components/cache/memcached-stop b/sca-cpp/branches/gcc-4.4/components/cache/memcached-stop
new file mode 100755
index 0000000000..80801cdfbf
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/cache/memcached-stop
@@ -0,0 +1,26 @@
+#!/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.
+
+# Stop memcached
+here=`readlink -f $0`; here=`dirname $here`
+
+memcached_prefix=`cat $here/memcached.prefix`
+mc="$memcached_prefix/bin/memcached -d -l 127.0.0.1 -m 4 -p 11211"
+
+kill `ps -ef | grep -v grep | grep "${mc}" | awk '{ print $2 }'`
diff --git a/sca-cpp/branches/gcc-4.4/components/cache/memcached-test b/sca-cpp/branches/gcc-4.4/components/cache/memcached-test
new file mode 100755
index 0000000000..842e8d2030
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/cache/memcached-test
@@ -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.
+
+# Setup
+./memcached-start
+sleep 1
+
+# Test
+./memcache-test 2>/dev/null
+rc=$?
+
+# Cleanup
+./memcached-stop
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/components/cache/server-test b/sca-cpp/branches/gcc-4.4/components/cache/server-test
new file mode 100755
index 0000000000..5c86b75ebc
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/cache/server-test
@@ -0,0 +1,41 @@
+#!/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
+../../modules/http/httpd-conf tmp localhost 8090 ../../modules/http/htdocs
+../../modules/server/server-conf tmp
+../../modules/server/scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+SCAContribution `pwd`/
+SCAComposite memcache.composite
+EOF
+
+./memcached-start
+../../modules/http/httpd-start tmp
+sleep 2
+
+# Test
+./client-test 2>/dev/null
+rc=$?
+
+# Cleanup
+../../modules/http/httpd-stop tmp
+./memcached-stop
+sleep 2
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/components/chat/Makefile.am b/sca-cpp/branches/gcc-4.4/components/chat/Makefile.am
new file mode 100644
index 0000000000..804238a5d7
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/chat/Makefile.am
@@ -0,0 +1,54 @@
+# 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.
+
+JAVAROOT = $(top_builddir)/components/chat
+
+if WANT_CHAT
+
+INCLUDES = -I${LIBSTROPHE_INCLUDE}
+
+comp_SCRIPTS = vysper-start vysper-stop vysper-classpath
+compdir=$(prefix)/components/chat
+
+comp_DATA = vysper.prefix
+vysper.prefix: $(top_builddir)/config.status
+ echo ${VYSPER_PREFIX} >vysper.prefix
+
+comp_LTLIBRARIES = libchatter.la
+libchatter_la_SOURCES = chatter.cpp
+libchatter_la_LDFLAGS = -L${LIBSTROPHE_LIB} -R${LIBSTROPHE_LIB} -lstrophe -lexpat -lssl -lresolv
+
+xmpp_test_SOURCES = xmpp-test.cpp
+xmpp_test_LDFLAGS = -L${LIBSTROPHE_LIB} -R${LIBSTROPHE_LIB} -lstrophe -lexpat -lssl -lresolv
+
+client_test_SOURCES = client-test.cpp
+client_test_LDFLAGS = -lxml2 -lcurl -lmozjs -L${LIBSTROPHE_LIB} -R${LIBSTROPHE_LIB} -lstrophe -lexpat -lssl -lresolv
+
+noinst_PROGRAMS = xmpp-test client-test
+
+if WANT_VYSPER
+
+AM_JAVACFLAGS = -cp `${top_builddir}/components/chat/vysper-classpath ${VYSPER_PREFIX}`${JAVAROOT}
+
+noinst_JAVA = test/*.java
+
+CLEANFILES = test/*.class
+
+TESTS = echo-test
+endif
+
+endif
diff --git a/sca-cpp/branches/gcc-4.4/components/chat/chat.composite b/sca-cpp/branches/gcc-4.4/components/chat/chat.composite
new file mode 100644
index 0000000000..569dbfc4b2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/chat/chat.composite
@@ -0,0 +1,52 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/components"
+ name="chat">
+
+ <component name="print-sender">
+ <implementation.cpp path=".libs" library="libchatter"/>
+ <property name="jid">sca1@localhost</property>
+ <property name="password">sca1</property>
+ <service name="print-sender">
+ <t:binding.http uri="print-sender"/>
+ </service>
+ </component>
+
+ <component name="print-chatter">
+ <implementation.cpp path=".libs" library="libchatter"/>
+ <property name="jid">sca2@localhost</property>
+ <property name="password">sca2</property>
+ <service name="print-chatter">
+ <t:binding.http uri="print-chatter"/>
+ </service>
+ <reference name="relay" target="print"/>
+ </component>
+
+ <component name="print">
+ <t:implementation.scheme script="server-test.scm"/>
+ <service name="print">
+ <t:binding.http uri="print"/>
+ </service>
+ <reference name="report" target="print-chatter"/>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/components/chat/chatter.cpp b/sca-cpp/branches/gcc-4.4/components/chat/chatter.cpp
new file mode 100644
index 0000000000..95f2d40077
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/chat/chatter.cpp
@@ -0,0 +1,162 @@
+/*
+ * 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$ */
+
+/**
+ * XMPP chatter component implementation.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "parallel.hpp"
+#include "xmpp.hpp"
+
+namespace tuscany {
+namespace chat {
+
+/**
+ * Post an item to an XMPP JID.
+ */
+const failable<value> post(const list<value>& params, XMPPClient& xc) {
+ const value to = car<value>(car(params));
+ const value val = cadr(params);
+ debug(to, "chat::post::jid");
+ debug(val, "chat::post::value");
+ const failable<bool> r = post(to, val, xc);
+ if (!hasContent(r))
+ return mkfailure<value>(reason(r));
+ return value(mklist<value>(to));
+}
+
+/**
+ * A relay function that posts the XMPP messages it receives to a relay component reference.
+ */
+class relay {
+public:
+ relay(const lambda<value(const list<value>&)>& rel) : rel(rel) {
+ }
+
+ const failable<bool> operator()(const value& jid, const value& val, unused XMPPClient& xc) const {
+ if (isNil(rel))
+ return true;
+ debug(jid, "chat::relay::jid");
+ debug(val, "chat::relay::value");
+ const value res = rel(mklist<value>("post", mklist<value>(jid), val));
+ return true;
+ }
+
+private:
+ const lambda<value(const list<value>&)> rel;
+};
+
+/**
+ * Subscribe and listen to an XMPP session.
+ */
+class subscribe {
+public:
+ subscribe(const lambda<failable<bool>(const value&, const value&, XMPPClient&)>& l, XMPPClient& xc) : l(l), xc(xc) {
+ }
+
+ const failable<bool> operator()() const {
+ gc_pool pool;
+ debug("chat::subscribe::listen");
+ const failable<bool> r = listen(l, const_cast<XMPPClient&>(xc));
+ debug("chat::subscribe::stopped");
+ return r;
+ }
+
+private:
+ const lambda<failable<bool>(const value&, const value&, XMPPClient&)> l;
+ XMPPClient xc;
+};
+
+/**
+ * Chatter component lambda function
+ */
+class chatter {
+public:
+ chatter(XMPPClient& xc, worker& w) : xc(xc), w(w) {
+ }
+
+ const value operator()(const list<value>& params) const {
+ const tuscany::value func(car(params));
+ if (func == "post")
+ return post(cdr(params), const_cast<XMPPClient&>(xc));
+
+ // Stop the chatter component
+ if (func != "stop")
+ return tuscany::mkfailure<tuscany::value>();
+ debug("chat::chatter::stop");
+
+ // Disconnect and shutdown the worker thread
+ disconnect(const_cast<XMPPClient&>(xc));
+ cancel(const_cast<worker&>(w));
+ debug("chat::chatter::stopped");
+
+ return failable<value>(value(lambda<value(const list<value>&)>()));
+ }
+
+private:
+ const XMPPClient xc;
+ worker w;
+};
+
+/**
+ * Start the component.
+ */
+const failable<value> start(const list<value>& params) {
+ // Extract the relay reference and the XMPP JID and password
+ const bool hasRelay = !isNil(cddr(params));
+ const value rel = hasRelay? car(params) : value(lambda<value(const list<value>&)>());
+ const list<value> props = hasRelay? cdr(params) : params;
+ const value jid = ((lambda<value(list<value>)>)car(props))(list<value>());
+ const value pass = ((lambda<value(list<value>)>)cadr(props))(list<value>());
+
+ // Create an XMPP client session
+ XMPPClient xc(jid, pass, false);
+ const failable<bool> r = connect(xc);
+ if (!hasContent(r))
+ return mkfailure<value>(reason(r));
+
+ // Listen and relay messages in a worker thread
+ worker w(3);
+ const lambda<failable<bool>(const value&, const value&, XMPPClient&)> rl = relay(rel);
+ submit<failable<bool> >(w, lambda<failable<bool>()>(subscribe(rl, xc)));
+
+ // Return the chatter component lambda function
+ return value(lambda<value(const list<value>&)>(chatter(xc, w)));
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+ const tuscany::value func(car(params));
+ if (func == "start")
+ return tuscany::chat::start(cdr(params));
+ return tuscany::mkfailure<tuscany::value>();
+}
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/chat/client-test.cpp b/sca-cpp/branches/gcc-4.4/components/chat/client-test.cpp
new file mode 100644
index 0000000000..f9ca2cabd6
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/chat/client-test.cpp
@@ -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.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Test chat component.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "list.hpp"
+#include "element.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "perf.hpp"
+#include "parallel.hpp"
+#include "../../modules/http/curl.hpp"
+#include "xmpp.hpp"
+
+namespace tuscany {
+namespace chat {
+
+const value jid1("sca1@localhost");
+const value pass1("sca1");
+const value jid2("sca2@localhost");
+const value pass2("sca2");
+const value jid3("sca3@localhost");
+const value pass3("sca3");
+
+const list<value> item = list<value>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99"));
+const list<value> entry = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), item);
+
+worker w(2);
+bool received;
+
+const failable<bool> listener(const value& from, const value& val, unused XMPPClient& xc) {
+ assert(contains(from, "sca2@localhost"));
+ assert(val == entry);
+ received = true;
+ return false;
+}
+
+struct subscribe {
+ XMPPClient& xc;
+ subscribe(XMPPClient& xc) : xc(xc) {
+ }
+ const failable<bool> operator()() const {
+ const lambda<failable<bool>(const value&, const value&, XMPPClient&)> l(listener);
+ listen(l, xc);
+ return true;
+ }
+};
+
+bool testListen() {
+ received = false;
+ XMPPClient& xc = *(new (gc_new<XMPPClient>()) XMPPClient(jid3, pass3));
+ const failable<bool> c = connect(xc);
+ assert(hasContent(c));
+ const lambda<failable<bool>()> subs = subscribe(xc);
+ submit(w, subs);
+ return true;
+}
+
+bool testPost() {
+ gc_scoped_pool pool;
+ http::CURLSession ch;
+ const failable<value> id = http::post(entry, "http://localhost:8090/print-sender/sca2@localhost", ch);
+ assert(hasContent(id));
+ return true;
+}
+
+bool testReceived() {
+ shutdown(w);
+ assert(received == true);
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::chat::testListen();
+ tuscany::chat::testPost();
+ tuscany::chat::testReceived();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/chat/echo-test b/sca-cpp/branches/gcc-4.4/components/chat/echo-test
new file mode 100755
index 0000000000..271d40d122
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/chat/echo-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
+./vysper-start
+sleep 3
+
+# Test
+./xmpp-test 2>/dev/null
+rc=$?
+
+# Cleanup
+./vysper-stop
+sleep 1
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/components/chat/server-test b/sca-cpp/branches/gcc-4.4/components/chat/server-test
new file mode 100755
index 0000000000..dd1dc6faa7
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/chat/server-test
@@ -0,0 +1,39 @@
+#!/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
+../../modules/http/httpd-conf tmp localhost 8090 ../../modules/http/htdocs
+../../modules/server/server-conf tmp
+../../modules/server/scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+SCAContribution `pwd`/
+SCAComposite chat.composite
+EOF
+
+../../modules/http/httpd-start tmp
+sleep 2
+
+# Test
+./client-test 2>/dev/null
+rc=$?
+
+# Cleanup
+../../modules/http/httpd-stop tmp
+sleep 1
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/components/chat/server-test.scm b/sca-cpp/branches/gcc-4.4/components/chat/server-test.scm
new file mode 100644
index 0000000000..a6023708e1
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/chat/server-test.scm
@@ -0,0 +1,20 @@
+; 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.
+
+; Chat test case
+
+(define (post key val report) (report "post" '("sca3@localhost") val))
diff --git a/sca-cpp/branches/gcc-4.4/components/chat/test/TestVysperServer.java b/sca-cpp/branches/gcc-4.4/components/chat/test/TestVysperServer.java
new file mode 100644
index 0000000000..3d2b7d7c3e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/chat/test/TestVysperServer.java
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+package test;
+
+/**
+ * A test XMPP server, using Apache Vysper.
+ */
+import static java.lang.System.*;
+
+import java.io.File;
+
+import org.apache.vysper.mina.TCPEndpoint;
+import org.apache.vysper.stanzasession.StanzaSessionFactory;
+import org.apache.vysper.storage.StorageProviderRegistry;
+import org.apache.vysper.storage.inmemory.MemoryStorageProviderRegistry;
+import org.apache.vysper.xmpp.authorization.AccountManagement;
+import org.apache.vysper.xmpp.modules.extension.xep0049_privatedata.PrivateDataModule;
+import org.apache.vysper.xmpp.modules.extension.xep0054_vcardtemp.VcardTempModule;
+import org.apache.vysper.xmpp.modules.extension.xep0092_software_version.SoftwareVersionModule;
+import org.apache.vysper.xmpp.modules.extension.xep0119_xmppping.XmppPingModule;
+import org.apache.vysper.xmpp.modules.extension.xep0202_entity_time.EntityTimeModule;
+import org.apache.vysper.xmpp.server.XMPPServer;
+
+class TestVysperServer {
+ public static void main(final String args[]) throws Exception {
+ out.println("Starting test Vysper server...");
+
+ // Add the XMPP users used by the xmpp-test and server-test test cases
+ // If you're using your own XMPP server you need to add these users manually
+ final StorageProviderRegistry providerRegistry = new MemoryStorageProviderRegistry();
+ final AccountManagement accountManagement = (AccountManagement)providerRegistry.retrieve(AccountManagement.class);
+ accountManagement.addUser("sca1@localhost", "sca1");
+ accountManagement.addUser("sca2@localhost", "sca2");
+ accountManagement.addUser("sca3@localhost", "sca3");
+
+ // Create and start XMPP server for domain: localhost
+ final XMPPServer server = new org.apache.vysper.xmpp.server.XMPPServer("localhost");
+ server.addEndpoint(new TCPEndpoint());
+ server.addEndpoint(new StanzaSessionFactory());
+ server.setStorageProviderRegistry(providerRegistry);
+ final File cert = new File(TestVysperServer.class.getClassLoader().getResource("bogus_mina_tls.cert").getPath());
+ server.setTLSCertificateInfo(cert, "boguspw");
+ server.start();
+ server.addModule(new SoftwareVersionModule());
+ server.addModule(new EntityTimeModule());
+ server.addModule(new VcardTempModule());
+ server.addModule(new XmppPingModule());
+ server.addModule(new PrivateDataModule());
+ out.println("Test Vysper server started...");
+
+ // Wait forever
+ final Object lock = new Object();
+ synchronized(lock) {
+ lock.wait();
+ }
+
+ System.out.println("Stopping test Vysper server...");
+ server.stop();
+ out.println("Test Vysper server stopped.");
+ System.exit(0);
+ }
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/chat/vysper-classpath b/sca-cpp/branches/gcc-4.4/components/chat/vysper-classpath
new file mode 100755
index 0000000000..7cf16a5ae8
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/chat/vysper-classpath
@@ -0,0 +1,29 @@
+#!/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.
+
+# Compute a classpath for running a Vysper server
+here=`readlink -f $0`; here=`dirname $here`
+
+if [ "$1" = "" ]; then
+ vysper_prefix=`cat $here/vysper.prefix`
+else
+ vysper_prefix=$1
+fi
+jars=`find $vysper_prefix/lib -name "*.jar" | awk '{ printf "%s:", $1 }'`
+echo "$vysper_prefix/config:$jars"
diff --git a/sca-cpp/branches/gcc-4.4/components/chat/vysper-start b/sca-cpp/branches/gcc-4.4/components/chat/vysper-start
new file mode 100755
index 0000000000..af95ecadf4
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/chat/vysper-start
@@ -0,0 +1,25 @@
+#!/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.
+
+# Start Vysper test XMPP server
+here=`readlink -f $0`; here=`dirname $here`
+
+java_prefix=`cat $here/../../modules/java/java.prefix`
+mkdir -p $here/tmp/logs
+${java_prefix}/jre/bin/java -cp `$here/vysper-classpath`$here test.TestVysperServer 2>&1 1>>$here/tmp/logs/vysper.log &
diff --git a/sca-cpp/branches/gcc-4.4/components/chat/vysper-stop b/sca-cpp/branches/gcc-4.4/components/chat/vysper-stop
new file mode 100755
index 0000000000..3c4be4efa9
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/chat/vysper-stop
@@ -0,0 +1,25 @@
+#!/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.
+
+# Stop Vysper test XMPP server
+here=`readlink -f $0`; here=`dirname $here`
+
+java_prefix=`cat $here/../../modules/java/java.prefix`
+kill `ps -ef | grep -v grep | grep "${java_prefix}/jre/bin/java" | grep "vysper" | awk '{ print $2 }'`
+
diff --git a/sca-cpp/branches/gcc-4.4/components/chat/xmpp-test.cpp b/sca-cpp/branches/gcc-4.4/components/chat/xmpp-test.cpp
new file mode 100644
index 0000000000..6b7fa3439f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/chat/xmpp-test.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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 XMPP support functions.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "list.hpp"
+#include "element.hpp"
+#include "monad.hpp"
+#include "value.hpp"
+#include "perf.hpp"
+#include "parallel.hpp"
+#include "xmpp.hpp"
+
+namespace tuscany {
+namespace chat {
+
+const value jid1("sca1@localhost");
+const value pass1("sca1");
+const value jid2("sca2@localhost");
+const value pass2("sca2");
+
+worker w(2);
+bool received;
+
+const failable<bool> listener(const value& from, const value& val, unused XMPPClient& xc) {
+ assert(contains(from, "sca1@localhost"));
+ assert(val == "hey");
+ received = true;
+ return false;
+}
+
+struct subscribe {
+ XMPPClient& xc;
+ subscribe(XMPPClient& xc) : xc(xc) {
+ }
+ const failable<bool> operator()() const {
+ const lambda<failable<bool>(const value&, const value&, XMPPClient&)> l(listener);
+ listen(l, xc);
+ return true;
+ }
+};
+
+bool testListen() {
+ received = false;
+ XMPPClient& xc = *(new (gc_new<XMPPClient>()) XMPPClient(jid2, pass2));
+ const failable<bool> c = connect(xc);
+ assert(hasContent(c));
+ const lambda<failable<bool>()> subs = subscribe(xc);
+ submit(w, subs);
+ return true;
+}
+
+bool testPost() {
+ XMPPClient xc(jid1, pass1);
+ const failable<bool> c = connect(xc);
+ assert(hasContent(c));
+ const failable<bool> p = post(jid2, "hey", xc);
+ assert(hasContent(p));
+ return true;
+}
+
+bool testReceived() {
+ shutdown(w);
+ assert(received == true);
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::chat::testListen();
+ tuscany::chat::testPost();
+ tuscany::chat::testReceived();
+
+ tuscany::cout << "OK" << tuscany::endl;
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/chat/xmpp.hpp b/sca-cpp/branches/gcc-4.4/components/chat/xmpp.hpp
new file mode 100644
index 0000000000..34ab13ed98
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/chat/xmpp.hpp
@@ -0,0 +1,330 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_queue_hpp
+#define tuscany_queue_hpp
+
+/**
+ * XMPP support functions.
+ */
+
+#include <apr_uuid.h>
+
+#include "strophe.h"
+extern "C" {
+#include "common.h"
+}
+#include "string.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "../../modules/scheme/eval.hpp"
+
+namespace tuscany {
+namespace chat {
+
+/**
+ * XMPP runtime, one per process.
+ */
+class XMPPRuntime {
+public:
+ XMPPRuntime() {
+ xmpp_initialize();
+ log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG);
+ }
+
+ ~XMPPRuntime() {
+ xmpp_shutdown();
+ }
+
+private:
+ friend class XMPPClient;
+ xmpp_log_t* log;
+
+} xmppRuntime;
+
+/**
+ * Represents an XMPP client.
+ */
+const string resourceUUID() {
+ apr_uuid_t uuid;
+ apr_uuid_get(&uuid);
+ char buf[APR_UUID_FORMATTED_LENGTH];
+ apr_uuid_format(buf, &uuid);
+ return string(buf, APR_UUID_FORMATTED_LENGTH);
+}
+
+class XMPPClient {
+public:
+ XMPPClient(const string& jid, const string& pass, bool owner = true) : owner(owner), ctx(xmpp_ctx_new(NULL, xmppRuntime.log)), conn(xmpp_conn_new(ctx)), connecting(false), connected(false), disconnecting(false) {
+ xmpp_conn_set_jid(conn, c_str(jid + "/" + resourceUUID()));
+ xmpp_conn_set_pass(conn, c_str(pass));
+ }
+
+ XMPPClient(const XMPPClient& xc) : owner(false), ctx(xc.ctx), conn(xc.conn), listener(xc.listener), connecting(xc.connecting), connected(xc.connected), disconnecting(xc.disconnecting) {
+ }
+
+ ~XMPPClient() {
+ extern const failable<bool> disconnect(XMPPClient& xc);
+ if (!owner)
+ return;
+ if (!disconnecting)
+ disconnect(*this);
+ xmpp_conn_release(conn);
+ xmpp_ctx_free(ctx);
+ }
+
+private:
+ friend int versionHandler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* const udata);
+ friend void connHandler(xmpp_conn_t * const conn, const xmpp_conn_event_t status, const int err, xmpp_stream_error_t* const errstream, void *const udata);
+ friend int messageHandler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* const udata);
+ friend const failable<bool> connect(XMPPClient& xc);
+ friend const failable<int> send(const char* data, const int len, XMPPClient& xc);
+ friend const failable<int> send(xmpp_stanza_t* const stanza, XMPPClient& xc);
+ friend const failable<bool> post(const value& to, const value& val, XMPPClient& xc);
+ friend const failable<bool> disconnect(XMPPClient& xc);
+ friend const failable<bool> listen(const lambda<failable<bool>(const value&, const value&, XMPPClient&)>& listener, XMPPClient& xc);
+
+ const bool owner;
+ xmpp_ctx_t* ctx;
+ xmpp_conn_t* conn;
+ lambda<failable<bool>(const value&, const value&, XMPPClient&)> listener;
+ bool connecting;
+ bool connected;
+ bool disconnecting;
+};
+
+/**
+ * Make a text stanza.
+ */
+xmpp_stanza_t* textStanza(const char* text, xmpp_ctx_t* ctx) {
+ xmpp_stanza_t* stanza = xmpp_stanza_new(ctx);
+ xmpp_stanza_set_text(stanza, text);
+ return stanza;
+}
+
+/**
+ * Make a named stanza.
+ */
+xmpp_stanza_t* namedStanza(const char* ns, const char* name, xmpp_ctx_t* ctx) {
+ xmpp_stanza_t* stanza = xmpp_stanza_new(ctx);
+ xmpp_stanza_set_name(stanza, name);
+ if (ns != NULL)
+ xmpp_stanza_set_ns(stanza, ns);
+ return stanza;
+}
+
+/**
+ * Make a named stanza using a qualified name.
+ */
+xmpp_stanza_t* namedStanza(const char* name, xmpp_ctx_t* ctx) {
+ xmpp_stanza_t* stanza = xmpp_stanza_new(ctx);
+ xmpp_stanza_set_name(stanza, name);
+ return stanza;
+}
+
+/**
+ * XMPP version handler.
+ */
+int versionHandler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* const udata) {
+ XMPPClient& xc = *(XMPPClient*)udata;
+
+ // Build version reply stanza
+ xmpp_stanza_t* reply = namedStanza("iq", xc.ctx);
+ xmpp_stanza_set_type(reply, "result");
+ xmpp_stanza_set_id(reply, xmpp_stanza_get_id(stanza));
+ xmpp_stanza_set_attribute(reply, "to", xmpp_stanza_get_attribute(stanza, "from"));
+ xmpp_stanza_t* query = namedStanza(xmpp_stanza_get_ns(xmpp_stanza_get_children(stanza)), "query", xc.ctx);
+ xmpp_stanza_add_child(reply, query);
+ xmpp_stanza_t* name = namedStanza("name", xc.ctx);
+ xmpp_stanza_add_child(query, name);
+ xmpp_stanza_add_child(name, textStanza("Apache Tuscany", xc.ctx));
+ xmpp_stanza_t* version = namedStanza("version", xc.ctx);
+ xmpp_stanza_add_child(query, version);
+ xmpp_stanza_add_child(version, textStanza("1.0", xc.ctx));
+
+ // Send it
+ xmpp_send(conn, reply);
+ xmpp_stanza_release(reply);
+ return 1;
+}
+
+/**
+ * XMPP message handler
+ */
+int messageHandler(unused xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* const udata) {
+ // Ignore noise
+ if(xmpp_stanza_get_child_by_name(stanza, "body") == NULL)
+ return 1;
+ if(!strcmp(xmpp_stanza_get_attribute(stanza, "type"), "error"))
+ return 1;
+
+ // Call the client listener function
+ XMPPClient& xc = *(XMPPClient*)udata;
+ const char* from = xmpp_stanza_get_attribute(stanza, "from");
+ const char* text = xmpp_stanza_get_text(xmpp_stanza_get_child_by_name(stanza, "body"));
+ if (isNil(xc.listener))
+ return 1;
+ const value val(scheme::readValue(text));
+ debug(from, "chat::messageHandler::from");
+ debug(val, "chat::messageHandler::body");
+ const failable<bool> r = xc.listener(value(string(from)), val, xc);
+ if (!hasContent(r) || !content(r)) {
+ // Stop listening
+ xc.listener = lambda<failable<bool>(const value&, const value&, XMPPClient&)>();
+ return 0;
+ }
+ return 1;
+}
+
+/**
+ * XMPP connection handler.
+ */
+void connHandler(xmpp_conn_t * const conn, const xmpp_conn_event_t status, unused const int err, unused xmpp_stream_error_t* const errstream, void *const udata) {
+ XMPPClient& xc = *(XMPPClient*)udata;
+ xc.connecting = false;
+
+ if (status == XMPP_CONN_CONNECT) {
+ debug("chat::connHandler::connected");
+ xmpp_handler_add(conn, versionHandler, "jabber:iq:version", "iq", NULL, &xc);
+
+ // Send a <presence/> stanza so that we appear online to contacts
+ xmpp_stanza_t* pres = xmpp_stanza_new(xc.ctx);
+ xmpp_stanza_set_name(pres, "presence");
+ xmpp_send(conn, pres);
+ xmpp_stanza_release(pres);
+ xc.connected = true;
+ return;
+ }
+
+ debug("chat::connHandler::disconnected");
+ xc.connected = false;
+ if (xc.ctx->loop_status == XMPP_LOOP_RUNNING)
+ xc.ctx->loop_status = XMPP_LOOP_QUIT;
+}
+
+/**
+ * Connect to an XMPP server.
+ */
+const failable<bool> connect(XMPPClient& xc) {
+ xc.connecting = true;
+ xmpp_connect_client(xc.conn, NULL, 0, connHandler, &xc);
+ while(xc.connecting)
+ xmpp_run_once(xc.ctx, 20L);
+ if (!xc.connected)
+ return mkfailure<bool>("Couldn't connect to XMPP server");
+ return true;
+}
+
+/**
+ * Send a buffer on an XMPP session.
+ */
+const failable<int> send(const char* data, const int len, XMPPClient& xc) {
+ if (len == 0)
+ return 0;
+ const int written = xc.conn->tls? tls_write(xc.conn->tls, data, len) : sock_write(xc.conn->sock, data, len);
+ if (written < 0) {
+ xc.conn->error = xc.conn->tls? tls_error(xc.conn->tls) : sock_error();
+ return mkfailure<int>("Couldn't send stanza to XMPP server");
+ }
+ return send(data + written, len - written, xc);
+}
+
+/**
+ * Send a string on an XMPP session.
+ */
+const failable<int> send(const string& data, XMPPClient& xc) {
+ return send(c_str(data), length(data), xc);
+}
+
+/**
+ * Send a stanza on an XMPP session.
+ */
+const failable<int> send(xmpp_stanza_t* const stanza, XMPPClient& xc) {
+ char *buf;
+ size_t len;
+ const int rc = xmpp_stanza_to_text(stanza, &buf, &len);
+ if (rc != 0)
+ return mkfailure<int>("Couldn't convert stanza to text");
+ const failable<int> r = send(buf, len, xc);
+ if (!hasContent(r)) {
+ xmpp_free(xc.conn->ctx, buf);
+ return r;
+ }
+ xmpp_debug(xc.conn->ctx, "conn", "SENT: %s", buf);
+ xmpp_free(xc.conn->ctx, buf);
+ return content(r);
+}
+
+/**
+ * Post a message to an XMPP jid.
+ */
+const failable<bool> post(const value& to, const value& val, XMPPClient& xc) {
+ debug(to, "chat::post::to");
+ debug(val, "chat::post::body");
+
+ // Convert the value to a string
+ const string vs(scheme::writeValue(val));
+
+ // Build message stanza
+ xmpp_stanza_t* stanza = namedStanza("message", xc.ctx);
+ xmpp_stanza_set_type(stanza, "chat");
+ xmpp_stanza_set_attribute(stanza, "to", c_str(string(to)));
+ xmpp_stanza_t* body = namedStanza("body", xc.ctx);
+ xmpp_stanza_add_child(stanza, body);
+ xmpp_stanza_add_child(body, textStanza(c_str(vs), xc.ctx));
+
+ // Send it
+ const failable<int> r = send(stanza, xc);
+ xmpp_stanza_release(stanza);
+ if (!hasContent(r))
+ return mkfailure<bool>(reason(r));
+ return true;
+}
+
+/**
+ * Disconnect an XMPP session.
+ */
+const failable<bool> disconnect(XMPPClient& xc) {
+ xc.disconnecting = true;
+ const failable<int> r = send("</stream:stream>", xc);
+ if (!hasContent(r))
+ return mkfailure<bool>(reason(r));
+ return true;
+}
+
+/**
+ * Listen to messages received by an XMPP client.
+ */
+const failable<bool> listen(const lambda<failable<bool>(const value&, const value&, XMPPClient&)>& listener, XMPPClient& xc) {
+ debug("chat::listen");
+ xc.listener = listener;
+ xmpp_handler_add(xc.conn, messageHandler, NULL, "message", NULL, &xc);
+ xc.ctx->loop_status = XMPP_LOOP_RUNNING;
+ while(xc.connected && !isNil(xc.listener) && xc.ctx->loop_status == XMPP_LOOP_RUNNING)
+ xmpp_run_once(xc.ctx, 1000L);
+ return true;
+}
+
+}
+}
+
+#endif /* tuscany_xmpp_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/components/log/Makefile.am b/sca-cpp/branches/gcc-4.4/components/log/Makefile.am
new file mode 100644
index 0000000000..de5c2d1b1e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/log/Makefile.am
@@ -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/gcc-4.4/components/log/log.composite b/sca-cpp/branches/gcc-4.4/components/log/log.composite
new file mode 100644
index 0000000000..2b0a557e4e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/log/log.composite
@@ -0,0 +1,33 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/components"
+ name="log">
+
+ <component name="log">
+ <implementation.cpp path=".libs" library="liblog"/>
+ <property name="file">sample.log</property>property>
+ <service name="log">
+ <t:binding.http uri="log"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/components/queue/Makefile.am b/sca-cpp/branches/gcc-4.4/components/queue/Makefile.am
new file mode 100644
index 0000000000..856aef8ea0
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/queue/Makefile.am
@@ -0,0 +1,46 @@
+# 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_QUEUE
+
+INCLUDES = -I${QPIDC_INCLUDE}
+
+comp_SCRIPTS = qpidd-start qpidd-stop
+compdir=$(prefix)/components/queue
+
+comp_DATA = qpidc.prefix
+qpidc.prefix: $(top_builddir)/config.status
+ echo ${QPIDC_PREFIX} >qpidc.prefix
+
+comp_LTLIBRARIES = libqueue-sender.la libqueue-listener.la
+
+libqueue_sender_la_SOURCES = queue-sender.cpp
+libqueue_sender_la_LDFLAGS = -L${QPIDC_LIB} -R${QPIDC_LIB} -lqpidclient -lqpidcommon
+
+libqueue_listener_la_SOURCES = queue-listener.cpp
+libqueue_listener_la_LDFLAGS = -L${QPIDC_LIB} -R${QPIDC_LIB} -lqpidclient -lqpidcommon
+
+qpid_test_SOURCES = qpid-test.cpp
+qpid_test_LDFLAGS = -L${QPIDC_LIB} -R${QPIDC_LIB} -lqpidclient -lqpidcommon
+
+client_test_SOURCES = client-test.cpp
+client_test_LDFLAGS = -lxml2 -lcurl -lmozjs -L${QPIDC_LIB} -R${QPIDC_LIB} -lqpidclient -lqpidcommon
+
+noinst_PROGRAMS = qpid-test client-test
+TESTS = send-test server-test
+
+endif
diff --git a/sca-cpp/branches/gcc-4.4/components/queue/client-test.cpp b/sca-cpp/branches/gcc-4.4/components/queue/client-test.cpp
new file mode 100644
index 0000000000..a448d1fccd
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/queue/client-test.cpp
@@ -0,0 +1,99 @@
+/*
+ * 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 queue component.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "list.hpp"
+#include "element.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "perf.hpp"
+#include "../../modules/http/curl.hpp"
+#include "qpid.hpp"
+
+// Ignore conversion issues and redundant declarations in Qpid headers
+#ifdef WANT_MAINTAINER_MODE
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#endif
+
+namespace tuscany {
+namespace queue {
+
+const value key(mklist<value>(string("report")));
+const string qname("reportq");
+
+const list<value> item = list<value>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99"));
+const list<value> entry = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), item);
+
+bool testDeclareQueue() {
+ QpidConnection qc;
+ QpidSession qs(qc);
+ const failable<bool> r = declareQueue(key, qname, qs);
+ assert(hasContent(r));
+ return true;
+}
+
+const bool listener(const value& k, const value& v) {
+ cerr << "k " << k << " v " << v << endl;
+ assert(k == key);
+ assert(v == entry);
+ return false;
+}
+
+bool testListen() {
+ QpidConnection qc;
+ QpidSession qs(qc);
+ QpidSubscription qsub(qs);
+ const lambda<bool(const value&, const value&)> l(listener);
+ listen(qname, l, qsub);
+ return true;
+}
+
+bool testPost() {
+ gc_scoped_pool pool;
+ http::CURLSession ch;
+ const failable<value> id = http::post(entry, "http://localhost:8090/print-sender", ch);
+ assert(hasContent(id));
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::queue::testDeclareQueue();
+ tuscany::queue::testPost();
+ tuscany::queue::testListen();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/queue/qpid-test.cpp b/sca-cpp/branches/gcc-4.4/components/queue/qpid-test.cpp
new file mode 100644
index 0000000000..1a650157b2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/queue/qpid-test.cpp
@@ -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.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Test Qpid support functions.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "list.hpp"
+#include "element.hpp"
+#include "monad.hpp"
+#include "value.hpp"
+#include "perf.hpp"
+#include "qpid.hpp"
+
+// Ignore conversion issues and redundant declarations in Qpid headers
+#ifdef WANT_MAINTAINER_MODE
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#endif
+
+namespace tuscany {
+namespace queue {
+
+const value key(mklist<value>("test"));
+const string qname("testq");
+
+bool testDeclareQueue() {
+ QpidConnection qc;
+ QpidSession qs(qc);
+ const failable<bool> r = declareQueue(key, qname, qs);
+ assert(hasContent(r));
+ return true;
+}
+
+const list<value> item = list<value>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99"));
+const list<value> entry = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), item);
+
+bool testPost() {
+ QpidConnection qc;
+ QpidSession qs(qc);
+ const failable<bool> r = post(key, entry, qs);
+ assert(hasContent(r));
+ return true;
+}
+
+const bool listener(const value& k, const value& v) {
+ assert(k == key);
+ assert(v == entry);
+ return false;
+}
+
+bool testListen() {
+ QpidConnection qc;
+ QpidSession qs(qc);
+ QpidSubscription qsub(qs);
+ const lambda<bool(const value&, const value&)> l(listener);
+ listen(qname, l, qsub);
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::queue::testDeclareQueue();
+ tuscany::queue::testPost();
+ tuscany::queue::testListen();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/queue/qpid.hpp b/sca-cpp/branches/gcc-4.4/components/queue/qpid.hpp
new file mode 100644
index 0000000000..2651e3a433
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/queue/qpid.hpp
@@ -0,0 +1,260 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_qpid_hpp
+#define tuscany_qpid_hpp
+
+/**
+ * AMQP queue access functions.
+ */
+
+// Ignore conversion issues and redundant declarations in Qpid headers
+#ifdef WANT_MAINTAINER_MODE
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#endif
+
+#include <qpid/client/Connection.h>
+#include <qpid/client/Session.h>
+#include <qpid/client/MessageListener.h>
+#include <qpid/client/SubscriptionManager.h>
+
+#include "string.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "../../modules/scheme/eval.hpp"
+
+namespace tuscany {
+namespace queue {
+
+/**
+ * Represents a Qpid connection.
+ */
+class QpidConnection {
+public:
+ QpidConnection() : owner(true) {
+ c.open("localhost", 5672);
+ }
+
+ QpidConnection(const bool owner) : owner(owner) {
+ c.open("localhost", 5672);
+ }
+
+ QpidConnection(const QpidConnection& qc) : owner(false), c(qc.c) {
+ }
+
+ ~QpidConnection() {
+ if (!owner)
+ return;
+ c.close();
+ }
+
+private:
+ friend const failable<bool> close(QpidConnection& qc);
+ friend class QpidSession;
+
+ const bool owner;
+ qpid::client::Connection c;
+
+};
+
+/**
+ * Close a Qpid connection.
+ */
+const failable<bool> close(QpidConnection& qc) {
+ qc.c.close();
+ return true;
+}
+
+/**
+ * Represents a Qpid session.
+ */
+class QpidSession {
+public:
+ QpidSession(QpidConnection& qc) : owner(true), s(qc.c.newSession()) {
+ }
+
+ QpidSession(QpidConnection& qc, const bool owner) : owner(owner), s(qc.c.newSession()) {
+ }
+
+ QpidSession(const QpidSession& qs) : owner(false), s(qs.s) {
+ }
+
+ ~QpidSession() {
+ if (!owner)
+ return;
+ s.close();
+ }
+
+private:
+ friend const failable<bool> close(QpidSession& qs);
+ friend const failable<bool> declareQueue(const value& key, const string& name, QpidSession& qs);
+ friend const failable<bool> post(const value& key, const value& val, QpidSession& qs);
+ friend class QpidSubscription;
+
+ const bool owner;
+ qpid::client::Session s;
+};
+
+/**
+ * Close a Qpid session.
+ */
+const failable<bool> close(QpidSession& qs) {
+ try {
+ qs.s.close();
+ } catch (const qpid::Exception& e) {
+ return mkfailure<bool>(string("Qpid failure: ") + e.what());
+ }
+ return true;
+}
+
+/**
+ * Declare a key / AMQP queue pair.
+ */
+const failable<bool> declareQueue(const value& key, const string& name, QpidSession& qs) {
+ const string ks(scheme::writeValue(key));
+ try {
+ qs.s.queueDeclare(qpid::client::arg::queue=c_str(name));
+ qs.s.exchangeBind(qpid::client::arg::exchange="amq.direct", qpid::client::arg::queue=c_str(name), qpid::client::arg::bindingKey=c_str(ks));
+ } catch (const qpid::Exception& e) {
+ return mkfailure<bool>(string("Qpid failure: ") + e.what());
+ }
+ return true;
+}
+
+/**
+ * Post a key / value pair message to an AMQP broker.
+ */
+const failable<bool> post(const value& key, const value& val, QpidSession& qs) {
+
+ // Send in a message with the given key.
+ const string ks(scheme::writeValue(key));
+ const string vs(scheme::writeValue(val));
+ try {
+ qpid::client::Message message;
+ message.getDeliveryProperties().setRoutingKey(c_str(ks));
+ message.setData(c_str(vs));
+ qs.s.messageTransfer(qpid::client::arg::content=message, qpid::client::arg::destination="amq.direct");
+ } catch (const qpid::Exception& e) {
+ return mkfailure<bool>(string("Qpid failure: ") + e.what());
+ }
+ return true;
+}
+
+/**
+ * Represents a Qpid subscription.
+ */
+class QpidSubscription {
+public:
+ QpidSubscription(QpidSession& qs) : owner(true), subs(qs.s) {
+ }
+
+ QpidSubscription(QpidSession& qs, const bool owner) : owner(owner), subs(qs.s) {
+ }
+
+ QpidSubscription(const QpidSubscription& qsub) : owner(false), subs(qsub.subs) {
+ }
+
+ ~QpidSubscription() {
+ if (!owner)
+ return;
+ try {
+ subs.stop();
+ } catch (const qpid::Exception& e) {
+ mkfailure<bool>(string("Qpid failure: ") + e.what());
+ }
+ }
+
+private:
+ friend const failable<bool> listen(const string& name, const lambda<bool(const value&, const value&)>& l, QpidSubscription& qsub);
+ friend const failable<bool> stop(QpidSubscription& qsub);
+
+ const bool owner;
+ qpid::client::SubscriptionManager subs;
+};
+
+/**
+ * Register a listener function with an AMQP queue.
+ */
+class Listener : public qpid::client::MessageListener {
+public:
+ Listener(const lambda<bool(const value&, const value&)> l, qpid::client::SubscriptionManager& subs) : l(l), subs(subs) {
+ }
+
+ virtual void received(qpid::client::Message& msg) {
+
+ // Call the listener function
+ const value k(scheme::readValue(msg.getDeliveryProperties().getRoutingKey().c_str()));
+ const value v(scheme::readValue(msg.getData().c_str()));
+ const bool r = l(k, v);
+ if (!r) {
+ try {
+ subs.cancel(msg.getDestination());
+ } catch (const qpid::Exception& e) {
+ mkfailure<bool>(string("Qpid failure: ") + e.what());
+ }
+ }
+ }
+
+private:
+ const lambda<bool(const value&, const value&)> l;
+ qpid::client::SubscriptionManager& subs;
+};
+
+
+const failable<bool> listen(const string& name, const lambda<bool(const value&, const value&)>& l, QpidSubscription& qsub) {
+ debug("queue::listen");
+ Listener listener(l, qsub.subs);
+ try {
+ qsub.subs.subscribe(listener, c_str(name));
+ qsub.subs.run();
+ } catch (const qpid::Exception& e) {
+ return mkfailure<bool>(string("Qpid failure: ") + e.what());
+ }
+ debug("queue::listen::stopped");
+ return true;
+}
+
+/**
+ * Stop an AMQP subscription.
+ */
+const failable<bool> stop(QpidSubscription& qsub) {
+ debug("queue::stop");
+ try {
+ qsub.subs.stop();
+ } catch (const qpid::Exception& e) {
+ return mkfailure<bool>(string("Qpid failure: ") + e.what());
+ }
+ debug("queue::stopped");
+ return true;
+}
+
+}
+}
+
+// Re-enable conversion and redundant declarations warnings
+#ifdef WANT_MAINTAINER_MODE
+#pragma GCC diagnostic warning "-Wconversion"
+#pragma GCC diagnostic warning "-Wredundant-decls"
+#endif
+
+#endif /* tuscany_qpid_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/components/queue/qpidd-start b/sca-cpp/branches/gcc-4.4/components/queue/qpidd-start
new file mode 100755
index 0000000000..02e048c41e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/queue/qpidd-start
@@ -0,0 +1,24 @@
+#!/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.
+
+# Start qpidd
+here=`readlink -f $0`; here=`dirname $here`
+
+qpid_prefix=`cat $here/qpidc.prefix`
+$qpid_prefix/sbin/qpidd &
diff --git a/sca-cpp/branches/gcc-4.4/components/queue/qpidd-stop b/sca-cpp/branches/gcc-4.4/components/queue/qpidd-stop
new file mode 100755
index 0000000000..3baf2fee27
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/queue/qpidd-stop
@@ -0,0 +1,26 @@
+#!/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.
+
+# Stop qpidd
+here=`readlink -f $0`; here=`dirname $here`
+
+qpid_prefix=`cat $here/qpidc.prefix`
+qpidd="$qpid_prefix/sbin/qpidd"
+
+kill `ps -ef | grep -v grep | grep "${qpidd}" | awk '{ print $2 }'`
diff --git a/sca-cpp/branches/gcc-4.4/components/queue/queue-listener.cpp b/sca-cpp/branches/gcc-4.4/components/queue/queue-listener.cpp
new file mode 100644
index 0000000000..d714101583
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/queue/queue-listener.cpp
@@ -0,0 +1,158 @@
+/*
+ * 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$ */
+
+/**
+ * AMQP queue listener component implementation.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "parallel.hpp"
+#include "qpid.hpp"
+
+// Ignore conversion issues and redundant declarations in Qpid headers
+#ifdef WANT_MAINTAINER_MODE
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#endif
+
+namespace tuscany {
+namespace queue {
+
+/**
+ * A relay function that posts the AMQP messages it receives to a relay component reference.
+ */
+class relay {
+public:
+ relay(const lambda<value(const list<value>&)>& rel) : rel(rel) {
+ }
+
+ const bool operator()(const value& k, const value& v) const {
+ debug(k, "queue::relay::key");
+ debug(v, "queue::relay::value");
+ const value res = rel(mklist<value>("post", isList(k)? (list<value>)k : mklist<value>(k), v));
+ return true;
+ }
+
+private:
+ const lambda<value(const list<value>&)> rel;
+};
+
+/**
+ * Subscribe and listen to an AMQP queue.
+ */
+class subscribe {
+public:
+ subscribe(const string& qname, const lambda<bool(const value&, const value&)>& l, const QpidSubscription& qsub) : qname(qname), l(l), qsub(qsub) {
+ }
+
+ const failable<bool> operator()() const {
+ gc_pool pool;
+ debug(qname, "queue::subscribe::listen");
+ const failable<bool> r = listen(qname, l, const_cast<QpidSubscription&>(qsub));
+ debug(qname, "queue::subscribe::stopped");
+ return r;
+ }
+
+private:
+ const string qname;
+ const lambda<bool(const value&, const value&)> l;
+ const QpidSubscription qsub;
+};
+
+/**
+ * Listener lambda function, responsible for starting an AMQP subscription in a worker thread, and
+ * apply any function calls to the listener component. The only supported function is stop(),
+ * called to stop the listener component and shutdown the worker thread.
+ */
+class listener {
+public:
+ listener(QpidConnection& qc, QpidSession& qs, QpidSubscription& qsub, worker& w) : qc(qc), qs(qs), qsub(qsub), w(w) {
+ }
+
+ const value operator()(const list<value>& params) const {
+ const tuscany::value func(car(params));
+
+ // Stop the component
+ if (func != "stop")
+ return tuscany::mkfailure<tuscany::value>();
+ debug("queue::listener::stop");
+
+ // TODO check why stop() and close() hang in child processes
+ stop(const_cast<QpidSubscription&>(qsub));
+ close(const_cast<QpidSession&>(qs));
+ close(const_cast<QpidConnection&>(qc));
+ cancel(const_cast<worker&>(w));
+
+ debug("queue::listener::stopped");
+ return failable<value>(value(lambda<value(const list<value>&)>()));
+ }
+
+private:
+ QpidConnection qc;
+ QpidSession qs;
+ QpidSubscription qsub;
+ worker w;
+};
+
+/**
+ * Start the component.
+ */
+const failable<value> start(const list<value>& params) {
+ // Extract the relay reference and the AMQP key and queue name
+ const value rel = car(params);
+ const value pk = ((lambda<value(list<value>)>)cadr(params))(list<value>());
+ const value key = isList(pk)? (list<value>)pk : mklist<value>(pk);
+ const value qname = ((lambda<value(list<value>)>)caddr(params))(list<value>());
+
+ // Create an AMQP session
+ QpidConnection qc(false);
+ QpidSession qs(qc, false);
+
+ // Declare the configured AMQP key / queue pair
+ declareQueue(key, qname, qs);
+
+ // Listen and relay messages in a worker thread
+ QpidSubscription qsub(qs, false);
+ worker w(3);
+ const lambda<bool(const value&, const value&)> rl = relay(rel);
+ submit<failable<bool> >(w, lambda<failable<bool>()>(subscribe(qname, rl, qsub)));
+
+ // Return the listener component lambda function
+ return value(lambda<value(const list<value>&)>(listener(qc, qs, qsub, w)));
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+ const tuscany::value func(car(params));
+ if (func == "start")
+ return tuscany::queue::start(cdr(params));
+ return tuscany::mkfailure<tuscany::value>();
+}
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/queue/queue-sender.cpp b/sca-cpp/branches/gcc-4.4/components/queue/queue-sender.cpp
new file mode 100644
index 0000000000..07f8491f54
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/queue/queue-sender.cpp
@@ -0,0 +1,72 @@
+/*
+ * 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$ */
+
+/**
+ * AMQP queue sender component implementation.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "qpid.hpp"
+
+// Ignore conversion issues and redundant declarations in Qpid headers
+#ifdef WANT_MAINTAINER_MODE
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#endif
+
+namespace tuscany {
+namespace queue {
+
+/**
+ * Post an item to a queue.
+ */
+const failable<value> post(const list<value>& params) {
+ QpidConnection qc;
+ QpidSession qs(qc);
+
+ // Post the item
+ const value pk = ((lambda<value(list<value>)>)caddr(params))(list<value>());
+ const value key = isList(pk)? append<value>(pk, (list<value>)car(params)) : cons<value>(pk, (list<value>)car(params));
+ debug(key, "queue::post::key");
+ debug(cadr(params), "queue::post::value");
+ const failable<bool> r = post(key, cadr(params), qs);
+ if (!hasContent(r))
+ return mkfailure<value>(reason(r));
+ return key;
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+ const tuscany::value func(car(params));
+ if (func == "post")
+ return tuscany::queue::post(cdr(params));
+ return tuscany::mkfailure<tuscany::value>();
+}
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/queue/queue.composite b/sca-cpp/branches/gcc-4.4/components/queue/queue.composite
new file mode 100644
index 0000000000..535680c6c3
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/queue/queue.composite
@@ -0,0 +1,56 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/components"
+ name="queue">
+
+ <component name="print-sender">
+ <implementation.cpp path=".libs" library="libqueue-sender"/>
+ <property name="key">print</property>
+ <service name="print-sender">
+ <t:binding.http uri="print-sender"/>
+ </service>
+ </component>
+
+ <component name="print-listener">
+ <implementation.cpp path=".libs" library="libqueue-listener"/>
+ <property name="key">print</property>
+ <property name="queue">printq</property>
+ <reference name="relay" target="print"/>
+ </component>
+
+ <component name="print">
+ <t:implementation.scheme script="server-test.scm"/>
+ <service name="print">
+ <t:binding.http uri="print"/>
+ </service>
+ <reference name="report" target="report-sender"/>
+ </component>
+
+ <component name="report-sender">
+ <implementation.cpp path=".libs" library="libqueue-sender"/>
+ <property name="key">report</property>
+ <service name="report-sender">
+ <t:binding.http uri="report-sender"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/components/queue/send-test b/sca-cpp/branches/gcc-4.4/components/queue/send-test
new file mode 100755
index 0000000000..ec6d9d9083
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/queue/send-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
+./qpidd-start
+sleep 1
+
+# Test
+./qpid-test 2>/dev/null
+rc=$?
+
+# Cleanup
+./qpidd-stop
+sleep 1
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/components/queue/server-test b/sca-cpp/branches/gcc-4.4/components/queue/server-test
new file mode 100755
index 0000000000..571b09082c
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/queue/server-test
@@ -0,0 +1,43 @@
+#!/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
+../../modules/http/httpd-conf tmp localhost 8090 ../../modules/http/htdocs
+../../modules/server/server-conf tmp
+../../modules/server/scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+SCAContribution `pwd`/
+SCAComposite queue.composite
+EOF
+
+./qpidd-start
+sleep 1
+../../modules/http/httpd-start tmp
+sleep 2
+
+# Test
+./client-test 2>/dev/null
+rc=$?
+
+# Cleanup
+../../modules/http/httpd-stop tmp
+sleep 1
+./qpidd-stop
+sleep 1
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/components/queue/server-test.scm b/sca-cpp/branches/gcc-4.4/components/queue/server-test.scm
new file mode 100644
index 0000000000..1a89ce8b31
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/queue/server-test.scm
@@ -0,0 +1,20 @@
+; 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.
+
+; Queue test case
+
+(define (post key val report) (report "post" '() val))
diff --git a/sca-cpp/branches/gcc-4.4/components/sqldb/Makefile.am b/sca-cpp/branches/gcc-4.4/components/sqldb/Makefile.am
new file mode 100644
index 0000000000..b7c8a4eeaf
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/sqldb/Makefile.am
@@ -0,0 +1,43 @@
+# 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_SQLDB
+
+INCLUDES = -I${PGSQL_INCLUDE}
+
+#comp_SCRIPTS = pgsql-start pgsql-stop
+compdir=$(prefix)/components/sqldb
+
+comp_DATA = pgsql.prefix
+pgsql.prefix: $(top_builddir)/config.status
+ echo ${PGSQL_PREFIX} >pgsql.prefix
+
+comp_LTLIBRARIES = libsqldb.la
+
+libsqldb_la_SOURCES = sqldb.cpp
+libsqldb_la_LDFLAGS = -L${PGSQL_LIB} -R${PGSQL_LIB} -lpq
+
+pgsql_test_SOURCES = pgsql-test.cpp
+pgsql_test_LDFLAGS = -L${PGSQL_LIB} -R${PGSQL_LIB} -lpq
+
+client_test_SOURCES = client-test.cpp
+client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+
+noinst_PROGRAMS = pgsql-test client-test
+TESTS = sqldb-test server-test
+
+endif
diff --git a/sca-cpp/branches/gcc-4.4/components/sqldb/client-test.cpp b/sca-cpp/branches/gcc-4.4/components/sqldb/client-test.cpp
new file mode 100644
index 0000000000..271ec08bed
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/sqldb/client-test.cpp
@@ -0,0 +1,130 @@
+/*
+ * 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 SQLDB component.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "perf.hpp"
+#include "../../modules/http/curl.hpp"
+
+namespace tuscany {
+namespace sqldb {
+
+const string uri("http://localhost:8090/sqldb");
+
+bool testSqlDb() {
+ http::CURLSession cs;
+
+ const list<value> i = list<value>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99"));
+ const list<value> a = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
+
+ const failable<value> id = http::post(a, uri, cs);
+ assert(hasContent(id));
+
+ const string p = path(content(id));
+ {
+ const failable<value> val = http::get(uri + p, cs);
+ assert(hasContent(val));
+ assert(content(val) == a);
+ }
+
+ const list<value> j = list<value>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$3.55"));
+ const list<value> b = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), j);
+
+ {
+ const failable<value> r = http::put(b, uri + p, cs);
+ assert(hasContent(r));
+ assert(content(r) == value(true));
+ }
+ {
+ const failable<value> val = http::get(uri + p, cs);
+ assert(hasContent(val));
+ assert(content(val) == b);
+ }
+ {
+ const failable<value> r = http::del(uri + p, cs);
+ assert(hasContent(r));
+ assert(content(r) == value(true));
+ }
+ {
+ const failable<value> val = http::get(uri + p, cs);
+ assert(!hasContent(val));
+ }
+
+ return true;
+}
+
+struct getLoop {
+ const string path;
+ const value entry;
+ http::CURLSession cs;
+ getLoop(const string& path, const value& entry, http::CURLSession cs) : path(path), entry(entry), cs(cs) {
+ }
+ const bool operator()() const {
+ const failable<value> val = http::get(uri + path, cs);
+ assert(hasContent(val));
+ assert(content(val) == entry);
+ return true;
+ }
+};
+
+bool testGetPerf() {
+ const list<value> i = list<value>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$4.55"));
+ const value a = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
+
+ http::CURLSession cs;
+ const failable<value> id = http::post(a, uri, cs);
+ assert(hasContent(id));
+ const string p = path(content(id));
+
+ const lambda<bool()> gl = getLoop(p, a, cs);
+ cout << "Sqldb get test " << time(gl, 5, 200) << " ms" << endl;
+
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::sqldb::testSqlDb();
+ tuscany::sqldb::testGetPerf();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/sqldb/pgsql b/sca-cpp/branches/gcc-4.4/components/sqldb/pgsql
new file mode 100755
index 0000000000..3cd1904e32
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/sqldb/pgsql
@@ -0,0 +1,25 @@
+#!/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 SQL command
+here=`readlink -f $0`; here=`dirname $here`
+pgsql_prefix=`cat $here/pgsql.prefix`
+
+$pgsql_prefix/bin/psql -c "$1" db
+
diff --git a/sca-cpp/branches/gcc-4.4/components/sqldb/pgsql-start b/sca-cpp/branches/gcc-4.4/components/sqldb/pgsql-start
new file mode 100755
index 0000000000..f5c0f87614
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/sqldb/pgsql-start
@@ -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.
+
+# Start postgresql
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+
+pgsql_prefix=`cat $here/pgsql.prefix`
+mkdir -p $root/sqldb
+mkdir -p $root/logs
+if [ ! -f $root/sqldb/postgresql.conf ]; then
+ $pgsql_prefix/bin/pg_ctl init -D $root/sqldb 1>/dev/null 2>&1
+ createdb="true"
+fi
+
+$pgsql_prefix/bin/pg_ctl start -D $root/sqldb -l $root/logs/postgresql 1>/dev/null 2>&1
+sleep 2
+if [ "$createdb" = "true" ]; then
+ $pgsql_prefix/bin/createdb db 1>/dev/null 2>&1
+fi
+
diff --git a/sca-cpp/branches/gcc-4.4/components/sqldb/pgsql-stop b/sca-cpp/branches/gcc-4.4/components/sqldb/pgsql-stop
new file mode 100755
index 0000000000..d0cda096ba
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/sqldb/pgsql-stop
@@ -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.
+
+# Stop postgresql
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+
+pgsql_prefix=`cat $here/pgsql.prefix`
+mkdir -p $root/sqldb
+mkdir -p $root/logs
+$pgsql_prefix/bin/pg_ctl stop -D $root/sqldb 1>/dev/null 2>&1
+
diff --git a/sca-cpp/branches/gcc-4.4/components/sqldb/pgsql-test.cpp b/sca-cpp/branches/gcc-4.4/components/sqldb/pgsql-test.cpp
new file mode 100644
index 0000000000..7fb6b0c814
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/sqldb/pgsql-test.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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 PostgreSQL access functions.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "perf.hpp"
+#include "pgsql.hpp"
+
+namespace tuscany {
+namespace pgsql {
+
+bool testPGSql() {
+ PGSql pg("dbname=db", "test");
+ const value k = mklist<value>("a");
+
+ assert(hasContent(post(k, string("AAA"), pg)));
+ assert((get(k, pg)) == value(string("AAA")));
+ assert(hasContent(put(k, string("aaa"), pg)));
+ assert((get(k, pg)) == value(string("aaa")));
+ assert(hasContent(del(k, pg)));
+ assert(!hasContent(get(k, pg)));
+
+ return true;
+}
+
+struct getLoop {
+ const value k;
+ PGSql& pg;
+ getLoop(const value& k, PGSql& pg) : k(k), pg(pg) {
+ }
+ const bool operator()() const {
+ assert((get(k, pg)) == value(string("CCC")));
+ return true;
+ }
+};
+
+bool testGetPerf() {
+ const value k = mklist<value>("c");
+ PGSql pg("dbname=db", "test");
+ assert(hasContent(post(k, string("CCC"), pg)));
+
+ const lambda<bool()> gl = getLoop(k, pg);
+ cout << "PGSql get test " << time(gl, 5, 200) << " ms" << endl;
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::pgsql::testPGSql();
+ tuscany::pgsql::testGetPerf();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/sqldb/pgsql.hpp b/sca-cpp/branches/gcc-4.4/components/sqldb/pgsql.hpp
new file mode 100644
index 0000000000..08e8a44123
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/sqldb/pgsql.hpp
@@ -0,0 +1,227 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_pgsql_hpp
+#define tuscany_pgsql_hpp
+
+#include <libpq-fe.h>
+
+#include "string.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "../../modules/scheme/eval.hpp"
+
+namespace tuscany {
+namespace pgsql {
+
+/**
+ * Return and clear a Postgres result failure.
+ */
+const string pgfailure(PGresult* r) {
+ const string e = PQresultErrorMessage(r);
+ PQclear(r);
+ return e;
+}
+
+/**
+ * Represents a PGSql connection.
+ */
+class PGSql {
+public:
+ PGSql() : owner(false) {
+ }
+
+ PGSql(const string& conninfo, const string& table) : owner(true), conninfo(conninfo), table(table) {
+ init();
+ }
+
+ PGSql(const PGSql& c) : owner(false) {
+ conninfo = c.conninfo;
+ conn = c.conn;
+ table = c.table;
+ }
+
+ ~PGSql() {
+ if (!owner)
+ return;
+ PQfinish(conn);
+ }
+
+private:
+ bool owner;
+ PGconn *conn;
+ string conninfo;
+ string table;
+
+ friend const failable<bool> post(const value& key, const value& val, const PGSql& pgsql);
+ friend const failable<bool> put(const value& key, const value& val, const PGSql& pgsql);
+ friend const failable<value> get(const value& key, const PGSql& pgsql);
+ friend const failable<bool> del(const value& key, const PGSql& pgsql);
+
+ /**
+ * Initialize the database connection
+ */
+ const failable<bool> init() {
+ conn = PQconnectdb(c_str(conninfo));
+ if (PQstatus(conn) != CONNECTION_OK)
+ return mkfailure<bool>(string("Could not connect to database: ") + PQerrorMessage(conn));
+
+ // Find the name of the first column in the target table
+ // Assume that's the key we need to use
+ string ks = string("select a.attname from pg_attribute a, pg_class c where a.attrelid = c.relfilenode and c.relname = '") + table + string("' and a.attnum in (1, 2) order by a.attnum;");
+ PGresult* kr = PQexec(conn, c_str(ks));
+ if (PQresultStatus(kr) != PGRES_TUPLES_OK)
+ return mkfailure<bool>(string("Could not execute column select statement: ") + pgfailure(kr));
+ if (PQntuples(kr) != 2) {
+ PQclear(kr);
+ return mkfailure<bool>(string("Could not find table key and value column names"));
+ }
+ const string kname = PQgetvalue(kr, 0, 0);
+ const string vname = PQgetvalue(kr, 1, 0);
+ PQclear(kr);
+
+ // Prepare the post, put, get and delete statements
+ {
+ PGresult* r = PQprepare(conn, "post", c_str(string("insert into ") + table + string(" values($1, $2);")), 2, NULL);
+ if (PQresultStatus(r) != PGRES_COMMAND_OK)
+ return mkfailure<bool>(string("Could not prepare post SQL statement: ") + pgfailure(r));
+ PQclear(r);
+ }
+ {
+ PGresult* r = PQprepare(conn, "put", c_str(string("update ") + table + string(" set ") + vname + string(" = $2 where ") + kname + string(" = $1;")), 2, NULL);
+ if (PQresultStatus(r) != PGRES_COMMAND_OK)
+ return mkfailure<bool>(string("Could not prepare put SQL statement: ") + pgfailure(r));
+ PQclear(r);
+ }
+ {
+ PGresult* r = PQprepare(conn, "get", c_str(string("select * from ") + table + string(" where ") + kname + string(" = $1;")), 1, NULL);
+ if (PQresultStatus(r) != PGRES_COMMAND_OK)
+ return mkfailure<bool>(string("Could not prepare get SQL statement: ") + pgfailure(r));
+ PQclear(r);
+ }
+ {
+ PGresult* r = PQprepare(conn, "delete", c_str(string("delete from ") + table + string(" where ") + kname + string(" = $1;")), 1, NULL);
+ if (PQresultStatus(r) != PGRES_COMMAND_OK)
+ return mkfailure<bool>(string("Could not prepare delete SQL statement: ") + pgfailure(r));
+ PQclear(r);
+ }
+ return true;
+ }
+};
+
+/**
+ * Post a new item to the database.
+ */
+const failable<bool> post(const value& key, const value& val, const PGSql& pgsql) {
+ debug(key, "pgsql::post::key");
+ debug(val, "pgsql::post::value");
+ debug(pgsql.table, "pgsql::post::table");
+
+ const string ks(scheme::writeValue(key));
+ const string vs(scheme::writeValue(val));
+ const char* params[2] = { c_str(ks), c_str(vs) };
+ PGresult* r = PQexecPrepared(pgsql.conn, "post", 2, params, NULL, NULL, 0);
+ if (PQresultStatus(r) != PGRES_COMMAND_OK)
+ return mkfailure<bool>(string("Could not execute post SQL statement: ") + pgfailure(r));
+ PQclear(r);
+
+ debug(true, "pgsql::post::result");
+ return true;
+}
+
+/**
+ * Update an item in the database. If the item doesn't exist it is added.
+ */
+const failable<bool> put(const value& key, const value& val, const PGSql& pgsql) {
+ debug(key, "pgsql::put::key");
+ debug(val, "pgsql::put::value");
+ debug(pgsql.table, "pgsql::put::table");
+
+ const string ks(scheme::writeValue(key));
+ const string vs(scheme::writeValue(val));
+ const char* params[2] = { c_str(ks), c_str(vs) };
+ PGresult* r = PQexecPrepared(pgsql.conn, "put", 2, params, NULL, NULL, 0);
+ if (PQresultStatus(r) != PGRES_COMMAND_OK)
+ return mkfailure<bool>(string("Could not execute put SQL statement: ") + pgfailure(r));
+ const string t = PQcmdTuples(r);
+ if (t != "0") {
+ PQclear(r);
+ debug(true, "pgsql::put::result");
+ return true;
+ }
+ PQclear(r);
+
+ PGresult* pr = PQexecPrepared(pgsql.conn, "post", 2, params, NULL, NULL, 0);
+ if (PQresultStatus(pr) != PGRES_COMMAND_OK)
+ return mkfailure<bool>(string("Could not execute post SQL statement: ") + pgfailure(pr));
+ PQclear(pr);
+
+ debug(true, "pgsql::put::result");
+ return true;
+}
+
+/**
+ * Get an item from the database.
+ */
+const failable<value> get(const value& key, const PGSql& pgsql) {
+ debug(key, "pgsql::get::key");
+ debug(pgsql.table, "pgsql::get::table");
+
+ const string ks(scheme::writeValue(key));
+ const char* params[1] = { c_str(ks) };
+ PGresult* r = PQexecPrepared(pgsql.conn, "get", 1, params, NULL, NULL, 0);
+ if (PQresultStatus(r) != PGRES_TUPLES_OK)
+ return mkfailure<value>(string("Could not execute get SQL statement: ") + pgfailure(r));
+ if (PQntuples(r) < 1) {
+ PQclear(r);
+ return mkfailure<value>(string("Could not get entry: ") + PQerrorMessage(pgsql.conn));
+ }
+ const char* data = PQgetvalue(r, 0, 1);
+ const value val(scheme::readValue(string(data)));
+ PQclear(r);
+
+ debug(val, "pgsql::get::result");
+ return val;
+}
+
+/**
+ * Delete an item from the database
+ */
+const failable<bool> del(const value& key, const PGSql& pgsql) {
+ debug(key, "pgsql::delete::key");
+ debug(pgsql.table, "pgsql::delete::table");
+
+ const string ks(scheme::writeValue(key));
+ const char* params[1] = { c_str(ks) };
+ PGresult* r = PQexecPrepared(pgsql.conn, "delete", 1, params, NULL, NULL, 0);
+ if (PQresultStatus(r) != PGRES_COMMAND_OK)
+ return mkfailure<bool>(string("Could not execute delete SQL statement: ") + pgfailure(r));
+ PQclear(r);
+
+ debug(true, "pgsql::delete::result");
+ return true;
+}
+
+}
+}
+
+#endif /* tuscany_pgsql_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/components/sqldb/server-test b/sca-cpp/branches/gcc-4.4/components/sqldb/server-test
new file mode 100755
index 0000000000..784c7156c5
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/sqldb/server-test
@@ -0,0 +1,43 @@
+#!/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
+../../modules/http/httpd-conf tmp localhost 8090 ../../modules/http/htdocs
+../../modules/server/server-conf tmp
+../../modules/server/scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+SCAContribution `pwd`/
+SCAComposite sqldb.composite
+EOF
+
+./pgsql-start tmp
+./pgsql "drop table test;" 1>/dev/null 2>&1
+./pgsql "create table test(key text, value text);" 1>/dev/null 2>&1
+../../modules/http/httpd-start tmp
+sleep 2
+
+# Test
+./client-test 2>/dev/null
+rc=$?
+
+# Cleanup
+../../modules/http/httpd-stop tmp
+./pgsql-stop tmp
+sleep 2
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/components/sqldb/sqldb-test b/sca-cpp/branches/gcc-4.4/components/sqldb/sqldb-test
new file mode 100755
index 0000000000..05fe413d50
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/sqldb/sqldb-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
+./pgsql-start tmp
+./pgsql "drop table test;" 1>/dev/null 2>&1
+./pgsql "create table test(key text, value text);" 1>/dev/null 2>&1
+
+# Test
+./pgsql-test 2>/dev/null
+rc=$?
+
+# Cleanup
+./pgsql-stop tmp
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/components/sqldb/sqldb.composite b/sca-cpp/branches/gcc-4.4/components/sqldb/sqldb.composite
new file mode 100644
index 0000000000..9675340b0c
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/sqldb/sqldb.composite
@@ -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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/components"
+ name="sqldb">
+
+ <component name="sqldb">
+ <implementation.cpp path=".libs" library="libsqldb"/>
+ <property name="conninfo">dbname=db</property>
+ <property name="table">test</property>
+ <service name="sqldb">
+ <t:binding.http uri="sqldb"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/components/sqldb/sqldb.cpp b/sca-cpp/branches/gcc-4.4/components/sqldb/sqldb.cpp
new file mode 100644
index 0000000000..e84a732511
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/sqldb/sqldb.cpp
@@ -0,0 +1,135 @@
+/*
+ * 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$ */
+
+/**
+ * PostgreSQL-based database component implementation.
+ */
+
+#include <apr_uuid.h>
+
+#include "string.hpp"
+
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "pgsql.hpp"
+
+namespace tuscany {
+namespace sqldb {
+
+/**
+ * Get an item from the database.
+ */
+const failable<value> get(const list<value>& params, pgsql::PGSql& pg) {
+ return pgsql::get(car(params), pg);
+}
+
+/**
+ * Post an item to the database.
+ */
+const value uuidValue() {
+ apr_uuid_t uuid;
+ apr_uuid_get(&uuid);
+ char buf[APR_UUID_FORMATTED_LENGTH];
+ apr_uuid_format(buf, &uuid);
+ return value(string(buf, APR_UUID_FORMATTED_LENGTH));
+}
+
+const failable<value> post(const list<value>& params, pgsql::PGSql& pg) {
+ const value id = append<value>(car(params), mklist(uuidValue()));
+ const failable<bool> val = pgsql::post(id, cadr(params), pg);
+ if (!hasContent(val))
+ return mkfailure<value>(reason(val));
+ return id;
+}
+
+/**
+ * Put an item into the database.
+ */
+const failable<value> put(const list<value>& params, pgsql::PGSql& pg) {
+ const failable<bool> val = pgsql::put(car(params), cadr(params), pg);
+ if (!hasContent(val))
+ return mkfailure<value>(reason(val));
+ return value(content(val));
+}
+
+/**
+ * Delete an item from the database.
+ */
+const failable<value> del(const list<value>& params, pgsql::PGSql& pg) {
+ const failable<bool> val = pgsql::del(car(params), pg);
+ if (!hasContent(val))
+ return mkfailure<value>(reason(val));
+ return value(content(val));
+}
+
+/**
+ * Component implementation lambda function.
+ */
+class applySqldb {
+public:
+ applySqldb(pgsql::PGSql& pg) : pg(pg) {
+ }
+
+ const value operator()(const list<value>& params) const {
+ const value func(car(params));
+ if (func == "get")
+ return get(cdr(params), pg);
+ if (func == "post")
+ return post(cdr(params), pg);
+ if (func == "put")
+ return put(cdr(params), pg);
+ if (func == "delete")
+ return del(cdr(params), pg);
+ return tuscany::mkfailure<tuscany::value>();
+ }
+
+private:
+ pgsql::PGSql& pg;
+};
+
+/**
+ * Start the component.
+ */
+const failable<value> start(unused const list<value>& params) {
+ // Connect to the configured database and table
+ const value conninfo = ((lambda<value(list<value>)>)car(params))(list<value>());
+ const value table = ((lambda<value(list<value>)>)cadr(params))(list<value>());
+ pgsql::PGSql& pg = *(new (gc_new<pgsql::PGSql>()) pgsql::PGSql(conninfo, table));
+
+ // Return the component implementation lambda function
+ return value(lambda<value(const list<value>&)>(applySqldb(pg)));
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+ const tuscany::value func(car(params));
+ if (func == "start")
+ return tuscany::sqldb::start(cdr(params));
+ return tuscany::mkfailure<tuscany::value>();
+}
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/store/Makefile.am b/sca-cpp/branches/gcc-4.4/components/store/Makefile.am
new file mode 100644
index 0000000000..f372faf8a2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/store/Makefile.am
@@ -0,0 +1,20 @@
+# 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_NOSQLDB
+
+endif
diff --git a/sca-cpp/branches/gcc-4.4/components/store/store.composite b/sca-cpp/branches/gcc-4.4/components/store/store.composite
new file mode 100644
index 0000000000..ccfd61fc4d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/store/store.composite
@@ -0,0 +1,32 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/components"
+ name="store">
+
+ <component name="store">
+ <implementation.cpp path=".libs" library="libstore"/>
+ <service name="store">
+ <t:binding.http uri="store"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/Makefile.am b/sca-cpp/branches/gcc-4.4/components/webservice/Makefile.am
new file mode 100644
index 0000000000..1f4ece7003
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/Makefile.am
@@ -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 WANT_WEBSERVICE
+
+INCLUDES = -I${AXIS2C_INCLUDE}
+
+comp_DATA = axis2c.prefix
+compdir=$(prefix)/components/webservice
+axis2c.prefix: $(top_builddir)/config.status
+ echo ${AXIS2C_PREFIX} >axis2c.prefix
+
+comp_LTLIBRARIES = libwebservice-client.la libwebservice-listener.la libaxis2-dispatcher.la libaxis2-service.la
+
+libwebservice_client_la_SOURCES = webservice-client.cpp
+libwebservice_client_la_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine -laxis2_axiom -laxutil
+
+libwebservice_listener_la_SOURCES = webservice-listener.cpp
+libwebservice_listener_la_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine -laxis2_axiom -laxutil
+
+libaxis2_dispatcher_la_SOURCES = axis2-dispatcher.cpp
+libaxis2_dispatcher_la_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine -laxis2_axiom -laxutil
+
+libaxis2_service_la_SOURCES = axis2-service.cpp
+libaxis2_service_la_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine -laxis2_axiom -laxutil
+
+axiom_test_SOURCES = axiom-test.cpp
+axiom_test_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine -laxis2_axiom -laxutil
+
+axis2_test_SOURCES = axis2-test.cpp
+axis2_test_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine -laxis2_axiom -laxutil
+
+client_test_SOURCES = client-test.cpp
+client_test_LDFLAGS = -lxml2 -lcurl -lmozjs -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine -laxis2_axiom -laxutil
+
+noinst_PROGRAMS = axiom-test axis2-test client-test
+TESTS = axiom-test echo-test server-test
+
+endif
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/axiom-test.cpp b/sca-cpp/branches/gcc-4.4/components/webservice/axiom-test.cpp
new file mode 100644
index 0000000000..a3ab8e7e8f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/axiom-test.cpp
@@ -0,0 +1,85 @@
+/*
+ * 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 Web service Axiom support functions.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "list.hpp"
+#include "element.hpp"
+#include "monad.hpp"
+#include "value.hpp"
+#include "perf.hpp"
+#include "axis2.hpp"
+
+namespace tuscany {
+namespace webservice {
+
+const string customerElement =
+"<customer>"
+"<name>jdoe</name>"
+"<address><city>san francisco</city><state>ca</state></address>"
+"<account><id>1234</id><balance>1000</balance></account>"
+"<account><id>6789</id><balance>2000</balance></account>"
+"<account><id>4567</id><balance>3000</balance></account>"
+"</customer>";
+
+bool testAxiom() {
+ const Axis2Context ax;
+ {
+ const failable<axiom_node_t*> n = stringToAxiomNode(customerElement, ax);
+ assert(hasContent(n));
+ const failable<const string> c = axiomNodeToString(content(n), ax);
+ assert(hasContent(c));
+ assert(content(c) == customerElement);
+ }
+ {
+ const list<value> arg = mklist<value>(
+ list<value>() + "ns1:echoString"
+ + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo"))
+ + (list<value>() + "text" + string("Hello World!")));
+ const failable<axiom_node_t*> n = valuesToAxiomNode(arg, ax);
+ assert(hasContent(n));
+ const failable<const string> x = axiomNodeToString(content(n), ax);
+ assert(hasContent(x));
+ assert(content(x) == "<ns1:echoString xmlns:ns1=\"http://ws.apache.org/axis2/services/echo\"><text>Hello World!</text></ns1:echoString>");
+ const failable<const list<value> > l = axiomNodeToValues(content(n), ax);
+ assert(hasContent(l));
+ assert(l == arg);
+ }
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::webservice::testAxiom();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/axis2-conf b/sca-cpp/branches/gcc-4.4/components/webservice/axis2-conf
new file mode 100755
index 0000000000..c731733662
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/axis2-conf
@@ -0,0 +1,55 @@
+#!/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.
+
+# Generate an Axis2 server conf
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+axis2_prefix=`cat axis2c.prefix`
+
+# Create an Axis2 home directory
+mkdir -p $root/axis2c
+ln -f -s $axis2_prefix/lib $root/axis2c/lib
+mkdir -p $root/axis2c/logs
+mkdir -p $root/axis2c/modules
+ln -f -s $axis2_prefix/modules/addressing $root/axis2c/modules/addressing
+ln -f -s $axis2_prefix/modules/logging $root/axis2c/modules/logging
+mkdir -p $root/axis2c/services
+
+# Install Tuscany Axis2 module and service
+mkdir -p $root/axis2c/modules/tuscany
+ln -f -s $here/.libs/libaxis2-dispatcher.so $root/axis2c/modules/tuscany/libaxis2-dispatcher.so
+ln -f -s $here/module.xml $root/axis2c/modules/tuscany/module.xml
+mkdir -p $root/axis2c/services/tuscany
+ln -f -s $here/.libs/libaxis2-service.so $root/axis2c/services/tuscany/libaxis2-service.so
+ln -f -s $here/services.xml $root/axis2c/services/tuscany/services.xml
+cp $here/axis2.xml $root/axis2c/axis2.xml
+
+# Configure HTTPD Axis2 module
+cat >>$root/conf/httpd.conf <<EOF
+# Support for Web Services
+SCASetEnv AXIS2C_HOME $root/axis2c
+LoadModule axis2_module $root/axis2c/lib/libmod_axis2.so
+Axis2RepoPath $root/axis2c
+Axis2LogFile $root/axis2c/logs/mod_axis2.log
+Axis2LogLevel debug
+<Location /axis2>
+ SetHandler axis2_module
+</Location>
+
+EOF
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/axis2-dispatcher.cpp b/sca-cpp/branches/gcc-4.4/components/webservice/axis2-dispatcher.cpp
new file mode 100644
index 0000000000..3f753e0e35
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/axis2-dispatcher.cpp
@@ -0,0 +1,138 @@
+/*
+ * 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$ */
+
+/**
+ * Axis2/C module that dispatches all server requests to the Tuscany Axis/2C service.
+ */
+
+#include "axis2.hpp"
+
+namespace tuscany {
+namespace webservice {
+
+/**
+ * Determine the service and operation to dispatch a request to.
+ */
+axis2_svc_t* AXIS2_CALL dispatchFindService(axis2_msg_ctx_t* msg_ctx, const axutil_env_t* env) {
+ const axis2_conf_ctx_t* conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ const axis2_conf_t* conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ axis2_svc_t* svc = axis2_conf_get_svc(conf, env, "TuscanyService");
+ return svc;
+}
+
+axis2_op_t *AXIS2_CALL dispatchFindOp(unused axis2_msg_ctx_t* msg_ctx, const axutil_env_t* env, axis2_svc_t* svc) {
+ axutil_qname_t* op_qname = axutil_qname_create(env, "execute", NULL, NULL);
+ axis2_op_t *op = axis2_svc_get_op_with_name(svc, env, axutil_qname_get_localpart(op_qname, env));
+ axutil_qname_free(op_qname, env);
+ return op;
+}
+
+/**
+ * Dispatcher invoke function, called by Axis2/C.
+ */
+axis2_status_t AXIS2_CALL dispatchInvoke( struct axis2_handler* handler, const axutil_env_t* env, axis2_msg_ctx_t* msg_ctx) {
+ if (!(axis2_msg_ctx_get_server_side(msg_ctx, env)))
+ return AXIS2_SUCCESS;
+ axis2_msg_ctx_set_find_svc(msg_ctx, env, dispatchFindService);
+ axis2_msg_ctx_set_find_op(msg_ctx, env, dispatchFindOp);
+ return axis2_disp_find_svc_and_op(handler, env, msg_ctx);
+}
+
+/**
+ * Create a dispatch handler.
+ */
+AXIS2_EXPORT axis2_handler_t* AXIS2_CALL dispatchHandler(const axutil_env_t* env, unused axutil_string_t* name) {
+ axis2_handler_t *handler = axis2_handler_create(env);
+ if (handler == NULL)
+ return NULL;
+ axis2_handler_set_invoke(handler, env, dispatchInvoke);
+ return handler;
+}
+
+/**
+ * Initialize dispatch module.
+ */
+axis2_status_t AXIS2_CALL dispatchInit(unused axis2_module_t * module, unused const axutil_env_t * env, unused axis2_conf_ctx_t * conf_ctx, unused axis2_module_desc_t * module_desc) {
+ return AXIS2_SUCCESS;
+}
+
+/**
+ * Initialize dispatch module function map.
+ */
+axis2_status_t AXIS2_CALL dispatchFuncMap(axis2_module_t * module, const axutil_env_t * env) {
+ module->handler_create_func_map = axutil_hash_make(env);
+ axutil_hash_set(module->handler_create_func_map, "TuscanyDispatcher", AXIS2_HASH_KEY_STRING, (const void *)dispatchHandler);
+ return AXIS2_SUCCESS;
+}
+
+/**
+ * Shutdown dispatch module.
+ */
+axis2_status_t AXIS2_CALL dispatchShutdown(axis2_module_t* module, const axutil_env_t* env) {
+ if (module->handler_create_func_map != NULL) {
+ axutil_hash_free(module->handler_create_func_map, env);
+ module->handler_create_func_map = NULL;
+ }
+ AXIS2_FREE(env->allocator, module);
+ return AXIS2_SUCCESS;
+}
+
+/**
+ * Return a new dispatch module.
+ */
+const axis2_module_ops_t dispatchOps = {
+ dispatchInit,
+ dispatchShutdown,
+ dispatchFuncMap
+};
+
+axis2_module_t * dispatchModule(const axutil_env_t* env) {
+ axis2_module_t *module = (axis2_module_t*)AXIS2_MALLOC(env->allocator, sizeof(axis2_module_t));
+ if (module == NULL)
+ return NULL;
+ module->ops = &dispatchOps;
+ module->handler_create_func_map = NULL;
+ return module;
+}
+
+}
+}
+
+extern "C"
+{
+
+/**
+ * Axis2/C module entry point functions.
+ */
+AXIS2_EXPORT int axis2_get_instance(axis2_module_t** inst, const axutil_env_t* env) {
+ *inst = tuscany::webservice::dispatchModule(env);
+ if(*inst == NULL)
+ return AXIS2_FAILURE;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXPORT int axis2_remove_instance(axis2_module_t* inst, const axutil_env_t* env) {
+ if (inst != NULL)
+ return tuscany::webservice::dispatchShutdown(inst, env);
+ return AXIS2_FAILURE;
+}
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/axis2-service.cpp b/sca-cpp/branches/gcc-4.4/components/webservice/axis2-service.cpp
new file mode 100644
index 0000000000..4c0ce22722
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/axis2-service.cpp
@@ -0,0 +1,151 @@
+/*
+ * 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$ */
+
+/**
+ * Axis2/C service implementation that dispatches requests to SCA Web service components.
+ */
+
+#include "value.hpp"
+#include "string.hpp"
+#include "../../modules/http/httpd.hpp"
+#include "axis2.hpp"
+
+namespace tuscany {
+namespace webservice {
+
+/**
+ * Initialize the service.
+ */
+int AXIS2_CALL serviceInit(unused axis2_svc_skeleton_t* svc_skeleton, unused const axutil_env_t* env) {
+ return AXIS2_SUCCESS;
+}
+
+/**
+ * Free the service.
+ */
+int AXIS2_CALL serviceFree(axis2_svc_skeleton_t* svc_skeleton, const axutil_env_t* env) {
+ if (svc_skeleton)
+ AXIS2_FREE(env->allocator, svc_skeleton);
+ return AXIS2_SUCCESS;
+}
+
+typedef struct axis2_apache2_out_transport_info {
+ axis2_http_out_transport_info_t out_transport_info;
+ request_rec *request;
+ axis2_char_t *encoding;
+} axis2_apache2_out_transport_info_t;
+
+extern "C" {
+ extern module axis2_module;
+}
+
+/**
+ * Service invoke function, called by Axis2/C.
+ */
+axiom_node_t *AXIS2_CALL serviceInvoke(unused axis2_svc_skeleton_t* svc_skeleton, const axutil_env_t* env, axiom_node_t* node, axis2_msg_ctx_t* msg_ctx) {
+
+ // Check that we have an input node
+ if (node == NULL || axiom_node_get_node_type(node, env) != AXIOM_ELEMENT)
+ return NULL;
+ axiom_element_t *e = (axiom_element_t *) axiom_node_get_data_element(node, env);
+ if (e == NULL)
+ return NULL;
+
+ // Get the function name
+ const char* func = axiom_element_get_localname(e, env);
+ if (func == NULL)
+ return NULL;
+
+ // Get the target endpoint address
+ const axis2_endpoint_ref_t* epr = axis2_msg_ctx_get_from(msg_ctx, env);
+ if (epr == NULL)
+ return NULL;
+ string address = axis2_endpoint_ref_get_address(epr, env);
+
+ // Get the underlying HTTPD request
+ axis2_out_transport_info_t* tinfo = axis2_msg_ctx_get_out_transport_info(msg_ctx, env);
+ axis2_apache2_out_transport_info_t* httpinfo = (axis2_apache2_out_transport_info_t*)tinfo;
+ request_rec* r = httpinfo->request;
+ httpdDebugRequest(r, "webservice::serviceInvoke");
+
+ // Parse the request Axiom node and construct request expression
+ Axis2Context ax(env);
+ const failable<const list<value> > lv = axiomNodeToValues(node, ax);
+ if (!hasContent(lv))
+ return NULL;
+ const value expr = mklist<value>(func, content(lv));
+ debug(expr, "webservice::serviceInvoke::expr");
+
+ // Retrieve the target lambda function from the HTTPD request and invoke it
+ const value* rv = const_cast<const value*>((value*)ap_get_module_config(r->request_config, &axis2_module));
+ cout << "relay: " << rv << endl;
+ const lambda<value(const list<value>&)> relay = *rv;
+ const value res = relay(expr);
+ debug(res, "webservice::serviceInvoke::result");
+
+ // Construct response Axiom node
+ const failable<axiom_node_t*> rnode = valuesToAxiomNode(res, ax);
+ if (!hasContent(rnode))
+ return NULL;
+ return content(rnode);
+}
+
+/**
+ * Return a new service skeleton.
+ */
+const axis2_svc_skeleton_ops_t serviceOps = {
+ serviceInit,
+ serviceInvoke,
+ NULL,
+ serviceFree,
+ NULL
+};
+
+AXIS2_EXTERN axis2_svc_skeleton_t *AXIS2_CALL serviceSkeleton(const axutil_env_t* env) {
+ axis2_svc_skeleton_t* svc_skeleton = (axis2_svc_skeleton_t*)AXIS2_MALLOC(env->allocator, sizeof(axis2_svc_skeleton_t));
+ svc_skeleton->ops = &serviceOps;
+ svc_skeleton->func_array = NULL;
+ return svc_skeleton;
+}
+
+}
+}
+
+extern "C"
+{
+
+/**
+ * Axis2/C service entry point functions.
+ */
+AXIS2_EXPORT int axis2_get_instance(struct axis2_svc_skeleton** inst, const axutil_env_t* env) {
+ *inst = tuscany::webservice::serviceSkeleton(env);
+ if (inst == NULL)
+ return AXIS2_FAILURE;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXPORT int axis2_remove_instance(axis2_svc_skeleton_t* inst, const axutil_env_t* env) {
+ if (inst != NULL)
+ return AXIS2_SVC_SKELETON_FREE(inst, env);
+ return AXIS2_FAILURE;
+}
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/axis2-test.cpp b/sca-cpp/branches/gcc-4.4/components/webservice/axis2-test.cpp
new file mode 100644
index 0000000000..d7c2f3b671
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/axis2-test.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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 WebService Axis2 client support functions.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "list.hpp"
+#include "element.hpp"
+#include "monad.hpp"
+#include "value.hpp"
+#include "perf.hpp"
+#include "axis2.hpp"
+
+namespace tuscany {
+namespace webservice {
+
+bool testEval() {
+ const Axis2Context ax;
+
+ const value func = "http://ws.apache.org/axis2/c/samples/echoString";
+ const list<value> arg = mklist<value>(
+ list<value>() + "ns1:echoString"
+ + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo"))
+ + (list<value>() + "text" + string("Hello World!")));
+
+ const failable<value> rval = evalExpr(mklist<value>(func, arg, string("http://localhost:9090/axis2/services/echo")), ax);
+ assert(hasContent(rval));
+
+ const list<value> r = mklist<value>(
+ list<value>() + "ns1:echoString"
+ + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/c/samples"))
+ + (list<value>() + "text" + string("Hello World!")));
+ assert(content(rval) == r);
+
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::webservice::testEval();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/axis2.hpp b/sca-cpp/branches/gcc-4.4/components/webservice/axis2.hpp
new file mode 100644
index 0000000000..c2886edb71
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/axis2.hpp
@@ -0,0 +1,194 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_webservice_hpp
+#define tuscany_webservice_hpp
+
+/**
+ * Web service invocation functions using Axis2.
+ */
+#include "config.hpp"
+
+// Ignore redundant declarations in Axiom headers
+#ifdef WANT_MAINTAINER_MODE
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#endif
+#include <axiom.h>
+#include <axis2_client.h>
+#include <axis2_module.h>
+#include <axis2_addr_mod.h>
+#include <axis2_conf_ctx.h>
+#include <axis2_disp.h>
+#include <axis2_http_out_transport_info.h>
+#ifdef WANT_MAINTAINER_MODE
+#pragma GCC diagnostic warning "-Wredundant-decls"
+#endif
+
+#include "string.hpp"
+#include "sstream.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "xml.hpp"
+#include "monad.hpp"
+
+namespace tuscany {
+namespace webservice {
+
+/**
+ * Represents an Axis2 runtime context.
+ */
+class Axis2Context {
+public:
+ Axis2Context() : env(axutil_env_create_all("axis2.log", AXIS2_LOG_LEVEL_WARNING)), owner(true) {
+ }
+
+ Axis2Context(const Axis2Context& ax) : env(ax.env), owner(false) {
+ }
+
+ Axis2Context(const axutil_env_t* env) : env(const_cast<axutil_env_t*>(env)), owner(false) {
+ }
+
+ ~Axis2Context() {
+ if (!owner || env == NULL)
+ return;
+ axutil_env_free(env);
+ }
+
+private:
+ axutil_env_t* env;
+ bool owner;
+
+ friend const axutil_env_t* env(const Axis2Context& ax);
+};
+
+const axutil_env_t* env(const Axis2Context& ax) {
+ return ax.env;
+}
+
+/**
+ * Return the latest Axis2 error in an Axis2 context.
+ */
+const string axis2Error(const Axis2Context& ax) {
+ ostringstream os;
+ os << env(ax)->error->error_number << " : " << AXIS2_ERROR_GET_MESSAGE(env(ax)->error);
+ return str(os);
+}
+
+/**
+ * Convert a string to an Axiom node.
+ */
+const failable<axiom_node_t*> stringToAxiomNode(const string& s, const Axis2Context& ax) {
+ axiom_node_t* node = axiom_node_create_from_buffer(env(ax), const_cast<axis2_char_t*>(c_str(s)));
+ if (node == NULL)
+ return mkfailure<axiom_node_t*>(string("Couldn't convert XML to Axiom node: ") + axis2Error(ax));
+ return node;
+}
+
+/**
+ * Convert a list of values representing XML elements to an Axiom node.
+ */
+const failable<axiom_node_t*> valuesToAxiomNode(const list<value>& l, const Axis2Context& ax) {
+ const failable<list<string> > xml = writeXML(valuesToElements(l), false);
+ if (!hasContent(xml))
+ return mkfailure<axiom_node_t*>(reason(xml));
+ ostringstream os;
+ write(content(xml), os);
+ return stringToAxiomNode(str(os), ax);
+}
+
+/**
+ * Convert an axiom node to a string.
+ */
+const failable<const string> axiomNodeToString(axiom_node_t* node, const Axis2Context& ax) {
+ const char* c = axiom_node_to_string(node, env(ax));
+ if (c == NULL)
+ return mkfailure<const string>(string("Couldn't convert Axiom node to XML: ") + axis2Error(ax));
+ const string s(c);
+ AXIS2_FREE(env(ax)->allocator, const_cast<char*>(c));
+ return s;
+}
+
+/**
+ * Convert an axiom node to a list of values representing XML elements.
+ */
+const failable<const list<value> > axiomNodeToValues(axiom_node_t* node, const Axis2Context& ax) {
+ const failable<const string> s = axiomNodeToString(node, ax);
+ if (!hasContent(s))
+ return mkfailure<const list<value> >(reason(s));
+ istringstream is(content(s));
+ const failable<const list<value> > l = readXML(streamList(is));
+ if (!hasContent(l))
+ return l;
+ return elementsToValues(content(l));
+}
+
+/**
+ * Evaluate an expression in the form (soap-action-string, document, uri). Send the
+ * SOAP action and document to the Web Service at the given URI using Axis2.
+ */
+const failable<value> evalExpr(const value& expr, const Axis2Context& ax) {
+ debug(expr, "webservice::evalExpr::input");
+
+ // Extract func name and single argument
+ const value func(car<value>(expr));
+ const list<value> param(cadr<value>(expr));
+ const value uri(caddr<value>(expr));
+
+ // Create Axis2 client
+ axis2_svc_client_t *client = axis2_svc_client_create(env(ax), getenv("AXIS2C_HOME"));
+ if (client == NULL)
+ return mkfailure<value>("Couldn't create Axis2 client: " + axis2Error(ax));
+ axis2_endpoint_ref_t *epr = axis2_endpoint_ref_create(env(ax), c_str(uri));
+ axis2_options_t *opt = axis2_options_create(env(ax));
+ axis2_options_set_to(opt, env(ax), epr);
+ axis2_options_set_action(opt, env(ax), (const axis2_char_t*)c_str(func));
+ axis2_svc_client_set_options(client, env(ax), opt);
+ axis2_svc_client_engage_module(client, env(ax), AXIS2_MODULE_ADDRESSING);
+
+ // Construct request Axiom node
+ const failable<axiom_node_t*> req = valuesToAxiomNode(param, ax);
+ if (!hasContent(req))
+ return mkfailure<value>(reason(req));
+
+ // Call the Web service
+ axiom_node_t* res = axis2_svc_client_send_receive(client, env(ax), content(req));
+ if (res == NULL) {
+ axis2_svc_client_free(client, env(ax));
+ return mkfailure<value>("Couldn't invoke Axis2 service: " + axis2Error(ax));
+ }
+
+ // Parse result Axiom node
+ const failable<const list<value> > lval = axiomNodeToValues(res, ax);
+ if (!hasContent(lval))
+ return mkfailure<value>(reason(lval));
+ const value rval = content(lval);
+ debug(rval, "webservice::evalExpr::result");
+
+ // Cleanup
+ axis2_svc_client_free(client, env(ax));
+
+ return rval;
+}
+
+}
+}
+
+#endif /* tuscany_webservice_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/axis2.xml b/sca-cpp/branches/gcc-4.4/components/webservice/axis2.xml
new file mode 100644
index 0000000000..ea9b6d2194
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/axis2.xml
@@ -0,0 +1,148 @@
+<!--
+ 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.
+-->
+<axisconfig name="Axis2/C">
+ <!-- ================================================= -->
+ <!-- Parameters -->
+ <!-- ================================================= -->
+ <!-- Uncomment following to enable MTOM support globally -->
+ <!--parameter name="enableMTOM" locked="false">true</parameter-->
+
+ <!-- Set the suitable size for optimum memory usage when sending large attachments -->
+ <!--parameter name="MTOMBufferSize" locked="false">10</parameter-->
+ <!--parameter name="MTOMMaxBuffers" locked="false">1000</parameter-->
+ <!--parameter name="EnableMTOMServiceCallback" locked="false">true</parameter-->
+ <!--parameter name="attachmentDIR" locked="false">/path/to/the/attachment/caching/dir/</parameter-->
+ <!--parameter name="MTOMCachingCallback" locked="false">/path/to/the/caching_callback</parameter-->
+ <!--parameter name="MTOMSendingCallback" locked="false">/path/to/the/sending_callback</parameter-->
+
+ <!-- Enable REST -->
+ <parameter name="enableREST" locked="false">true</parameter>
+
+ <!-- Uncomment following to persist op_ctx, useful with RM -->
+ <!--parameter name="persistOperationContext" locked="false">true</parameter-->
+
+ <!--if you want to extract the service archive file and work with that please uncomment this-->
+ <!--else , it wont extract archive file or does not take into consideration if someone drop-->
+ <!--exploded directory into /service directory-->
+ <!--<parameter name="extractServiceArchive" locked="false">true</parameter>-->
+
+
+ <!-- ================================================= -->
+ <!-- Message Receivers -->
+ <!-- ================================================= -->
+ <!-- This is the Deafult Message Receiver for the Request Response style Operations -->
+ <!--messageReceiver mep="INOUT" class="axis2_receivers"/-->
+
+
+ <!-- ================================================= -->
+ <!-- Transport Ins -->
+ <!-- ================================================= -->
+
+ <transportReceiver name="http" class="axis2_http_receiver">
+ <parameter name="port" locked="false">6060</parameter>
+ <parameter name="exposeHeaders" locked="true">false</parameter>
+ </transportReceiver>
+
+ <!--transportReceiver name="https" class="axis2_http_receiver">
+ <parameter name="port" locked="false">6060</parameter>
+ <parameter name="exposeHeaders" locked="true">false</parameter>
+ </transportReceiver-->
+
+ <!--transportReceiver name="tcp" class="axis2_tcp_receiver">
+ <parameter name="port" locked="false">6060</parameter>
+ </transportReceiver-->
+
+
+ <!-- ================================================= -->
+ <!-- Transport Outs -->
+ <!-- ================================================= -->
+
+ <transportSender name="http" class="axis2_http_sender">
+ <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter>
+ <parameter name="xml-declaration" insert="false"/>
+ <!--parameter name="Transfer-Encoding">chunked</parameter-->
+ <!--parameter name="HTTP-Authentication" username="" password="" locked="true"/-->
+ <!--parameter name="PROXY" proxy_host="127.0.0.1" proxy_port="8080" proxy_username="" proxy_password="" locked="true"/-->
+ </transportSender>
+
+ <!-- Uncomment the following with appropriate parameters to enable the SSL transport sender.
+ Also make sure that the appropriate transport receiver is enabled above.-->
+ <!--transportSender name="https" class="axis2_http_sender">
+ <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter>
+ <parameter name="xml-declaration" insert="false"/>
+ </transportSender>
+ <parameter name="SERVER_CERT">/path/to/ca/certificate</parameter>
+ <parameter name="KEY_FILE">/path/to/client/certificate/chain/file</parameter>
+ <parameter name="SSL_PASSPHRASE">passphrase</parameter>
+ -->
+
+ <!-- Uncomment this one with the appropriate papameters to enable the TCP transport Sender-->
+ <!--transportSender name="tcp" class="axis2_tcp_sender">
+ <parameter name="PROTOCOL" locked="false">TCP</parameter>
+ <parameter name="xml-declaration" insert="false"/>
+ </transportSender-->
+
+
+ <!-- ================================================= -->
+ <!-- Global Modules -->
+ <!-- ================================================= -->
+ <!-- Comment this to disable Addressing -->
+ <module ref="addressing"/>
+
+ <!-- Tuscany dispatcher module -->
+ <module ref="tuscany"/>
+
+ <!--Configuring module , providing paramters for modules whether they refer or not-->
+ <!--<moduleConfig name="addressing">-->
+ <!--<parameter name="addressingPara" locked="false">N/A</parameter>-->
+ <!--</moduleConfig>-->
+
+ <!-- ================================================= -->
+ <!-- Phases -->
+ <!-- ================================================= -->
+ <phaseOrder type="inflow">
+ <!-- System pre defined phases -->
+ <phase name="Transport"/>
+ <phase name="PreDispatch"/>
+ <phase name="Dispatch"/>
+ <phase name="PostDispatch"/>
+ <!--phase name="Security"/-->
+ <!-- End system pre defined phases -->
+ <!-- After PostDispatch phase, module or service author can add any phase as required -->
+ <!-- User defined phases could be added here -->
+ <!--phase name="userphase1"/-->
+ </phaseOrder>
+ <phaseOrder type="outflow">
+ <!-- User defined phases could be added here -->
+ <!--phase name="userphase1"/-->
+ <!--system predefined phase-->
+ <phase name="MessageOut"/>
+ <!--phase name="Security"/-->
+ </phaseOrder>
+ <phaseOrder type="INfaultflow">
+ <!-- User defined phases could be added here -->
+ <!--phase name="userphase1"/-->
+ </phaseOrder>
+ <phaseOrder type="Outfaultflow">
+ <!-- User defined phases could be added here -->
+ <!--phase name="userphase1"/-->
+ <phase name="MessageOut"/>
+ </phaseOrder>
+</axisconfig>
+
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/client-test.cpp b/sca-cpp/branches/gcc-4.4/components/webservice/client-test.cpp
new file mode 100644
index 0000000000..9030a77676
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/client-test.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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 Web service component.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "list.hpp"
+#include "element.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "perf.hpp"
+#include "../../modules/http/curl.hpp"
+#include "axis2.hpp"
+
+namespace tuscany {
+namespace webservice {
+
+
+bool testModAxis2() {
+ const Axis2Context ax;
+
+ const value func = "http://ws.apache.org/axis2/c/samples/echoString";
+ const list<value> arg = mklist<value>(
+ list<value>() + "ns1:echoString"
+ + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo"))
+ + (list<value>() + "text" + string("Hello World!")));
+
+ const failable<value> rval = evalExpr(mklist<value>(func, arg, string("http://localhost:8090/echo-listener")), ax);
+ assert(hasContent(rval));
+
+ const list<value> r = mklist<value>(
+ list<value>() + "ns1:echoString"
+ + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo"))
+ + (list<value>() + "text" + string("Hello World!")));
+ assert(content(rval) == r);
+
+ return true;
+}
+
+bool testEval() {
+ http::CURLSession cs;
+
+ const value func = "http://ws.apache.org/axis2/c/samples/echoString";
+ const list<value> arg = mklist<value>(
+ list<value>() + "ns1:echoString"
+ + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo"))
+ + (list<value>() + "text" + string("Hello World!")));
+
+ const failable<value> rval = http::evalExpr(mklist<value>(func, arg), "http://localhost:8090/echo-client", cs);
+ assert(hasContent(rval));
+
+ const list<value> r = mklist<value>(
+ list<value>() + "ns1:echoString"
+ + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/c/samples"))
+ + (list<value>() + "text" + string("Hello World!")));
+ assert(content(rval) == r);
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::webservice::testModAxis2();
+ tuscany::webservice::testEval();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/echo-test b/sca-cpp/branches/gcc-4.4/components/webservice/echo-test
new file mode 100755
index 0000000000..e5cd1d9a9d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/echo-test
@@ -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.
+
+# Setup
+axis2_prefix=`cat axis2c.prefix`
+export AXIS2C_HOME=$axis2_prefix
+axis2="$axis2_prefix/bin/axis2_http_server"
+pwd=`pwd`
+cd "$axis2_prefix/bin"
+$axis2 &
+cd $pwd
+sleep 1
+
+# Test
+./axis2-test 2>/dev/null
+rc=$?
+
+# Cleanup
+kill `ps -f | grep -v grep | grep "$axis2" | awk '{ print $2 }'`
+sleep 1
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/module.xml b/sca-cpp/branches/gcc-4.4/components/webservice/module.xml
new file mode 100644
index 0000000000..8f6ba5018f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/module.xml
@@ -0,0 +1,25 @@
+<!--
+ 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.
+-->
+<module name="tuscany" class="axis2-dispatcher">
+ <inflow>
+ <handler name="TuscanyDispatcher" class="axis2-dispatcher">
+ <order phase="Dispatch"/>
+ </handler>
+ </inflow>
+</module>
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/server-test b/sca-cpp/branches/gcc-4.4/components/webservice/server-test
new file mode 100755
index 0000000000..34fdb7266a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/server-test
@@ -0,0 +1,49 @@
+#!/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
+../../modules/http/httpd-conf tmp localhost 8090 ../../modules/http/htdocs
+../../modules/server/server-conf tmp
+../../modules/server/scheme-conf tmp
+./axis2-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+SCAContribution `pwd`/
+SCAComposite webservice.composite
+EOF
+
+../../modules/http/httpd-start tmp
+
+axis2_prefix=`cat axis2c.prefix`
+export AXIS2C_HOME=$axis2_prefix
+axis2="$axis2_prefix/bin/axis2_http_server"
+pwd=`pwd`
+cd "$axis2_prefix/bin"
+$axis2 &
+cd $pwd
+sleep 2
+
+# Test
+./client-test 2>/dev/null
+rc=$?
+
+# Cleanup
+kill `ps -f | grep -v grep | grep "${axis2}" | awk '{ print $2 }'`
+../../modules/http/httpd-stop tmp
+sleep 2
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/server-test.scm b/sca-cpp/branches/gcc-4.4/components/webservice/server-test.scm
new file mode 100644
index 0000000000..44e4eee92a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/server-test.scm
@@ -0,0 +1,21 @@
+; 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.
+
+; Web service test case
+
+(define (echoString x) x)
+
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/services.xml b/sca-cpp/branches/gcc-4.4/components/webservice/services.xml
new file mode 100644
index 0000000000..0adf136f4f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/services.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<serviceGroup>
+<service name="TuscanyService">
+ <parameter name="ServiceClass" locked="xsd:false">axis2-service</parameter>
+ <operation name="execute"/>
+</service>
+</serviceGroup>
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/webservice-client.cpp b/sca-cpp/branches/gcc-4.4/components/webservice/webservice-client.cpp
new file mode 100644
index 0000000000..06db6c01b8
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/webservice-client.cpp
@@ -0,0 +1,65 @@
+/*
+ * 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$ */
+
+/**
+ * Web service client component implementation.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "axis2.hpp"
+
+namespace tuscany {
+namespace webservice {
+
+/**
+ * Apply a function provided by a remote Web service using Axis2.
+ */
+const failable<value> apply(const value& func, const list<value>& params) {
+ const Axis2Context ax;
+
+ // Extract parameters
+ const value doc = car<value>(params);
+ const lambda<value(const list<value>&)> l = cadr<value>(params);
+
+ // Call the URI property lambda function to get the configured URI
+ const value uri = l(list<value>());
+
+ // Evaluate using Axis2
+ return evalExpr(mklist<value>(func, doc, uri), ax);
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+ const tuscany::value func(car(params));
+ if (func == "start")
+ return tuscany::mkfailure<tuscany::value>();
+ return tuscany::webservice::apply(func, cdr(params));
+}
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/webservice-listener.cpp b/sca-cpp/branches/gcc-4.4/components/webservice/webservice-listener.cpp
new file mode 100644
index 0000000000..2127ecf0df
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/webservice-listener.cpp
@@ -0,0 +1,86 @@
+/*
+ * 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$ */
+
+/**
+ * Web service listener component implementation.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "../../modules/http/httpd.hpp"
+#include "axis2.hpp"
+
+namespace tuscany {
+namespace webservice {
+
+/**
+ * Redirect an HTTP request to the Axis2/C HTTPD module. The given relay lambda function
+ * is stored in the HTTPD request, for later retrieval by the Axis2 service to relay the request
+ * to a target component.
+ */
+extern "C" {
+ extern module axis2_module;
+}
+
+const value redirectToAxis2(const string& uri, request_rec* r, const value& relay) {
+ const failable<request_rec*, int> nr = httpd::internalRedirectRequest(uri, r);
+ if (!hasContent(nr))
+ return value(reason(nr));
+ ap_set_module_config(content(nr)->request_config, &axis2_module, const_cast<void*>((const void*)&relay));
+ return value(httpd::internalRedirect(content(nr)));
+}
+
+/**
+ * Handle an HTTP request.
+ */
+const failable<value> handle(const list<value>& params) {
+
+ // Extract HTTPD request from the params
+ request_rec* r = httpd::request(car(params));
+ httpdDebugRequest(r, "webservice::handle");
+
+ // Extract the relay lambda from the params and store it in the HTTPD request,
+ // for later retrieval by our Axis2 service
+ const value relay = cadr(params);
+ cout << "relay: " << &relay << endl;
+
+ // Redirect HTTPD request to Mod-axis2
+ if (r->args == NULL)
+ return redirectToAxis2(httpd::redirectURI("/axis2", string(r->uri)), r, relay);
+ return redirectToAxis2(httpd::redirectURI("/axis2", string(r->uri), string(r->args)), r, relay);
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+ const tuscany::value func(car(params));
+ if (func == "handle")
+ return tuscany::webservice::handle(cdr(params));
+ return tuscany::mkfailure<tuscany::value>();
+}
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/components/webservice/webservice.composite b/sca-cpp/branches/gcc-4.4/components/webservice/webservice.composite
new file mode 100644
index 0000000000..6d4055aad3
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/components/webservice/webservice.composite
@@ -0,0 +1,48 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/components"
+ name="webservice-client">
+
+ <component name="webservice-client">
+ <implementation.cpp path=".libs" library="libwebservice-client"/>
+ <property name="uri">http://localhost:9090/axis2/services/echo</property>
+ <service name="webservice-client">
+ <t:binding.jsonrpc uri="echo-client"/>
+ </service>
+ </component>
+
+ <component name="webservice-listener">
+ <implementation.cpp path=".libs" library="libwebservice-listener"/>
+ <service name="webservice-listener">
+ <t:binding.http uri="echo-listener"/>
+ </service>
+ <reference name="relay" target="echo"/>
+ </component>
+
+ <component name="echo">
+ <t:implementation.scheme script="server-test.scm"/>
+ <service name="echo">
+ <t:binding.jsonrpc uri="echo"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/configure.ac b/sca-cpp/branches/gcc-4.4/configure.ac
new file mode 100644
index 0000000000..cb15a820ce
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/configure.ac
@@ -0,0 +1,712 @@
+# 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.
+
+dnl run autogen.sh to generate the configure script.
+
+AC_PREREQ(2.59)
+AC_INIT(tuscany-sca, 1.0, dev@tuscany.apache.org)
+AC_CONFIG_MACRO_DIR([m4])
+AC_CANONICAL_SYSTEM
+AM_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE([tar-ustar])
+AC_PREFIX_DEFAULT(/usr/local/tuscany/sca)
+
+# Use GCC 4.5 if available
+if test -x "/usr/bin/gcc-4.5"; then
+ CXX=/usr/bin/g++-4.5
+ CPP=/usr/bin/cpp-4.5
+ CC=/usr/bin/gcc-4.5
+fi
+
+# Check for required programs.
+AC_MSG_NOTICE([checking for programs])
+AC_PROG_CXX
+AC_PROG_AWK
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_LIBTOOL
+
+# Check for running on Darwin.
+AC_MSG_CHECKING([if running on Darwin])
+UNAME=`uname -s`
+if test "${UNAME}" = "Darwin"; then
+ AC_DEFINE([IS_DARWIN], 1, [running on Darwin])
+ AC_MSG_RESULT(yes)
+ AC_SUBST([libsuffix],[".dylib"])
+ AM_CONDITIONAL([DARWIN], true)
+else
+ AC_MSG_RESULT(no)
+ AC_SUBST([libsuffix],[".so"])
+ AM_CONDITIONAL([DARWIN], false)
+fi
+
+# Configure path to CURL.
+AC_MSG_CHECKING([for curl])
+AC_ARG_WITH([curl], [AC_HELP_STRING([--with-curl=PATH], [path to installed curl [default=/usr]])], [
+ CURL_PREFIX="${withval}"
+ LIBCURL_INCLUDE="${withval}/include"
+ LIBCURL_LIB="${withval}/lib"
+ AC_MSG_RESULT("${withval}")
+], [
+ CURL_PREFIX="/usr"
+ LIBCURL_INCLUDE="/usr/include"
+ LIBCURL_LIB="/usr/lib"
+ AC_MSG_RESULT(/usr)
+])
+AC_SUBST(CURL_PREFIX)
+AC_SUBST(LIBCURL_INCLUDE)
+AC_SUBST(LIBCURL_LIB)
+
+# Configure path to libxml2 includes and lib.
+AC_MSG_CHECKING([for libxml2])
+AC_ARG_WITH([libxml2], [AC_HELP_STRING([--with-libxml2=PATH], [path to installed libxml2 [default=/usr]])], [
+ LIBXML2_INCLUDE="${withval}/include/libxml2"
+ LIBXML2_LIB="${withval}/lib"
+ AC_MSG_RESULT("${withval}")
+], [
+ LIBXML2_INCLUDE="/usr/include/libxml2"
+ LIBXML2_LIB="/usr/lib"
+ AC_MSG_RESULT(/usr)
+])
+AC_SUBST(LIBXML2_INCLUDE)
+AC_SUBST(LIBXML2_LIB)
+
+# Configure path to libmozjs includes and lib.
+AC_MSG_CHECKING([for js-include])
+xulrunner=`ls /usr/include | grep "xulrunner" | tail -1`
+if test "$xulrunner" = ""; then
+ xulrunner="xulrunner-1.9.1.8"
+fi
+AC_ARG_WITH([js-include], [AC_HELP_STRING([--with-js-include=PATH], [path to installed SpiderMonkey include dir
+ [default=/usr/include/$xulrunner/unstable]])], [
+ JS_INCLUDE="${withval}"
+ AC_MSG_RESULT("${withval}")
+], [
+ JS_INCLUDE="/usr/include/$xulrunner/unstable"
+ AC_MSG_RESULT(/usr/include/$xulrunner/unstable)
+])
+AC_MSG_CHECKING([for js-lib])
+AC_ARG_WITH([js-lib], [AC_HELP_STRING([--with-js-lib=PATH], [path to installed SpiderMonkey lib dir [default=/usr/lib/$xulrunner]])], [
+ JS_LIB="${withval}"
+ AC_MSG_RESULT("${withval}")
+], [
+ JS_LIB="/usr/lib/$xulrunner"
+ AC_MSG_RESULT(/usr/lib/$xulrunner)
+])
+AC_SUBST(JS_INCLUDE)
+AC_SUBST(JS_LIB)
+
+# Configure path to Apache APR and HTTPD includes and libs.
+AC_MSG_CHECKING([for apr])
+AC_ARG_WITH([apr], [AC_HELP_STRING([--with-apr=PATH], [path to installed Apache APR [default=/usr/local/apache2]])], [
+ APR_INCLUDE="${withval}/include"
+ APR_LIB="${withval}/lib"
+ AC_MSG_RESULT("${withval}")
+], [
+ APR_INCLUDE="/usr/local/apache2/include"
+ APR_LIB="/usr/local/apache2/lib"
+ AC_MSG_RESULT(/usr/local/apache2/lib)
+])
+AC_SUBST(APR_INCLUDE)
+AC_SUBST(APR_LIB)
+
+AC_MSG_CHECKING([for httpd])
+AC_ARG_WITH([httpd], [AC_HELP_STRING([--with-httpd=PATH], [path to installed Apache HTTPD [default=/usr/local/apache2]])], [
+ HTTPD_PREFIX="${withval}"
+ HTTPD_INCLUDE="${withval}/include"
+ AC_MSG_RESULT("${withval}")
+], [
+ HTTPD_PREFIX="/usr/local/apache2"
+ HTTPD_INCLUDE="/usr/local/apache2/include"
+ AC_MSG_RESULT(/usr/local/apache2/lib)
+])
+AC_SUBST(HTTPD_PREFIX)
+AC_SUBST(HTTPD_INCLUDE)
+
+# Configure path to memcached.
+AC_MSG_CHECKING([for memcached])
+AC_ARG_WITH([memcached], [AC_HELP_STRING([--with-memcached=PATH], [path to installed memcached [default=/usr]])], [
+ MEMCACHED_PREFIX="${withval}"
+ AC_MSG_RESULT("${withval}")
+], [
+ MEMCACHED_PREFIX="/usr"
+ AC_MSG_RESULT(/usr)
+])
+AC_SUBST(MEMCACHED_PREFIX)
+
+# Configure path to tinycdb.
+AC_MSG_CHECKING([for tinycdb])
+AC_ARG_WITH([tinycdb], [AC_HELP_STRING([--with-tinycdb=PATH], [path to installed tinycdb [default=/usr]])], [
+ TINYCDB_PREFIX="${withval}"
+ TINYCDB_INCLUDE="${withval}/include"
+ TINYCDB_LIB="${withval}/lib"
+ AC_MSG_RESULT("${withval}")
+], [
+ TINYCDB_PREFIX="/usr"
+ TINYCDB_INCLUDE="/usr/include"
+ TINYCDB_LIB="/usr/lib"
+ AC_MSG_RESULT(/usr)
+])
+AC_SUBST(TINYCDB_PREFIX)
+AC_SUBST(TINYCDB_INCLUDE)
+AC_SUBST(TINYCDB_LIB)
+
+# Configure TUSCANY_SCACPP path variable.
+TUSCANY_SCACPP=`echo "${TUSCANY_SCACPP}"`
+if test "${TUSCANY_SCACPP}" = ""; then
+ pwd=`pwd`
+ AC_SUBST([TUSCANY_SCACPP], ["${pwd}"])
+fi
+
+# Initialize default GCC C++ and LD options.
+cxxflags=""
+ldflags="${LDFLAGS}"
+defaultlibs="${LIBS}"
+
+# Configure default includes.
+cxxflags="${cxxflags} ${INCLUDES} -I. -I${TUSCANY_SCACPP}/kernel -I${APR_INCLUDE} -I${LIBXML2_INCLUDE} -I${JS_INCLUDE} -I${LIBCURL_INCLUDE}"
+
+# Check for libraries required by all modules and add them to LD options.
+AC_MSG_NOTICE([checking for required libraries])
+LIBS="-L${APR_LIB} ${defaultlibs}"
+AC_CHECK_LIB([apr-1], [apr_pool_initialize], [AC_MSG_NOTICE([found])], [AC_MSG_ERROR([couldn't find a suitable libapr-1, use --with-apr=PATH])])
+ldflags="${ldflags} -ldl -L${APR_LIB} -R${APR_LIB} -lapr-1 -laprutil-1"
+
+# Check for libraries only required by some modules and add their search path to LD options.
+LIBS="-L${LIBCURL_LIB} ${defaultlibs}"
+AC_CHECK_LIB([curl], [curl_global_init], [], [AC_MSG_ERROR([couldn't find a suitable libcurl, use --with-libcurl=PATH])])
+LIBS="-L${JS_LIB} ${defaultlibs}"
+AC_CHECK_LIB([mozjs], [JS_NewContext], [], [AC_MSG_ERROR([couldn't find a suitable libmozjs, use --with-js-lib=PATH])])
+LIBS="-L${LIBXML2_LIB} ${defaultlibs}"
+AC_CHECK_LIB([xml2], [xmlInitParser], [], [AC_MSG_ERROR([couldn't find a suitable libxml2, use --with-libxml2=PATH])])
+ldflags="${ldflags} -L${LIBCURL_LIB} -R${LIBCURL_LIB} -L${JS_LIB} -R${JS_LIB} -L${LIBXML2_LIB} -R${LIBXML2_LIB}"
+
+# Check for required header files.
+AC_MSG_NOTICE([checking for header files])
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_CHECK_HEADERS([string.h sys/time.h])
+
+# Check for typedefs, structures, and compiler characteristics.
+AC_MSG_NOTICE([checking for typedefs, structures, and compiler characteristics])
+AC_HEADER_STDBOOL
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_SIZE_T
+
+# Check for required library functions.
+AC_MSG_NOTICE([checking for library functions])
+AC_CHECK_FUNCS([gettimeofday select])
+
+# Enable debugging and compile-time warnings.
+AC_MSG_CHECKING([whether to compile with debugging and compile-time warnings])
+AC_ARG_ENABLE(maintainer-mode, [AS_HELP_STRING([--enable-maintainer-mode], [compile with debugging and compile-time warnings [default=no]])],
+[ case "${enableval}" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ want_maintainer_mode=true
+ ;;
+ esac ],
+[ AC_MSG_RESULT(no)])
+if test "${want_maintainer_mode}" = "true"; then
+ cxxflags="${cxxflags} -D_DEBUG -O0 -ggdb -g3 -Werror -Wall -Wextra -Wno-ignored-qualifiers -Winit-self -Wmissing-include-dirs -Wcast-qual -Wcast-align -Wwrite-strings -Wpointer-arith -Wconversion -Waddress -Wlogical-op -Wredundant-decls -std=c++0x -fmessage-length=0"
+ ldflags="${ldflags} -pg"
+ AM_CONDITIONAL([WANT_MAINTAINER_MODE], true)
+ AC_DEFINE([WANT_MAINTAINER_MODE], 1, [compile with debugging and compile-time warnings])
+else
+ cxxflags="${cxxflags} -O3 -std=c++0x -fmessage-length=0"
+ AM_CONDITIONAL([WANT_MAINTAINER_MODE], false)
+fi
+
+# Enable profiling with gprof.
+AC_MSG_CHECKING([whether to compile with profiling])
+AC_ARG_ENABLE(profiling, [AS_HELP_STRING([--enable-profiling], [compile with profiling [default=no]])],
+[ case "${enableval}" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ want_profiling=true
+ ;;
+ esac ],
+[ AC_MSG_RESULT(no)])
+if test "${want_profiling}" = "true"; then
+ cxxflags="${cxxflags} -pg"
+ ldflags="${ldflags} -pg"
+ AM_CONDITIONAL([WANT_PROFILING], true)
+ AC_DEFINE([WANT_PROFILING], 1, [compile with profiling])
+else
+ AM_CONDITIONAL([WANT_PROFILING], false)
+fi
+
+# Enable multi-threading support.
+AC_MSG_CHECKING([whether to compile for multi-threaded execution])
+AC_ARG_ENABLE(threads, [AS_HELP_STRING([--enable-threads], [compile for multi-threaded execution [default=no]])],
+[ case "${enableval}" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ want_threads=true
+ ;;
+ esac ],
+[ AC_MSG_RESULT(no)])
+if test "${want_threads}" = "true"; then
+ AC_CHECK_LIB([pthread], [pthread_create], [], [AC_MSG_ERROR([couldn't find a suitable libpthread])])
+ LIBS="${defaultlibs}"
+ cxxflags="${cxxflags} -D_REENTRANT"
+ ldflags="${ldflags} -lpthread"
+ AM_CONDITIONAL([WANT_THREADS], true)
+ AC_DEFINE([WANT_THREADS], 1, [compile for multi-threaded execution])
+else
+ AM_CONDITIONAL([WANT_THREADS], false)
+fi
+
+# Configure exuberant ctags.
+TAGSFILE="`pwd`/tags"
+AC_SUBST([CTAGSFLAGS], ["${CTAGSFLAGS} --c++-kinds=+p --fields=+iaS --extra=+q --append --tag-relative=yes -f ${TAGSFILE}"])
+
+# Enable Doxygen documentation.
+AC_MSG_CHECKING([whether to build Doxygen documentation])
+AC_ARG_ENABLE(doxygen, [AS_HELP_STRING([--enable-doxygen], [build Doxygen documentation [default=no]])],
+[ case "${enableval}" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ want_doxygen=true
+ ;;
+ esac ],
+[ AC_MSG_RESULT(no)])
+if test "${want_doxygen}" = "true"; then
+ AC_PATH_PROG(DOXYGEN, doxygen, , ${PATH})
+ if test "${DOXYGEN}" = ""; then
+ AC_MSG_ERROR([could not find doxygen])
+ fi
+ AM_CONDITIONAL([WANT_DOXYGEN], true)
+ AC_DEFINE([WANT_DOXYGEN], 1, [build Doxygen documentation])
+else
+ AM_CONDITIONAL([WANT_DOXYGEN], false)
+fi
+
+# Configure path to Python 2.6 includes and lib.
+AC_MSG_CHECKING([for python])
+AC_ARG_WITH([python], [AC_HELP_STRING([--with-python=PATH], [path to installed Python 2.6 [default=/usr]])], [
+ PYTHON_PREFIX="${withval}"
+ PYTHON_INCLUDE="${withval}/include"
+ PYTHON_LIB="${withval}/lib"
+ AC_MSG_RESULT("${withval}")
+], [
+ PYTHON_PREFIX="/usr"
+ PYTHON_INCLUDE="/usr/include"
+ PYTHON_LIB="/usr/lib"
+ AC_MSG_RESULT(/usr)
+])
+AC_SUBST(PYTHON_PREFIX)
+AC_SUBST(PYTHON_INCLUDE)
+AC_SUBST(PYTHON_LIB)
+
+# Enable Python 2.6 support.
+AC_MSG_CHECKING([whether to enable Python support])
+AC_ARG_ENABLE(python, [AS_HELP_STRING([--enable-python], [enable Python support [default=no]])],
+[ case "${enableval}" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ want_python=true
+ ;;
+ esac ],
+[ AC_MSG_RESULT(no)])
+if test "${want_python}" = "true"; then
+ LIBS="-L${PYTHON_LIB} ${default_LIBS}"
+ AC_CHECK_LIB([python2.6], [Py_Initialize], [], [AC_MSG_ERROR([couldn't find a suitable libpython2.6, use --with-python=PATH])])
+ AM_CONDITIONAL([WANT_PYTHON], true)
+ AC_DEFINE([WANT_PYTHON], 1, [enable Python support])
+else
+ AM_CONDITIONAL([WANT_PYTHON], false)
+fi
+
+# Configure path to Java includes and lib.
+AC_MSG_CHECKING([for java])
+AC_ARG_WITH([java], [AC_HELP_STRING([--with-java=PATH], [path to installed Java [default=/usr/lib/jvm/default-java]])], [
+ JAVA_PREFIX="${withval}"
+ JAVA_INCLUDE="${withval}/include"
+ JAVAC="${withval}/bin/javac"
+ JAR="${withval}/bin/jar"
+ AC_MSG_RESULT("${withval}")
+], [
+ JAVA_PREFIX="/usr/lib/jvm/default-java"
+ JAVA_INCLUDE="/usr/lib/jvm/default-java/include"
+ JAVAC="/usr/lib/jvm/default-java/bin/javac"
+ JAR="/usr/lib/jvm/default-java/bin/jar"
+ AC_MSG_RESULT(/usr/lib/jvm/default-java)
+])
+AC_SUBST(JAVA_PREFIX)
+AC_SUBST(JAVA_INCLUDE)
+AC_SUBST(JAVAC)
+AC_SUBST(JAR)
+
+# Enable Java support.
+AC_MSG_CHECKING([whether to enable Java support])
+AC_ARG_ENABLE(java, [AS_HELP_STRING([--enable-java], [enable Java support [default=no]])],
+[ case "${enableval}" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ want_java=true
+ ;;
+ esac ],
+[ AC_MSG_RESULT(no)])
+if test "${want_java}" = "true"; then
+ # Detect most common Java VMs
+ if test -f "${JAVA_PREFIX}/jre/lib/i386/libjava.so"; then
+ if test -f "${JAVA_PREFIX}/jre/lib/i386/server/libjvm.so"; then
+ # Server VM
+ AC_MSG_NOTICE([checking for server Java VM])
+ JAVA_CHECK_LIB="-L${JAVA_PREFIX}/jre/lib/i386 -R${JAVA_PREFIX}/jre/lib/i386 -L${JAVA_PREFIX}/jre/lib/i386/server -R${JAVA_PREFIX}/jre/lib/i386/server"
+ LIBS="${JAVA_CHECK_LIB} ${default_LIBS}"
+ AC_CHECK_LIB([java], [JNI_CreateJavaVM], [JAVA_LDFLAGS="${JAVA_CHECK_LIB} -ljava -ljvm -lverify"], [], [-ljvm -lverify])
+ if test "${JAVA_LDFLAGS}" != ""; then
+ AC_DEFINE([JAVA_SERVER_VM], 1, [Server Java VM])
+ fi
+ else
+ if test -f "${JAVA_PREFIX}/jre/lib/i386/j9vm/libjvm.so"; then
+ # J9 VM
+ AC_MSG_NOTICE([checking for J9 Java VM])
+ JAVA_CHECK_LIB="-L${JAVA_PREFIX}/jre/lib/i386 -R${JAVA_PREFIX}/jre/lib/i386 -L${JAVA_PREFIX}/jre/lib/i386/j9vm -R${JAVA_PREFIX}/jre/lib/i386/j9vm"
+ LIBS="${JAVA_CHECK_LIB} ${default_LIBS}"
+ AC_CHECK_LIB([java], [JNI_CreateJavaVM], [JAVA_LDFLAGS="${JAVA_CHECK_LIB} -ljava -ljvm -ljsig"], [], [-ljvm -ljsig])
+ if test "${JAVA_LDFLAGS}" != ""; then
+ AC_DEFINE([JAVA_J9_VM], 1, [J9 Java VM])
+ fi
+ fi
+ fi
+ else
+ if test -f "${JAVA_PREFIX}/jre/bin/default/libharmonyvm.so"; then
+ # Apache Harmony VM
+ AC_MSG_NOTICE([checking for Apache Harmony Java VM])
+ JAVA_CHECK_LIB="-L${JAVA_PREFIX}/jre/bin -R${JAVA_PREFIX}/jre/bin -L${JAVA_PREFIX}/jre/bin/default -R${JAVA_PREFIX}/jre/bin/default"
+ LIBS="${JAVA_CHECK_LIB} ${default_LIBS}"
+ AC_CHECK_LIB([harmonyvm], [JNI_CreateJavaVM], [JAVA_LDFLAGS="${JAVA_CHECK_LIB} -lharmonyvm -lhythr -licuuc -lch ${JAVA_PREFIX}/jre/bin/default/libicudata.so.34"], [], [-lhythr -licuuc -lch ${JAVA_PREFIX}/jre/bin/default/libicudata.so.34])
+ if test "${JAVA_LDFLAGS}" != ""; then
+ AC_DEFINE([JAVA_HARMONY_VM], 1, [Apache Harmony Java VM])
+ fi
+ fi
+ fi
+ if test "${JAVA_LDFLAGS}" = ""; then
+ AC_MSG_ERROR([couldn't find a suitable Java JNI library, use --with-java=PATH])
+ fi
+ AC_MSG_CHECKING([for javac])
+ if test -x "${JAVAC}"; then
+ AC_MSG_RESULT("${JAVAC}")
+ else
+ AC_MSG_ERROR([couldn't find a suitable javac tool, use --with-java=PATH])
+ fi
+ AC_MSG_CHECKING([for jar])
+ if test -x "${JAR}"; then
+ AC_MSG_RESULT("${JAR}")
+ else
+ AC_MSG_ERROR([couldn't find a suitable jar tool, use --with-java=PATH])
+ fi
+ AM_CONDITIONAL([WANT_JAVA], true)
+ AC_DEFINE([WANT_JAVA], 1, [enable Java support])
+else
+ AM_CONDITIONAL([WANT_JAVA], false)
+ JAVA_LDFLAGS=""
+fi
+AC_SUBST(JAVA_LDFLAGS)
+
+# Configure path to Google AppEngine SDK.
+AC_MSG_CHECKING([for gae])
+AC_ARG_WITH([gae], [AC_HELP_STRING([--with-gae=PATH], [path to installed Google AppEngine 1.3.2 [default=$HOME/google_appengine]])], [
+ GAE_PREFIX="${withval}"
+ AC_MSG_RESULT("${withval}")
+], [
+ GAE_PREFIX="$HOME/google_appengine"
+ AC_MSG_RESULT($HOME/google_appengine)
+])
+AC_SUBST(GAE_PREFIX)
+
+# Enable support for Google AppEngine.
+AC_MSG_CHECKING([whether to enable Google AppEngine support])
+AC_ARG_ENABLE(gae, [AS_HELP_STRING([--enable-gae], [enable Google AppEngine support [default=no]])],
+[ case "${enableval}" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ want_gae=true
+ ;;
+ esac ],
+[ AC_MSG_RESULT(no)])
+if test "${want_gae}" = "true"; then
+ AM_CONDITIONAL([WANT_GAE], true)
+ AC_DEFINE([WANT_GAE], 1, [enable Google AppEngine support])
+else
+ AM_CONDITIONAL([WANT_GAE], false)
+fi
+
+# Configure path to Java includes and lib.
+# Configure path to Apache Axis2C includes and lib.
+AC_MSG_CHECKING([for axis2c])
+AC_ARG_WITH([axis2c], [AC_HELP_STRING([--with-axis2c=PATH], [path to installed Apache Axis2C [default=/usr/local/axis2c]])], [
+ AXIS2C_PREFIX="${withval}"
+ AXIS2C_INCLUDE="${withval}/include/axis2-1.6.0"
+ AXIS2C_LIB="${withval}/lib"
+ AC_MSG_RESULT("${withval}")
+], [
+ AXIS2C_PREFIX="/usr/local/axis2c"
+ AXIS2C_INCLUDE="/usr/local/axis2c/include/axis2-1.6.0"
+ AXIS2C_LIB="/usr/local/axis2c/lib"
+ AC_MSG_RESULT(/usr/local/axis2c)
+])
+AC_SUBST(AXIS2C_PREFIX)
+AC_SUBST(AXIS2C_INCLUDE)
+AC_SUBST(AXIS2C_LIB)
+
+# Enable Web service component.
+AC_MSG_CHECKING([whether to enable the Web service component])
+AC_ARG_ENABLE(webservice, [AS_HELP_STRING([--enable-webservice], [enable Web service component [default=no]])],
+[ case "${enableval}" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ want_webservice=true
+ ;;
+ esac ],
+[ AC_MSG_RESULT(no)])
+if test "${want_webservice}" = "true"; then
+ LIBS="-L${AXIS2C_LIB} ${default_LIBS}"
+ AC_CHECK_LIB([axis2_engine], [axis2_svc_client_create], [], [AC_MSG_ERROR([couldn't find a suitable libaxis2_engine, use --with-axis2c=PATH])])
+ AM_CONDITIONAL([WANT_WEBSERVICE], true)
+ AC_DEFINE([WANT_WEBSERVICE], 1, [enable Web service component])
+else
+ AM_CONDITIONAL([WANT_WEBSERVICE], false)
+fi
+
+# Enable NoSQL database component.
+AC_MSG_CHECKING([whether to enable the NoSQL database component])
+AC_ARG_ENABLE(nosqldb, [AS_HELP_STRING([--enable-nosqldb], [enable NoSQL database component [default=no]])],
+[ case "${enableval}" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ want_nosqldb=true
+ ;;
+ esac ],
+[ AC_MSG_RESULT(no)])
+if test "${want_nosqldb}" = "true"; then
+ AM_CONDITIONAL([WANT_NOSQLDB], true)
+ AC_DEFINE([WANT_NOSQLDB], 1, [enable NoSQL database component])
+else
+ AM_CONDITIONAL([WANT_NOSQLDB], false)
+fi
+
+# Configure path to PostgreSQL.
+AC_MSG_CHECKING([for pgsql])
+AC_ARG_WITH([pgsql], [AC_HELP_STRING([--with-pgsql=PATH], [path to installed PostgreSQL [default=/usr/local/pgsql]])], [
+ PGSQL_PREFIX="${withval}"
+ PGSQL_INCLUDE="${withval}/include"
+ PGSQL_LIB="${withval}/lib"
+ AC_MSG_RESULT("${withval}")
+], [
+ PGSQL_PREFIX="/usr/local/pgsql"
+ PGSQL_INCLUDE="/usr/local/pgsql/include"
+ PGSQL_LIB="/usr/local/pgsql/lib"
+ AC_MSG_RESULT(/usr/local)
+])
+AC_SUBST(PGSQL_PREFIX)
+AC_SUBST(PGSQL_INCLUDE)
+AC_SUBST(PGSQL_LIB)
+
+# Enable SQL Database component.
+AC_MSG_CHECKING([whether to enable the SQL Database component])
+AC_ARG_ENABLE(sqldb, [AS_HELP_STRING([--enable-sqldb], [enable SQL Database component [default=no]])],
+[ case "${enableval}" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ want_sqldb=true
+ ;;
+ esac ],
+[ AC_MSG_RESULT(no)])
+if test "${want_sqldb}" = "true"; then
+ AM_CONDITIONAL([WANT_SQLDB], true)
+ AC_DEFINE([WANT_SQLDB], 1, [enable SQL Database component])
+else
+ AM_CONDITIONAL([WANT_SQLDB], false)
+fi
+
+# Configure path to Apache Qpid/C++.
+AC_MSG_CHECKING([for qpidc])
+AC_ARG_WITH([qpidc], [AC_HELP_STRING([--with-qpidc=PATH], [path to installed Apache Qpid/C++ [default=/usr/local]])], [
+ QPIDC_PREFIX="${withval}"
+ QPIDC_INCLUDE="${withval}/include"
+ QPIDC_LIB="${withval}/lib"
+ AC_MSG_RESULT("${withval}")
+], [
+ QPIDC_PREFIX="/usr/local"
+ QPIDC_INCLUDE="/usr/local/include"
+ QPIDC_LIB="/usr/local/lib"
+ AC_MSG_RESULT(/usr/local)
+])
+AC_SUBST(QPIDC_PREFIX)
+AC_SUBST(QPIDC_INCLUDE)
+AC_SUBST(QPIDC_LIB)
+
+# Enable Queue component.
+AC_MSG_CHECKING([whether to enable the Queue component])
+AC_ARG_ENABLE(queue, [AS_HELP_STRING([--enable-queue], [enable Queue component [default=no]])],
+[ case "${enableval}" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ want_queue=true
+ ;;
+ esac ],
+[ AC_MSG_RESULT(no)])
+if test "${want_queue}" = "true"; then
+ if test "${want_threads}" != "true"; then
+ AC_MSG_ERROR([--enable-queue requires multi-threading, use --enable-threads])
+ fi
+ LIBS="-L${QPIDC_LIB} ${default_LIBS}"
+ AC_CHECK_LIB([qpidclient], [_init], [], [AC_MSG_ERROR([couldn't find a suitable libqpidclient, use --with-qpidc=PATH])])
+ AM_CONDITIONAL([WANT_QUEUE], true)
+ AC_DEFINE([WANT_QUEUE], 1, [enable Queue component])
+else
+ AM_CONDITIONAL([WANT_QUEUE], false)
+fi
+
+# Configure path to Libstrophe includes and lib.
+AC_MSG_CHECKING([for libstrophe])
+AC_ARG_WITH([libstrophe], [AC_HELP_STRING([--with-libstrophe=PATH], [path to libstrophe [default=${HOME}/libstrophe-bin]])], [
+ LIBSTROPHE_INCLUDE="${withval}/include"
+ LIBSTROPHE_LIB="${withval}/lib"
+ AC_MSG_RESULT("${withval}")
+], [
+ LIBSTROPHE_INCLUDE="${HOME}/libstrophe-bin/include"
+ LIBSTROPHE_LIB="${HOME}/libstrophe-bin/lib"
+ AC_MSG_RESULT(${HOME}/libstrophe-bin)
+])
+AC_SUBST(LIBSTROPHE_INCLUDE)
+AC_SUBST(LIBSTROPHE_LIB)
+
+# Configure path to Vysper
+AC_MSG_CHECKING([for vysper])
+AC_ARG_WITH([vysper], [AC_HELP_STRING([--with-vysper=PATH], [path to Apache Vysper [default=${HOME}/vysper-1.0.0]])], [
+ VYSPER_PREFIX="${withval}"
+ AC_MSG_RESULT("${withval}")
+], [
+ VYSPER_PREFIX="${HOME}/vysper-1.0.0"
+ AC_MSG_RESULT(${HOME}/vysper-1.0.0)
+])
+AC_SUBST(VYSPER_PREFIX)
+
+# Enable Chat component.
+AC_MSG_CHECKING([whether to enable the Chat component])
+AC_ARG_ENABLE(chat, [AS_HELP_STRING([--enable-chat], [enable Chat component [default=no]])],
+[ case "${enableval}" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ want_chat=true
+ ;;
+ esac ],
+[ AC_MSG_RESULT(no)])
+if test "${want_chat}" = "true"; then
+ if test "${want_threads}" != "true"; then
+ AC_MSG_ERROR([--enable-chat requires multi-threading, use --enable-threads])
+ fi
+ LIBS="-L${LIBSTROPHE_LIB} ${default_LIBS}"
+ AC_CHECK_LIB([strophe], [xmpp_initialize], [], [AC_MSG_ERROR([couldn't find a suitable libstrophe, use --with-libstrophe=PATH])], [-lexpat -lssl -lresolv])
+ AM_CONDITIONAL([WANT_CHAT], true)
+ AC_DEFINE([WANT_CHAT], 1, [enable Chat component])
+
+ # Check for Vysper
+ AC_CHECK_FILE([${VYSPER_PREFIX}/lib/vysper-core-0.5.jar], [want_vysper=true], [])
+ if test "${want_vysper}" = "true"; then
+ AM_CONDITIONAL([WANT_VYSPER], true)
+ else
+ AM_CONDITIONAL([WANT_VYSPER], false)
+ fi
+else
+ AM_CONDITIONAL([WANT_CHAT], false)
+ AM_CONDITIONAL([WANT_VYSPER], false)
+fi
+
+# Configure GCC C++ and LD options.
+AC_SUBST([CXXFLAGS], ["${cxxflags}"])
+AC_SUBST([LDFLAGS], ["${ldflags}"])
+LIBS="${defaultlibs}"
+
+AC_CONFIG_FILES([Makefile
+ kernel/Makefile
+ modules/Makefile
+ modules/scheme/Makefile
+ modules/atom/Makefile
+ modules/json/Makefile
+ modules/scdl/Makefile
+ modules/http/Makefile
+ modules/python/Makefile
+ modules/java/Makefile
+ modules/server/Makefile
+ modules/wsgi/Makefile
+ components/Makefile
+ components/cache/Makefile
+ components/log/Makefile
+ components/chat/Makefile
+ components/queue/Makefile
+ components/sqldb/Makefile
+ components/store/Makefile
+ components/webservice/Makefile
+ samples/Makefile
+ test/Makefile
+ test/store-scheme/Makefile
+ test/store-cpp/Makefile
+ test/store-python/Makefile
+ test/store-java/Makefile
+ test/store-gae/Makefile
+ test/store-sql/Makefile
+ doc/Makefile
+ doc/Doxyfile
+ ])
+AC_OUTPUT
+
diff --git a/sca-cpp/branches/gcc-4.4/doc/Doxyfile.in b/sca-cpp/branches/gcc-4.4/doc/Doxyfile.in
new file mode 100644
index 0000000000..ba02d58a2a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/doc/Doxyfile.in
@@ -0,0 +1,1541 @@
+# 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.
+
+# Doxyfile 1.6.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = tuscany-sca
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 1.0-M3
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses.
+# With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this tag.
+# The format is ext=language, where ext is a file extension, and language is one of
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran),
+# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = YES
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penality.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will rougly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = NO
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = YES
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = YES
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
+# doxygen. The layout file controls the global structure of the generated output files
+# in an output format independent way. The create the layout file that represents
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name
+# of the layout file.
+
+LAYOUT_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = ../kernel \
+ ../modules
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = YES
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = doxygen
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
+# are set, an additional index file will be generated that can be used as input for
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
+# HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE =
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.
+# For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP)
+# there is already a search function so this one should typically
+# be disabled.
+
+SEARCHENGINE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
diff --git a/sca-cpp/branches/gcc-4.4/doc/Makefile.am b/sca-cpp/branches/gcc-4.4/doc/Makefile.am
new file mode 100644
index 0000000000..c5f29b0d6b
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/doc/Makefile.am
@@ -0,0 +1,30 @@
+# 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_DOXYGEN
+
+BUILT_SOURCES = doxygen/index.html
+
+doxygen/index.html: Doxyfile
+ doxygen
+
+endif
+
+datadir=$(prefix)/doc
+
+clean:
+ rm -rf doxygen
diff --git a/sca-cpp/branches/gcc-4.4/etc/git-exclude b/sca-cpp/branches/gcc-4.4/etc/git-exclude
new file mode 100644
index 0000000000..3158aa3f4f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/etc/git-exclude
@@ -0,0 +1,99 @@
+# git-ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
+
+# Generic ignores
+target/
+work/
+tmp/
+build/
+*_build
+.project
+.cproject
+.classpath
+*.log
+junit*.properties
+surefire*.properties
+.settings/
+.deployables/
+.wtpmodules/
+.pydevproject
+.buildpath
+.svn/
+.cvs/
+.dotest/
+*.la
+*.lo
+*.o
+*.in
+*.so
+Makefile
+.deps/
+.libs/
+m4/
+*.m4
+config.guess
+config.sub
+config.status
+depcomp
+install-sh
+ltmain.sh
+missing
+stamp-h1
+autom4te.cache/
+deploy/
+libtool
+configure
+config.h
+Doxyfile
+*.tar
+*.tar.gz
+*-bin/
+*-src/
+*_Proxy.cpp
+*_Proxy.h
+*_Wrapper.cpp
+*_Wrapper.h
+gmon.out
+*~
+tags
+doxygen
+*.pyc
+*.class
+*.stamp
+*.jar
+*.prefix
+index.yaml
+core
+
+# Specific ignores
+kernel-test
+string-test
+mem-test
+hash-test
+parallel-test
+xml-test
+xsd-test
+atom-test
+eval-test
+eval-shell
+json-test
+client-test
+memcache-test
+curl-test
+scdl-test
+python-test
+python-shell
+jni-test
+java-test
+java-shell
+script-test
+axiom-test
+axis2-test
+qpid-test
+xmpp-test
+pgsql-test
+
diff --git a/sca-cpp/branches/gcc-4.4/etc/httpd-ipcrm b/sca-cpp/branches/gcc-4.4/etc/httpd-ipcrm
new file mode 100755
index 0000000000..b457e7385f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/etc/httpd-ipcrm
@@ -0,0 +1,23 @@
+#!/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.
+
+# Remove ipcs created by httpd
+
+ipcs -s | grep 0x | awk '{ print $2 }' | xargs -i -t ipcrm -s {}
+
diff --git a/sca-cpp/branches/gcc-4.4/etc/memgrind b/sca-cpp/branches/gcc-4.4/etc/memgrind
new file mode 100755
index 0000000000..1a220cd5d2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/etc/memgrind
@@ -0,0 +1,23 @@
+#!/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 valgrind to analyze memory usage and track memory leaks
+
+valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes $* 2>&1 | tee memgrind.log
+
diff --git a/sca-cpp/branches/gcc-4.4/etc/svn-config b/sca-cpp/branches/gcc-4.4/etc/svn-config
new file mode 100644
index 0000000000..4f8cb41685
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/etc/svn-config
@@ -0,0 +1,136 @@
+### This file configures various client-side behaviors.
+###
+### The commented-out examples below are intended to demonstrate
+### how to use this file.
+
+### Section for authentication and authorization customizations.
+[auth]
+### Set store-passwords to 'no' to avoid storing passwords in the
+### auth/ area of your config directory. It defaults to 'yes'.
+### Note that this option only prevents saving of *new* passwords;
+### it doesn't invalidate existing passwords. (To do that, remove
+### the cache files by hand as described in the Subversion book.)
+# store-passwords = no
+### Set store-auth-creds to 'no' to avoid storing any subversion
+### credentials in the auth/ area of your config directory.
+### It defaults to 'yes'. Note that this option only prevents
+### saving of *new* credentials; it doesn't invalidate existing
+### caches. (To do that, remove the cache files by hand.)
+# store-auth-creds = no
+
+### Section for configuring external helper applications.
+[helpers]
+### Set editor to the command used to invoke your text editor.
+### This will override the environment variables that Subversion
+### examines by default to find this information ($EDITOR,
+### et al).
+# editor-cmd = editor (vi, emacs, notepad, etc.)
+### Set diff-cmd to the absolute path of your 'diff' program.
+### This will override the compile-time default, which is to use
+### Subversion's internal diff implementation.
+# diff-cmd = diff_program (diff, gdiff, etc.)
+### Set diff3-cmd to the absolute path of your 'diff3' program.
+### This will override the compile-time default, which is to use
+### Subversion's internal diff3 implementation.
+# diff3-cmd = diff3_program (diff3, gdiff3, etc.)
+### Set diff3-has-program-arg to 'true' or 'yes' if your 'diff3'
+### program accepts the '--diff-program' option.
+# diff3-has-program-arg = [true | false]
+
+### Section for configuring tunnel agents.
+[tunnels]
+### Configure svn protocol tunnel schemes here. By default, only
+### the 'ssh' scheme is defined. You can define other schemes to
+### be used with 'svn+scheme://hostname/path' URLs. A scheme
+### definition is simply a command, optionally prefixed by an
+### environment variable name which can override the command if it
+### is defined. The command (or environment variable) may contain
+### arguments, using standard shell quoting for arguments with
+### spaces. The command will be invoked as:
+### <command> <hostname> svnserve -t
+### (If the URL includes a username, then the hostname will be
+### passed to the tunnel agent as <user>@<hostname>.) If the
+### built-in ssh scheme were not predefined, it could be defined
+### as:
+# ssh = $SVN_SSH ssh
+### If you wanted to define a new 'rsh' scheme, to be used with
+### 'svn+rsh:' URLs, you could do so as follows:
+# rsh = rsh
+### Or, if you wanted to specify a full path and arguments:
+# rsh = /path/to/rsh -l myusername
+### On Windows, if you are specifying a full path to a command,
+### use a forward slash (/) or a paired backslash (\\) as the
+### path separator. A single backslash will be treated as an
+### escape for the following character.
+
+### Section for configuring miscelleneous Subversion options.
+[miscellany]
+### Set global-ignores to a set of whitespace-delimited globs
+### which Subversion will ignore in its 'status' output.
+# global-ignores = *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store
+### Set log-encoding to the default encoding for log messages
+# log-encoding = latin1
+### Set use-commit-times to make checkout/update/switch/revert
+### put last-committed timestamps on every file touched.
+# use-commit-times = yes
+### Set no-unlock to prevent 'svn commit' from automatically
+### releasing locks on files.
+# no-unlock = yes
+### Set enable-auto-props to 'yes' to enable automatic properties
+### for 'svn add' and 'svn import', it defaults to 'no'.
+### Automatic properties are defined in the section 'auto-props'.
+enable-auto-props = yes
+
+### Section for configuring automatic properties.
+[auto-props]
+### The format of the entries is:
+### file-name-pattern = propname[=value][;propname[=value]...]
+### The file-name-pattern can contain wildcards (such as '*' and
+### '?'). All entries which match will be applied to the file.
+### Note that auto-props functionality must be enabled, which
+### is typically done by setting the 'enable-auto-props' option.
+# *.c = svn:eol-style=native
+# *.cpp = svn:eol-style=native
+# *.h = svn:eol-style=native
+# *.dsp = svn:eol-style=CRLF
+# *.dsw = svn:eol-style=CRLF
+# *.sh = svn:eol-style=native;svn:executable
+# *.txt = svn:eol-style=native
+# *.png = svn:mime-type=image/png
+# *.jpg = svn:mime-type=image/jpeg
+# Makefile = svn:eol-style=native
+
+*.c = svn:eol-style=native;svn:keywords=Rev Date
+*.cpp = svn:eol-style=native;svn:keywords=Rev Date
+*.h = svn:eol-style=native;svn:keywords=Rev Date
+*.dsp = svn:eol-style=CRLF
+*.dsw = svn:eol-style=CRLF
+*.sh = svn:eol-style=native;svn:executable;svn:keywords=Rev Date
+*.bat = svn:eol-style=native;svn:keywords=Rev Date
+*.txt = svn:eol-style=native;svn:keywords=Rev Date
+*.png = svn:mime-type=image/png
+*.jpg = svn:mime-type=image/jpeg
+*.am = svn:eol-style=native;svn:keywords=Rev Date
+*.ac = svn:eol-style=native;svn:keywords=Rev Date
+*.xml = svn:eol-style=native;svn:keywords=Rev Date
+*.xsd = svn:eol-style=native;svn:keywords=Rev Date
+*.html = svn:eol-style=native;svn:keywords=Rev Date
+*.wsdl = svn:eol-style=native;svn:keywords=Rev Date
+*.xsd = svn:eol-style=native;svn:keywords=Rev Date
+*.composite = svn:eol-style=native;svn:keywords=Rev Date
+*.componentType = svn:eol-style=native;svn:keywords=Rev Date
+*.rb = svn:eol-style=native;svn:keywords=Rev Date
+*.py = svn:eol-style=native;svn:keywords=Rev Date
+*.php = svn:eol-style=native;svn:keywords=Rev Date
+*.js = svn:eol-style=native;svn:keywords=Rev Date
+*.java = svn:eol-style=native;svn:keywords=Rev Date
+*.properties = svn:eol-style=native;svn:keywords=Rev Date
+*.jelly = svn:eol-style=native;svn:keywords=Rev Date
+*.ipr = svn:eol-style=native
+*.iml = svn:eol-style=native
+*.project = svn:eol-style=native
+*.classpath = svn:eol-style=native
+README = svn:eol-style=native;svn:keywords=Rev Date
+LICENSE = svn:eol-style=native
+NOTICE = svn:eol-style=native
+
diff --git a/sca-cpp/branches/gcc-4.4/etc/svn-ignore b/sca-cpp/branches/gcc-4.4/etc/svn-ignore
new file mode 100644
index 0000000000..125c009f39
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/etc/svn-ignore
@@ -0,0 +1,55 @@
+configure
+Makefile.in
+depcomp
+config.guess
+config.h
+config.sub
+ltmain.sh
+Makefile
+config.status
+stamp-h1
+config.h.in
+libtool
+autom4te.cache
+missing
+aclocal.m4
+install-sh
+.deps
+*.dat
+.libs
+tmp
+build
+.project
+.cdtproject
+.settings
+*_Proxy.cpp
+*_Proxy.h
+*_Wrapper.cpp
+*_Wrapper.h
+.pydevproject
+.buildpath
+*.lib
+*.dll
+*.exe
+*.suo
+*.ncb
+*.user
+*.pdb
+Debug
+Release
+gmon.out
+m4
+*.tar.gz
+*.pyc
+*.log
+*-bin
+*-src
+Doxyfile
+*~
+tags
+doxygen
+*.stamp
+*.class
+*.jar
+*.prefix
+target
diff --git a/sca-cpp/branches/gcc-4.4/kernel/Makefile.am b/sca-cpp/branches/gcc-4.4/kernel/Makefile.am
new file mode 100644
index 0000000000..f7db7821a3
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/Makefile.am
@@ -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.
+
+
+
+includedir = $(prefix)/include/kernel
+include_HEADERS = *.hpp
+
+string_test_SOURCES = string-test.cpp
+
+test_LTLIBRARIES = libdynlib-test.la
+testdir = $(prefix)/test
+libdynlib_test_la_SOURCES = dynlib-test.cpp
+
+kernel_test_SOURCES = kernel-test.cpp
+
+mem_test_SOURCES = mem-test.cpp
+
+parallel_test_SOURCES = parallel-test.cpp
+
+xml_test_SOURCES = xml-test.cpp
+xml_test_LDFLAGS = -lxml2
+
+xsd_test_SOURCES = xsd-test.cpp
+xsd_test_LDFLAGS = -lxml2
+
+hash_test_SOURCES = hash-test.cpp
+
+noinst_PROGRAMS = string-test kernel-test hash-test mem-test parallel-test xml-test xsd-test
+TESTS = string-test kernel-test hash-test mem-test parallel-test xml-test
+
diff --git a/sca-cpp/branches/gcc-4.4/kernel/config.hpp b/sca-cpp/branches/gcc-4.4/kernel/config.hpp
new file mode 100644
index 0000000000..195612428e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/config.hpp
@@ -0,0 +1,76 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_config_hpp
+#define tuscany_config_hpp
+
+#include "ap_config.h"
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include "../config.h"
+
+/**
+ * Platform configuration and debug functions.
+ */
+
+namespace tuscany
+{
+
+#ifdef WANT_MAINTAINER_MODE
+
+/**
+ * Add string watch members to important classes to help watch them in a debugger.
+ */
+#define WANT_MAINTAINER_WATCH
+
+/**
+ * Increment / decrement a debug counter.
+ */
+bool debug_inc(long int& c) {
+ c++;
+ return true;
+}
+
+bool debug_dec(long int& c) {
+ c--;
+ return true;
+}
+
+#else
+
+#define debug_inc(c)
+#define debug_dec(c)
+
+#endif
+
+/**
+ * Attribute used to mark unused parameters.
+ */
+#ifndef unused
+#define unused __attribute__ ((unused))
+#endif
+
+}
+#endif /* tuscany_config_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/dynlib-test.cpp b/sca-cpp/branches/gcc-4.4/kernel/dynlib-test.cpp
new file mode 100644
index 0000000000..419fa29db5
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/dynlib-test.cpp
@@ -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.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Test library.
+ */
+
+#include "function.hpp"
+
+namespace tuscany {
+namespace test {
+
+ const int cppsquare(int x) {
+ return x * x;
+ }
+
+}
+}
+
+extern "C" {
+
+ const int csquare(const int x) {
+ return tuscany::test::cppsquare(x);
+ }
+
+ const tuscany::lambda<int(const int)> csquarel() {
+ return tuscany::lambda<int(const int)>(tuscany::test::cppsquare);
+ }
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/kernel/dynlib.hpp b/sca-cpp/branches/gcc-4.4/kernel/dynlib.hpp
new file mode 100644
index 0000000000..9f55dc4a49
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/dynlib.hpp
@@ -0,0 +1,91 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_dlib_hpp
+#define tuscany_dlib_hpp
+
+/**
+ * Simple dynamic library access functions.
+ */
+
+#include <dlfcn.h>
+
+#include "function.hpp"
+#include "gc.hpp"
+#include "monad.hpp"
+
+namespace tuscany {
+
+/**
+ * OS specific dynamic library file extension.
+ */
+#ifdef IS_DARWIN
+const string dynlibExt(".dylib");
+#else
+const string dynlibExt(".so");
+#endif
+
+/**
+ * Represents a reference to a dynamic library.
+ */
+class lib {
+public:
+ lib() : h(NULL), owner(false) {
+ }
+
+ lib(const string& name) : name(name), h(dlopen(c_str(name), RTLD_NOW)), owner(true) {
+ if (h == NULL)
+ h = mkfailure<void*>(string("Could not load library: ") + name + ": " + dlerror());
+ }
+
+ lib(const lib& l) : name(l.name), h(l.h), owner(false) {
+ }
+
+ ~lib() {
+ if (!owner)
+ return;
+ if (!hasContent(h) || content(h) == NULL)
+ return;
+ dlclose(content(h));
+ }
+
+private:
+ template<typename S> friend const failable<lambda<S> > dynlambda(const string& name, const lib& l);
+
+ const string name;
+ failable<void*> h;
+ bool owner;
+};
+
+/**
+ * Find a lambda function in a dynamic library.
+ */
+template<typename S> const failable<lambda<S> > dynlambda(const string& name, const lib& l) {
+ if (!hasContent(l.h))
+ return mkfailure<lambda<S> >(reason(l.h));
+ const void* s = dlsym(content(l.h), c_str(name));
+ if (s == NULL)
+ return mkfailure<lambda<S> >(string("Could not load symbol: ") + name);
+ return lambda<S>((S*)s);
+}
+
+}
+#endif /* tuscany_dlib_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/element.hpp b/sca-cpp/branches/gcc-4.4/kernel/element.hpp
new file mode 100644
index 0000000000..c6aa2c44eb
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/element.hpp
@@ -0,0 +1,304 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_element_hpp
+#define tuscany_element_hpp
+
+/**
+ * Functions to help represent data as lists of elements and attributes.
+ */
+
+#include "list.hpp"
+#include "value.hpp"
+
+namespace tuscany
+{
+
+/**
+ * Tags used to tag lists of elements and attributes.
+ */
+const value attribute("attribute");
+const value element("element");
+const string atsign("@");
+
+/**
+ * Returns true if a value is an element.
+ */
+bool isElement(const value& v) {
+ if (!isList(v) || isNil(v) || element != car<value>(v))
+ return false;
+ return true;
+}
+
+/**
+ * Returns true if a value is an attribute.
+ */
+bool isAttribute(const value& v) {
+ if (!isList(v) || isNil(v) || attribute != car<value>(v))
+ return false;
+ return true;
+}
+
+/**
+ * Returns the name of an attribute.
+ */
+const value attributeName(const list<value>& l) {
+ return cadr(l);
+}
+
+/**
+ * Returns the value of an attribute.
+ */
+const value attributeValue(const list<value>& l) {
+ return caddr(l);
+}
+
+/**
+ * Returns the name of an element.
+ */
+const value elementName(const list<value>& l) {
+ return cadr(l);
+}
+
+/**
+ * Returns true if an element has children.
+ */
+const bool elementHasChildren(const list<value>& l) {
+ return !isNil(cddr(l));
+}
+
+/**
+ * Returns the children of an element.
+ */
+const list<value> elementChildren(const list<value>& l) {
+ return cddr(l);
+}
+
+/**
+ * Returns true if an element has a value.
+ */
+const value elementHasValue(const list<value>& l) {
+ const list<value> r = reverse(l);
+ if (isSymbol(car(r)))
+ return false;
+ if(isList(car(r)) && !isNil((list<value>)car(r)) && isSymbol(car<value>(car(r))))
+ return false;
+ return true;
+}
+
+/**
+ * Returns the value of an element.
+ */
+const value elementValue(const list<value>& l) {
+ return car(reverse(l));
+}
+
+/**
+ * Convert an element to a value.
+ */
+const bool elementToValueIsList(const value& v) {
+ if (!isList(v))
+ return false;
+ const list<value> l = v;
+ return (isNil(l) || !isSymbol(car(l)));
+}
+
+const value elementToValue(const value& t) {
+ const list<value> elementsToValues(const list<value>& e);
+
+ // Convert an attribute
+ if (isTaggedList(t, attribute))
+ return mklist<value>(c_str(atsign + attributeName(t)), attributeValue(t));
+
+ // Convert an element
+ if (isTaggedList(t, element)) {
+
+ // Convert an element's value
+ if (elementHasValue(t)) {
+
+ // Convert a single value
+ if (!elementToValueIsList(elementValue(t)))
+ return mklist(elementName(t), elementValue(t));
+
+ // Convert a list value
+ return cons(elementName(t), mklist<value>(elementsToValues(elementValue(t))));
+ }
+
+ // Convert an element's children
+ return cons(elementName(t), elementsToValues(elementChildren(t)));
+ }
+
+ // Convert a value
+ if (!isList(t))
+ return t;
+ return elementsToValues(t);
+}
+
+/**
+ * Convert a list of elements to a list of values.
+ */
+const bool elementToValueIsSymbol(const value& v) {
+ if (!isList(v))
+ return false;
+ const list<value> l = v;
+ if (isNil(l))
+ return false;
+ if (!isSymbol(car(l)))
+ return false;
+ return true;
+}
+
+const list<value> elementToValueGroupValues(const value& v, const list<value>& l) {
+ if (isNil(l) || !elementToValueIsSymbol(v) || !elementToValueIsSymbol(car(l)))
+ return cons(v, l);
+ if (car<value>(car(l)) != car<value>(v))
+ return cons(v, l);
+ if (!elementToValueIsList(cadr<value>(car(l)))) {
+ const value g = mklist<value>(car<value>(v), mklist<value>(cdr<value>(v), cdr<value>(car(l))));
+ return elementToValueGroupValues(g, cdr(l));
+ }
+ const value g = mklist<value>(car<value>(v), cons<value>(cdr<value>(v), (list<value>)cadr<value>(car(l))));
+ return elementToValueGroupValues(g, cdr(l));
+
+}
+
+const list<value> elementsToValues(const list<value>& e) {
+ if (isNil(e))
+ return e;
+ return elementToValueGroupValues(elementToValue(car(e)), elementsToValues(cdr(e)));
+}
+
+/**
+ * Convert a value to an element.
+ */
+const value valueToElement(const value& t) {
+ const list<value> valuesToElements(const list<value>& l);
+
+ // Convert a name value pair
+ if (isList(t) && !isNil((list<value>)t) && isSymbol(car<value>(t))) {
+ const value n = car<value>(t);
+ const value v = cadr<value>(t);
+
+ // Convert a single value to an attribute or an element
+ if (!isList(v)) {
+ if (substr(n, 0, 1) == atsign)
+ return mklist<value>(attribute, substr(n, 1), v);
+ return mklist(element, n, v);
+ }
+
+ // Convert a list value
+ if (isNil((list<value>)v) || !isSymbol(car<value>(v)))
+ return cons(element, cons(n, mklist<value>(valuesToElements(v))));
+
+ // Convert a nested name value pair value
+ return cons(element, cons(n, valuesToElements(cdr<value>(t))));
+ }
+
+ // Convert a value
+ if (!isList(t))
+ return t;
+ return valuesToElements(t);
+}
+
+/**
+ * Convert a list of values to a list of elements.
+ */
+const list<value> valuesToElements(const list<value>& l) {
+ if (isNil(l))
+ return l;
+ return cons<value>(valueToElement(car(l)), valuesToElements(cdr(l)));
+}
+
+/**
+ * Returns a selector lambda function which can be used to filter
+ * elements against the given element pattern.
+ */
+struct selectorLambda {
+ const list<value> select;
+ selectorLambda(const list<value>& s) : select(s) {
+ }
+ const bool evalSelect(const list<value>& s, const list<value> v) const {
+ if (isNil(s))
+ return true;
+ if (isNil(v))
+ return false;
+ if (car(s) != car(v))
+ return false;
+ return evalSelect(cdr(s), cdr(v));
+ }
+ const bool operator()(const value& v) const {
+ if (!isList(v))
+ return false;
+ return evalSelect(select, v);
+ }
+};
+
+const lambda<bool(const value&)> selector(const list<value> s) {
+ return selectorLambda(s);
+}
+
+/**
+ * Returns the value of the attribute with the given name.
+ */
+struct filterAttribute {
+ const value name;
+ filterAttribute(const value& n) : name(n) {
+ }
+ const bool operator()(const value& v) const {
+ return isAttribute(v) && attributeName((list<value>)v) == name;
+ }
+};
+
+const value attributeValue(const value& name, const value& l) {
+ const list<value> f = filter<value>(filterAttribute(name), list<value>(l));
+ if (isNil(f))
+ return value();
+ return caddr<value>(car(f));
+}
+
+/**
+ * Returns child elements with the given name.
+ */
+struct filterElement {
+ const value name;
+ filterElement(const value& n) : name(n) {
+ }
+ const bool operator()(const value& v) const {
+ return isElement(v) && elementName((list<value>)v) == name;
+ }
+};
+
+const value elementChildren(const value& name, const value& l) {
+ return filter<value>(filterElement(name), list<value>(l));
+}
+
+/**
+ * Return the child element with the given name.
+ */
+const value elementChild(const value& name, const value& l) {
+ const list<value> f = elementChildren(name, l);
+ if (isNil(f))
+ return value();
+ return car(f);
+}
+
+}
+#endif /* tuscany_element_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/fstream.hpp b/sca-cpp/branches/gcc-4.4/kernel/fstream.hpp
new file mode 100644
index 0000000000..f5a9dcd981
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/fstream.hpp
@@ -0,0 +1,162 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_fstream_hpp
+#define tuscany_fstream_hpp
+
+/**
+ * File based streams.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "string.hpp"
+#include "stream.hpp"
+
+namespace tuscany {
+
+/*
+ * Output stream backed by a FILE.
+ */
+class ofstream : public ostream {
+public:
+ ofstream(const string& path) : file(fopen(c_str(path), "wb")), owner(true) {
+ }
+
+ ofstream(FILE* file) : file(file), owner(false) {
+ }
+
+ ofstream(const ofstream& os) : file(os.file), owner(false) {
+ }
+
+ ~ofstream() {
+ if (!owner)
+ return;
+ if (file == NULL)
+ return;
+ fclose(file);
+ }
+
+ ofstream& vprintf(const char* fmt, ...) {
+ va_list args;
+ va_start (args, fmt);
+ vfprintf (file, fmt, args);
+ va_end (args);
+ return *this;
+ }
+
+ ofstream& write(const string& s) {
+ fwrite(c_str(s), 1, length(s), file);
+ return *this;
+ }
+
+ ofstream& flush() {
+ fflush(file);
+ return *this;
+ }
+
+private:
+ FILE* file;
+ bool owner;
+};
+
+/*
+ * Input stream backed by a FILE.
+ */
+class ifstream : public istream {
+public:
+ ifstream(const string& path) : file(fopen(c_str(path), "rb")), owner(true) {
+ }
+
+ ifstream(FILE* file) : file(file), owner(false) {
+ }
+
+ ifstream(const ifstream& is) : file(is.file), owner(false) {
+ }
+
+ ~ifstream() {
+ if (!owner)
+ return;
+ if (file == NULL)
+ return;
+ fclose(file);
+ }
+
+ const int read(void* buf, int size) {
+ return fread(buf, 1, size, file);
+ }
+
+ const bool eof() {
+ return feof(file);
+ }
+
+ const bool fail() {
+ return file == NULL;
+ }
+
+ const int get() {
+ return fgetc(file);
+ }
+
+ const int peek() {
+ int c = fgetc(file);
+ if (c == -1)
+ return c;
+ ungetc(c, file);
+ return c;
+ }
+
+private:
+ FILE* file;
+ bool owner;
+};
+
+/**
+ * Standard streams.
+ */
+ofstream cout(stdout);
+ofstream cerr(stderr);
+ifstream cin(stdin);
+
+/**
+ * Debug log stream.
+ */
+#ifdef WANT_MAINTAINER_MODE
+
+template<typename V> const bool debug(const V& v, const string& msg) {
+ cerr << msg << ": " << v << endl;
+ return true;
+}
+
+const bool debug(const string& msg) {
+ cerr << msg << endl;
+ return true;
+}
+
+#else
+
+#define debug(...)
+
+#endif
+
+}
+
+#endif /* tuscany_fstream_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/function.hpp b/sca-cpp/branches/gcc-4.4/kernel/function.hpp
new file mode 100644
index 0000000000..db7318303a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/function.hpp
@@ -0,0 +1,238 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_function_hpp
+#define tuscany_function_hpp
+
+/**
+ * Lambda function type.
+ */
+
+#include <utility>
+#include "fstream.hpp"
+#include "gc.hpp"
+#include "config.hpp"
+
+namespace tuscany {
+
+#ifdef WANT_MAINTAINER_MODE
+
+/**
+ * Debug counters.
+ */
+long int countProxies;
+long int countFProxies = 0;
+long int countCProxies = 0;
+long int countLambdas = 0;
+long int countELambdas = 0;
+long int countCLambdas = 0;
+long int countFLambdas = 0;
+
+bool resetLambdaCounters() {
+ countLambdas = countELambdas = countCLambdas = countFLambdas = countProxies = countFProxies = countCProxies = 0;
+ return true;
+}
+
+bool checkLambdaCounters() {
+ return countLambdas == 0;
+}
+
+bool printLambdaCounters() {
+ cout << "countLambdas " << countLambdas << endl;
+ cout << "countELambdas " << countELambdas << endl;
+ cout << "countFLambdas " << countFLambdas << endl;
+ cout << "countCLambdas " << countCLambdas << endl;
+ cout << "countProxies " << countProxies << endl;
+ cout << "countFProxies " << countFProxies << endl;
+ cout << "countCProxies " << countCProxies << endl;
+ return true;
+}
+
+#else
+
+#define resetLambdaCounters()
+#define checkLambdaCounters() true
+#define printLambdaCounters()
+
+#endif
+
+/**
+ * Lambda function type.
+ */
+
+template<typename R, typename... P> class Callable {
+public:
+ Callable() {
+ }
+
+ virtual const int size() const = 0;
+
+ virtual const R operator()(P... p) const = 0;
+
+ virtual ~Callable() {
+ }
+
+ template<typename F> class Proxy: public Callable {
+ public:
+ Proxy(const F& f) : function(f) {
+ debug_inc(countProxies);
+ debug_inc(countFProxies);
+ }
+
+ Proxy(const Proxy& p) : function(p.function) {
+ debug_inc(countProxies);
+ debug_inc(countCProxies);
+ }
+
+ ~Proxy() {
+ debug_dec(countProxies);
+ }
+
+ virtual const R operator() (P... p) const {
+ return function(std::forward<P>(p)...);
+ }
+
+ virtual const int size() const {
+ return sizeof(function);
+ }
+
+ private:
+ const F function;
+ };
+};
+
+template<typename S> class lambda;
+
+template<typename R, typename... P> class lambda<R(P...)> {
+public:
+ lambda() : callable(0) {
+ debug_inc(countLambdas);
+ debug_inc(countELambdas);
+ }
+
+ template<typename F> lambda(const F f) {
+ debug_inc(countLambdas);
+ debug_inc(countFLambdas);
+
+ typedef typename CallableType::template Proxy<F> ProxyType;
+ callable = gc_ptr<CallableType>(new (gc_new<ProxyType>()) ProxyType(f));
+ }
+
+ lambda(const lambda& l) {
+ debug_inc(countLambdas);
+ debug_inc(countCLambdas);
+ callable = l.callable;
+ }
+
+ const lambda& operator=(const lambda& l) {
+ if (this == &l)
+ return *this;
+ callable = l.callable;
+ return *this;
+ }
+
+ ~lambda() {
+ debug_dec(countLambdas);
+ }
+
+ const bool operator==(const lambda& l) const {
+ if (this == &l)
+ return true;
+ return callable == l.callable;
+ }
+
+ const bool operator!=(const lambda& l) const {
+ return !this->operator==(l);
+ }
+
+ const R operator()(P... p) const {
+ return (*callable)(std::forward<P>(p)...);
+ }
+
+ template<typename S> friend ostream& operator<<(ostream&, const lambda<S>&);
+ template<typename S> friend const bool isNil(const lambda<S>& l);
+
+private:
+ typedef Callable<R,P...> CallableType;
+ gc_ptr<CallableType> callable;
+};
+
+template<typename S> ostream& operator<<(ostream& out, const lambda<S>& l) {
+ return out << "lambda::" << l.callable;
+}
+
+/**
+ * Return true if a lambda is nil.
+ */
+template<typename S> const bool isNil(const lambda<S>& l) {
+ return ((void*)l.callable) == 0;
+}
+
+/**
+ * Curry a lambda function.
+ */
+template<typename R, typename T, typename... P> class curried {
+public:
+ curried(const lambda<R(T, P...)>& f, const T& v): v(v), f(f) {
+ }
+
+ const R operator()(P... p) const {
+ return f(v, std::forward<P>(p)...);
+ }
+
+private:
+ const T v;
+ const lambda<R(T, P...)>f;
+};
+
+template<typename R, typename T, typename... P> const lambda<R(P...)> curry(const lambda<R(T, P...)>& f, const T& t) {
+ return curried<R, T, P...>(f, t);
+}
+
+template<typename R, typename T, typename U, typename... P> const lambda<R(P...)> curry(const lambda<R(T, U, P...)>& f, const T& t, const U& u) {
+ return curry(curry(f, t), u);
+}
+
+template<typename R, typename T, typename U, typename V, typename... P> const lambda<R(P...)> curry(const lambda<R(T, U, V, P...)>& f, const T& t, const U& u, const V& v) {
+ return curry(curry(curry(f, t), u), v);
+}
+
+/**
+ * A lambda function that returns the given value.
+ */
+template<typename T> class returnResult {
+public:
+ returnResult(const T& v) :
+ v(v) {
+ }
+ const T operator()() const {
+ return v;
+ }
+private:
+ const T v;
+};
+
+template<typename T> const lambda<T()> result(const T& v) {
+ return returnResult<T> (v);
+}
+
+}
+#endif /* tuscany_function_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/gc.hpp b/sca-cpp/branches/gcc-4.4/kernel/gc.hpp
new file mode 100644
index 0000000000..ca01fdf95f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/gc.hpp
@@ -0,0 +1,276 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_gc_hpp
+#define tuscany_gc_hpp
+
+/**
+ * Garbage collected memory management, using APR memory pools.
+ */
+
+#include <stdlib.h>
+#include <apr_general.h>
+#include <apr_pools.h>
+#include <assert.h>
+#include <new>
+#include "config.hpp"
+
+namespace tuscany
+{
+
+/**
+ * Pointer to a value.
+ */
+template<typename T> class gc_ptr {
+public:
+ gc_ptr(T* ptr = NULL) throw() : ptr(ptr) {
+ }
+
+ ~gc_ptr() throw() {
+ }
+
+ gc_ptr(const gc_ptr& r) throw() : ptr(r.ptr) {
+ }
+
+ gc_ptr& operator=(const gc_ptr& r) throw() {
+ if(this == &r)
+ return *this;
+ ptr = r.ptr;
+ return *this;
+ }
+
+ const bool operator==(const gc_ptr& r) const throw() {
+ if (this == &r)
+ return true;
+ return ptr == r.ptr;
+ }
+
+ const bool operator!=(const gc_ptr& r) const throw() {
+ return !this->operator==(r);
+ }
+
+ T& operator*() const throw() {
+ return *ptr;
+ }
+
+ T* operator->() const throw() {
+ return ptr;
+ }
+
+ operator T*() const throw() {
+ return ptr;
+ }
+
+ T* ptr;
+};
+
+/**
+ * Garbage collected APR memory pool.
+ */
+class gc_pool {
+public:
+ gc_pool() : apr_pool(NULL) {
+ }
+
+ gc_pool(apr_pool_t* p) : apr_pool(p) {
+ }
+
+ gc_pool(const gc_pool& pool) : apr_pool(pool.apr_pool) {
+ }
+
+ gc_pool& operator=(const gc_pool& pool) {
+ if (this == &pool)
+ return *this;
+ apr_pool = pool.apr_pool;
+ return *this;
+ }
+
+private:
+ friend apr_pool_t* pool(const gc_pool& pool);
+ friend class gc_global_pool_t;
+ friend class gc_scoped_pool;
+
+ apr_pool_t* apr_pool;
+};
+
+/**
+ * Return APR pool used by a gc_pool.
+ */
+apr_pool_t* pool(const gc_pool& pool) {
+ return pool.apr_pool;
+}
+
+/**
+ * Destroy a memory pool.
+ */
+const bool destroy(const gc_pool& p) {
+ apr_pool_destroy(pool(p));
+ return true;
+}
+
+/**
+ * Initialize APR.
+ */
+class gc_apr_context_t {
+public:
+ gc_apr_context_t() {
+ apr_initialize();
+ }
+} gc_apr_context;
+
+/**
+ * Maintain a stack of memory pools.
+ */
+#ifdef WANT_THREADS
+__thread
+#endif
+apr_pool_t* gc_pool_stack = NULL;
+
+/**
+ * Return the current memory pool.
+ */
+apr_pool_t* gc_current_pool() {
+ apr_pool_t* apr_pool = gc_pool_stack;
+ if (apr_pool != NULL)
+ return apr_pool;
+
+ // Create a parent pool for the current thread
+ apr_pool_create(&apr_pool, NULL);
+ assert(apr_pool != NULL);
+ gc_pool_stack = apr_pool;
+ return apr_pool;
+}
+
+/**
+ * Push a pool onto the stack.
+ */
+apr_pool_t* gc_push_pool(apr_pool_t* pool) {
+ apr_pool_t* p = gc_pool_stack;
+ gc_pool_stack = pool;
+ return p;
+}
+
+/**
+ * Pop a pool from the stack.
+ */
+apr_pool_t* gc_pop_pool(apr_pool_t* pool) {
+ apr_pool_t* p = gc_pool_stack;
+ gc_pool_stack = pool;
+ return p;
+}
+
+/**
+ * A memory pool scope, used to setup a scope in which a particular pool
+ * will be used for all allocations.
+ */
+class gc_scoped_pool : public gc_pool {
+public:
+
+ gc_scoped_pool() : gc_pool(NULL), prev(gc_current_pool()), owner(true) {
+ apr_pool_create(&apr_pool, NULL);
+ assert(apr_pool != NULL);
+ gc_push_pool(apr_pool);
+ }
+
+ gc_scoped_pool(apr_pool_t* pool) : gc_pool(pool), prev(gc_current_pool()), owner(false) {
+ gc_push_pool(apr_pool);
+ }
+
+ ~gc_scoped_pool() {
+ if (owner)
+ apr_pool_destroy(apr_pool);
+ gc_pop_pool(prev);
+ }
+
+private:
+ gc_scoped_pool(const unused gc_scoped_pool& pool) : gc_pool(pool.apr_pool), prev(NULL), owner(false) {
+ }
+
+ apr_pool_t* prev;
+ bool owner;
+};
+
+/**
+ * Allocates a pointer to an object allocated from a memory pool and
+ * register a cleanup callback for it.
+ */
+template<typename T> apr_status_t gc_pool_cleanup(void* v) {
+ T* t = static_cast<T*>(v);
+ t->~T();
+ return APR_SUCCESS;
+}
+
+template<typename T> T* gc_new(apr_pool_t* p) {
+ void* gc_new_ptr = apr_palloc(p, sizeof(T));
+ assert(gc_new_ptr != NULL);
+ apr_pool_cleanup_register(p, gc_new_ptr, gc_pool_cleanup<T>, apr_pool_cleanup_null) ;
+ return static_cast<T*>(gc_new_ptr);
+}
+
+template<typename T> T* gc_new(const gc_pool& p) {
+ return gc_new<T>(pool(p));
+}
+
+template<typename T> T* gc_new() {
+ return gc_new<T>(gc_current_pool());
+}
+
+template<typename T> apr_status_t gc_pool_acleanup(void* v) {
+ int* m = static_cast<int*>(v);
+ int n = *m;
+ T* t = (T*)(m + 1);
+ for (int i = 0; i < n; i++, t++)
+ t->~T();
+ return APR_SUCCESS;
+}
+
+template<typename T> T* gc_anew(apr_pool_t* p, int n) {
+ int* gc_anew_ptr = static_cast<int*>(apr_palloc(p, sizeof(int) + sizeof(T[n])));
+ assert(gc_anew_ptr != NULL);
+ *gc_anew_ptr = n;
+ apr_pool_cleanup_register(p, gc_anew_ptr, gc_pool_acleanup<T>, apr_pool_cleanup_null) ;
+ return (T*)(gc_anew_ptr + 1);
+}
+
+template<typename T> T* gc_anew(const gc_pool& p, int n) {
+ return gc_anew<T>(pool(p), n);
+}
+
+template<typename T> T* gc_anew(int n) {
+ return gc_anew<T>(gc_current_pool(), n);
+}
+
+/**
+ * Allocate an array of chars.
+ */
+char* gc_cnew(apr_pool_t* p, int n) {
+ char* gc_cnew_ptr = static_cast<char*>(apr_palloc(p, n));
+ assert(gc_cnew_ptr != NULL);
+ return gc_cnew_ptr;
+}
+
+char* gc_cnew(int n) {
+ return gc_cnew(gc_current_pool(), n);
+}
+
+}
+
+#endif /* tuscany_gc_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/hash-test.cpp b/sca-cpp/branches/gcc-4.4/kernel/hash-test.cpp
new file mode 100644
index 0000000000..b794e38920
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/hash-test.cpp
@@ -0,0 +1,135 @@
+/*
+ * 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 hash functions.
+ */
+
+#include <assert.h>
+#include "string.hpp"
+#include "hash.hpp"
+#include "perf.hpp"
+
+namespace tuscany {
+
+bool testCrc32hash() {
+ const string key("This is a test key");
+ unsigned int h = crc32hash(c_str(key), length(key));
+ assert(h != 0);
+ return true;
+}
+
+bool testTimes33hash() {
+ const string key("This is a test key");
+ unsigned int h = times33hash(c_str(key), length(key));
+ assert(h != 0);
+ return true;
+}
+
+bool testMurmurhash() {
+ const string key("This is a test key");
+ unsigned int h = murmurhash(c_str(key), length(key));
+ assert(h != 0);
+ return true;
+}
+
+bool testPortablemurmurhash() {
+ const string key("This is a test key");
+ unsigned int h = portablemurmurhash(c_str(key), length(key));
+ assert(h != 0);
+ return true;
+}
+
+struct crc32hashTest {
+ const string key;
+ crc32hashTest(const string& key) : key(key) {
+ }
+ bool operator()() const {
+ unsigned int h = crc32hash(c_str(key), length(key));
+ assert(h != 0);
+ return true;
+ }
+};
+
+struct times33hashTest {
+ const string key;
+ times33hashTest(const string& key) : key(key) {
+ }
+ bool operator()() const {
+ unsigned int h = times33hash(c_str(key), length(key));
+ assert(h != 0);
+ return true;
+ }
+};
+
+struct murmurhashTest {
+ const string key;
+ murmurhashTest(const string& key) : key(key) {
+ }
+ bool operator()() const {
+ unsigned int h = murmurhash(c_str(key), length(key));
+ assert(h != 0);
+ return true;
+ }
+};
+
+struct portablemurmurhashTest {
+ const string key;
+ portablemurmurhashTest(const string& key) : key(key) {
+ }
+ bool operator()() const {
+ unsigned int h = portablemurmurhash(c_str(key), length(key));
+ assert(h != 0);
+ return true;
+ }
+};
+
+bool testHashPerf() {
+ const string key("This is a test key");
+ const int count = 100000;
+
+ const lambda<bool()> crc32 = crc32hashTest(key);
+ cout << "crc32hash test " << time(crc32, 5, count) << " ms" << endl;
+ const lambda<bool()> times33 = times33hashTest(key);
+ cout << "times33hash test " << time(times33, 5, count) << " ms" << endl;
+ const lambda<bool()> murmur = murmurhashTest(key);
+ cout << "murmurhash test " << time(murmur, 5, count) << " ms" << endl;
+ const lambda<bool()> portablemurmur = portablemurmurhashTest(key);
+ cout << "portable murmurhash test " << time(portablemurmur, 5, count) << " ms" << endl;
+
+ return true;
+}
+
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::testCrc32hash();
+ tuscany::testTimes33hash();
+ tuscany::testMurmurhash();
+ tuscany::testPortablemurmurhash();
+ tuscany::testHashPerf();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/kernel/hash.hpp b/sca-cpp/branches/gcc-4.4/kernel/hash.hpp
new file mode 100644
index 0000000000..5cd213f09e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/hash.hpp
@@ -0,0 +1,207 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_hash_hpp
+#define tuscany_hash_hpp
+
+/**
+ * Fast hash functions.
+ */
+
+#include <apr_hash.h>
+#include <apr_memcache.h>
+
+namespace tuscany
+{
+
+/**
+ * Apache apr-util CRC32 hash function.
+ *
+ * See srclib/apr-util/memcache/apr_memcache.c from the Apache HTTPD
+ * source tree. Reproducing the comments from apr_memcache.c here:
+ *
+ * The crc32 functions and data were originally written by Spencer
+ * Garrett <srg@quick.com> and were gleaned from the PostgreSQL source
+ * tree at contrib/ltree/crc32.[ch] and from FreeBSD at
+ * src/usr.bin/cksum/crc32.c.
+ */
+const unsigned int crc32hash(const char* data, const unsigned int len) {
+ return apr_memcache_hash_default(NULL, data, len);
+}
+
+/**
+ * Apache apr tables default hash function.
+ *
+ * See srclib/apr/tables/apr_hash.c from the Apache HTTPD source tree.
+ * Reproducing the comments from apr_hash.c here:
+ *
+ * This is the popular `times 33' hash algorithm which is used by
+ * perl and also appears in Berkeley DB. This is one of the best
+ * known hash functions for strings because it is both computed
+ * very fast and distributes very well.
+ *
+ * The originator may be Dan Bernstein but the code in Berkeley DB
+ * cites Chris Torek as the source. The best citation I have found
+ * is "Chris Torek, Hash function for text in C, Usenet message
+ * <27038@mimsy.umd.edu> in comp.lang.c , October, 1990." in Rich
+ * Salz's USENIX 1992 paper about INN which can be found at
+ * <http://citeseer.nj.nec.com/salz92internetnews.html>.
+ *
+ * The magic of number 33, i.e. why it works better than many other
+ * constants, prime or not, has never been adequately explained by
+ * anyone. So I try an explanation: if one experimentally tests all
+ * multipliers between 1 and 256 (as I did while writing a low-level
+ * data structure library some time ago) one detects that even
+ * numbers are not useable at all. The remaining 128 odd numbers
+ * (except for the number 1) work more or less all equally well.
+ * They all distribute in an acceptable way and this way fill a hash
+ * table with an average percent of approx. 86%.
+ *
+ * If one compares the chi^2 values of the variants (see
+ * Bob Jenkins ``Hashing Frequently Asked Questions'' at
+ * http://burtleburtle.net/bob/hash/hashfaq.html for a description
+ * of chi^2), the number 33 not even has the best value. But the
+ * number 33 and a few other equally good numbers like 17, 31, 63,
+ * 127 and 129 have nevertheless a great advantage to the remaining
+ * numbers in the large set of possible multipliers: their multiply
+ * operation can be replaced by a faster operation based on just one
+ * shift plus either a single addition or subtraction operation. And
+ * because a hash function has to both distribute good _and_ has to
+ * be very fast to compute, those few numbers should be preferred.
+ *
+ * -- Ralf S. Engelschall <rse@engelschall.com>
+ */
+const unsigned int times33hash(const char* data, const unsigned int len) {
+ apr_ssize_t l = len;
+ return apr_hashfunc_default(data, &l);
+}
+
+/**
+ * A very fast, non-cryptographic hash suitable for general hash-based
+ * lookup. See http://murmurhash.googlepages.com/ for more details.
+ *
+ * Original code by Austin Appleby, released to the public domain and under
+ * the MIT license.
+ *
+ * Compiles down to ~52 instructions on x86.
+ * Passes chi^2 tests for practically all keysets & bucket sizes.
+ * Excellent avalanche behavior. Maximum bias is under 0.5%.
+ * Passes Bob Jenkin's frog.c torture-test. No collisions possible for 4 byte
+ * keys, no small 1 to 7 bit differentials.
+ */
+const unsigned int murmurhash(const char* key, const unsigned int klen) {
+ unsigned int len = klen;
+ const unsigned int seed = 0;
+
+ // 'm' and 'r' are mixing constants generated offline.
+ // They're not really 'magic', they just happen to work well.
+ const unsigned int m = 0x5bd1e995;
+ const int r = 24;
+
+ // Initialize the hash to a 'random' value
+ unsigned int h = seed ^ len;
+
+ // Mix 4 bytes at a time into the hash
+ const unsigned char* data = (const unsigned char*)key;
+ while(len >= 4) {
+ unsigned int k = *(unsigned int*)data;
+ k *= m;
+ k ^= k >> r;
+ k *= m;
+ h *= m;
+ h ^= k;
+ data += 4;
+ len -= 4;
+ }
+
+ // Handle the last few bytes of the input array
+ switch(len) {
+ case 3: h ^= data[2] << 16;
+ case 2: h ^= data[1] << 8;
+ case 1: h ^= data[0];
+ h *= m;
+ };
+
+ // Do a few final mixes of the hash to ensure the last few
+ // bytes are well-incorporated.
+ h ^= h >> 13;
+ h *= m;
+ h ^= h >> 15;
+
+ return h;
+}
+
+/**
+ * An endian and alignment neutral, but half the speed, version of
+ * the murmur hash.
+ */
+const unsigned int portablemurmurhash(const char* key, const unsigned int klen) {
+ unsigned int len = klen;
+ const unsigned int seed = 0;
+
+ // 'm' and 'r' are mixing constants generated offline.
+ // They're not really 'magic', they just happen to work well.
+ const unsigned int m = 0x5bd1e995;
+ const int r = 24;
+
+ // Initialize the hash to a 'random' value
+ unsigned int h = seed ^ len;
+
+ // Mix 4 bytes at a time into the hash
+ const unsigned char* data = (const unsigned char *)key;
+ while(len >= 4) {
+ unsigned int k;
+ k = data[0];
+ k |= data[1] << 8;
+ k |= data[2] << 16;
+ k |= data[3] << 24;
+ k *= m;
+ k ^= k >> r;
+ k *= m;
+ h *= m;
+ h ^= k;
+ data += 4;
+ len -= 4;
+ }
+
+ // Handle the last few bytes of the input array
+ switch(len) {
+ case 3: h ^= data[2] << 16;
+ case 2: h ^= data[1] << 8;
+ case 1: h ^= data[0];
+ h *= m;
+ };
+
+ // Do a few final mixes of the hash to ensure the last few
+ // bytes are well-incorporated.
+ h ^= h >> 13;
+ h *= m;
+ h ^= h >> 15;
+
+ return h;
+}
+
+const unsigned int hashselect(const unsigned int hash, const unsigned int max) {
+ return hash % max;
+}
+
+}
+#endif /* tuscany_hash_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/kernel-test.cpp b/sca-cpp/branches/gcc-4.4/kernel/kernel-test.cpp
new file mode 100644
index 0000000000..44ffe06b7b
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/kernel-test.cpp
@@ -0,0 +1,594 @@
+/*
+ * 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 kernel functions.
+ */
+
+#include <assert.h>
+#include "string.hpp"
+#include "sstream.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "tree.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "dynlib.hpp"
+#include "perf.hpp"
+
+namespace tuscany {
+
+struct inc {
+ int i;
+ inc(int i) :
+ i(i) {
+ }
+ const int operator()(const int x) const {
+ return x + i;
+ }
+};
+
+const int square(const int x) {
+ return x * x;
+}
+
+int mapLambda(lambda<int(const int)> f, int v) {
+ return f(v);
+}
+
+bool testLambda() {
+ const lambda<int(const int)> sq(square);
+ assert(sq(2) == 4);
+ assert(mapLambda(sq, 2) == 4);
+ assert(mapLambda(square, 2) == 4);
+
+ const lambda<int(const int)> incf(inc(10));
+ assert(incf(1) == 11);
+ assert(mapLambda(incf, 1) == 11);
+ assert(mapLambda(inc(10), 1) == 11);
+
+ lambda<int(const int)> l;
+ l = incf;
+ assert(l(1) == 11);
+ l = square;
+ assert(l(2) == 4);
+ return true;
+}
+
+bool testLambdaGC() {
+ resetLambdaCounters();
+ {
+ gc_scoped_pool gc;
+ testLambda();
+ }
+ assert(checkLambdaCounters());
+ return true;
+}
+
+int countElements = 0;
+
+struct Element {
+ int i;
+
+ Element() : i(0) {
+ countElements++;
+ }
+
+ Element(int i) : i(i) {
+ countElements++;
+ }
+
+ Element(const Element& o) : i(o.i) {
+ countElements++;
+ }
+
+ ~Element() {
+ countElements--;
+ }
+
+ const bool operator==(const Element& o) const {
+ return o.i == i;
+ }
+};
+ostream& operator<<(ostream& out, const Element& v) {
+ out << v.i ;
+ return out;
+}
+
+bool testCons() {
+ assert(car(cons(2, mklist(3))) == 2);
+ assert(car(cdr(cons(2, mklist(3)))) == 3);
+ assert(isNil(cdr(cdr(cons(2, mklist(3))))));
+
+ assert(cons(Element(1), mklist(Element(2))) == mklist(Element(1), Element(2)));
+ return true;
+}
+
+bool testListGC() {
+ resetLambdaCounters();
+ resetListCounters();
+ countElements = 0;
+ {
+ gc_scoped_pool gc;
+ testCons();
+ }
+ assert(checkLambdaCounters());
+ assert(checkListCounters());
+ assert(countElements == 0);
+ return true;
+}
+
+bool testOut() {
+ ostringstream os1;
+ os1 << list<int> ();
+ assert(str(os1) == "()");
+
+ ostringstream os2;
+ os2 << mklist(1, 2, 3);
+ assert(str(os2) == "(1 2 3)");
+ return true;
+}
+
+bool testEquals() {
+ assert(list<int>() == list<int>());
+ assert(mklist(1, 2) == mklist(1, 2));
+ assert(list<int>() != mklist(1, 2));
+ assert(mklist(1, 2, 3) == mklist(1, 2, 3));
+ assert(mklist(1, 2) != mklist(1, 2, 3));
+ return true;
+}
+
+bool testLength() {
+ assert(0 == length(list<int>()));
+ assert(1 == length(mklist(1)));
+ assert(2 == length(cons(1, mklist(2))));
+ return true;
+}
+
+bool testAppend() {
+ assert(car(append(mklist(1), mklist(2))) == 1);
+ assert(car(cdr(append(mklist(1), mklist(2)))) == 2);
+ assert(car(cdr(cdr(append(mklist(1), mklist(2, 3))))) == 3);
+ assert(isNil(cdr(cdr(cdr(append(mklist(1), mklist(2, 3)))))));
+
+ assert(list<int>() + 1 + 2 + 3 == mklist(1, 2, 3));
+ return true;
+}
+
+struct Complex {
+ int x;
+ int y;
+ Complex() {
+ }
+ Complex(int x, int y) :
+ x(x), y(y) {
+ }
+};
+ostream& operator<<(ostream& out, const Complex& v) {
+ out << "[" << v.x << ":" << v.y << "]";
+ return out;
+}
+
+bool testComplex() {
+ const list<Complex> p = mklist(Complex(1, 2), Complex(3, 4));
+ assert(car(p).x == 1);
+ assert(car(cdr(p)).x == 3);
+ assert(isNil(cdr(cdr(p))));
+ return true;
+}
+
+bool testMap() {
+ assert(isNil(map<int, int>(square, list<int>())));
+
+ const list<int> m = map<int, int>(square, mklist(2, 3));
+ assert(car(m) == 4);
+ assert(car(cdr(m)) == 9);
+
+ return true;
+}
+
+const int add(const int x, const int y) {
+ return x + y;
+}
+
+bool testReduce() {
+ const lambda<int(const int, const int)> r(add);
+ assert(reduce(r, 0, mklist(1, 2, 3)) == 6);
+ return true;
+}
+
+bool isPositive(const int x) {
+ if(x >= 0)
+ return true;
+ else
+ return false;
+}
+
+bool testFilter() {
+ assert(car(filter<int>(isPositive, mklist(1, -1, 2, -2))) == 1);
+ assert(cadr(filter<int>(isPositive, mklist(1, -1, 2, -2))) == 2);
+ return true;
+}
+
+bool testMember() {
+ assert(isNil(member(4, mklist(1, 2, 3))));
+ assert(car(member(1, mklist(1, 2, 3))) == 1);
+ assert(car(member(2, mklist(1, 2, 3))) == 2);
+ assert(car(member(3, mklist(1, 2, 3))) == 3);
+ return true;
+}
+
+bool testReverse() {
+ assert(isNil(reverse(list<int>())));
+ assert(car(reverse(mklist(1, 2, 3))) == 3);
+ assert(cadr(reverse(mklist(1, 2, 3))) == 2);
+ return true;
+}
+
+bool testListRef() {
+ assert(listRef(mklist(1), 0) == 1);
+ assert(listRef(mklist(1, 2, 3), 0) == 1);
+ assert(listRef(mklist(1, 2, 3), 1) == 2);
+ assert(listRef(mklist(1, 2, 3), 2) == 3);
+ return true;
+}
+
+bool testAssoc() {
+ const list<list<string> > l = mklist(mklist<string>("x", "X"), mklist<string>("a", "A"), mklist<string>("y", "Y"), mklist<string>("a", "AA"));
+ assert(assoc<string>("a", l) == mklist<string>("a", "A"));
+ assert(isNil(assoc<string>("z", l)));
+
+ const list<list<value> > u = mklist(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "Y"), mklist<value>("a", "AA"));
+ assert(assoc<value>("a", u) == mklist<value>("a", "A"));
+
+ const list<value> v = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "Y"), mklist<value>("a", "AA"));
+ assert(assoc<value>("a", v) == mklist<value>("a", "A"));
+ return true;
+}
+
+bool testZip() {
+ const list<string> k = mklist<string>("x", "a", "y", "a");
+ const list<string> v = mklist<string>("X", "A", "Y", "AA");
+ const list<list<string> > z = mklist(k, v);
+ const list<list<string> > u = mklist(mklist<string>("x", "X"), mklist<string>("a", "A"), mklist<string>("y", "Y"), mklist<string>("a", "AA"));
+ assert(zip(k, v) == u);
+ assert(unzip(u) == z);
+ return true;
+}
+
+bool testTokenize() {
+ assert(tokenize("/", "aaa/bbb/ccc/ddd") == mklist<string>("aaa", "bbb", "ccc", "ddd"));
+ assert(tokenize("/", "/bbb/ccc/ddd") == mklist<string>("", "bbb", "ccc", "ddd"));
+ assert(tokenize("/", "/bbb/ccc/") == mklist<string>("", "bbb", "ccc"));
+ assert(tokenize("/", "/bbb//ccc/") == mklist<string>("", "bbb", "", "ccc"));
+ assert(tokenize("/", "abc/def/") == mklist<string>("abc", "def"));
+ return true;
+}
+
+double testSeqMap(double x) {
+ return x;
+}
+
+double testSeqReduce(unused double v, double accum) {
+ return accum + 1.0;
+}
+
+bool testSeq() {
+ resetLambdaCounters();
+ resetListCounters();
+
+ list<double> s = seq(0.0, 1000.0);
+ assert(1001 == length(s));
+
+ assert(1001 == length(map<double, double>(testSeqMap, s)));
+
+ assert(801 == length(member(200.0, s)));
+ assert(201 == length(member(200.0, reverse(s))));
+
+ assert(1001 == (reduce<double, double>(testSeqReduce, 0.0, s)));
+ return true;
+}
+
+value valueSquare(list<value> x) {
+ return (int)car(x) * (int)car(x);
+}
+
+bool testValue() {
+ assert(value(true) == value(true));
+ assert(value(1) == value(1));
+ assert(value("abcd") == value("abcd"));
+ lambda<value(const list<value>&)> vl(valueSquare);
+ assert(value(vl) == value(vl));
+ assert(value(mklist<value>(1, 2)) == value(mklist<value>(1, 2)));
+
+ const list<value> v = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "Y"));
+ assert(cadr((list<list<value> >)value(v)) == mklist<value>("a", "A"));
+
+ const value pv(gc_ptr<value>(new (gc_new<value>()) value(1)));
+ assert(*(gc_ptr<value>)pv == value(1));
+
+ const list<value> lpv = mklist<value>(gc_ptr<value>(new (gc_new<value>()) value(1)), gc_ptr<value>(new (gc_new<value>()) value(2)));
+ assert(*(gc_ptr<value>)car(lpv) == value(1));
+ return true;
+}
+
+bool testValueGC() {
+ resetLambdaCounters();
+ resetListCounters();
+ resetValueCounters();
+ {
+ gc_scoped_pool gc;
+ testValue();
+ }
+ assert(checkValueCounters());
+ assert(checkLambdaCounters());
+ assert(checkListCounters());
+ return true;
+}
+
+bool testTree() {
+ const list<value> t = mktree<value>("a", list<value>(), list<value>());
+ const list<value> ct = constree<value>("d", constree<value>("f", constree<value>("c", constree<value>("e", constree<value>("b", t)))));
+ const list<value> mt = mktree(mklist<value>("d", "f", "c", "e", "b", "a"));
+ assert(mt == ct);
+ const list<value> l = flatten<value>(mt);
+ assert(length(l) == 6);
+ assert(car(l) == "a");
+ assert(car(reverse(l)) == "f");
+ const list<value> bt = mkbtree<value>(l);
+ assert(car(bt) == "c");
+ return true;
+}
+
+const list<value> lta(const string& x) {
+ return mklist<value>(c_str(x), c_str(x + x));
+}
+
+bool testTreeAssoc() {
+ const list<value> t = mktree<value>(lta("a"), list<value>(), list<value>());
+ const list<value> at = constree<value>(lta("d"), constree<value>(lta("f"), constree<value>(lta("c"), constree<value>(lta("e"), constree<value>(lta("b"), t)))));
+ const list<value> l = flatten<value>(at);
+ assert(length(l) == 6);
+ assert(car(l) == mklist<value>("a", "aa"));
+ assert(car(reverse(l)) == mklist<value>("f", "ff"));
+ const list<value> bt = mkbtree<value>(l);
+ assert(car(bt) == mklist<value>("c", "cc"));
+ assert(assoctree<value>("a", bt) == mklist<value>("a", "aa"));
+ assert(assoctree<value>("b", bt) == mklist<value>("b", "bb"));
+ assert(assoctree<value>("f", bt) == mklist<value>("f", "ff"));
+ assert(isNil(assoctree<value>("x", bt)));
+ return true;
+}
+
+double fib_aux(double n, double a, double b) {
+ if(n == 0.0)
+ return a;
+ return fib_aux(n - 1.0, b, a + b);
+}
+
+double fib(double n) {
+ return fib_aux(n, 0.0, 1.0);
+}
+
+struct fibMapPerf {
+ const bool operator()() const {
+ list<double> s = seq(0.0, 999.0);
+ list<double> r = map<double, double>(fib, s);
+ assert(1000 == length(r));
+ return true;
+ }
+};
+
+struct nestedFibMapPerf {
+ const lambda<double(const double)> fib;
+ nestedFibMapPerf(const lambda<double(const double)>& fib) : fib(fib) {
+ }
+ const bool operator()() const {
+ list<double> s = seq(0.0, 999.0);
+ list<double> r = map<double, double>(fib, s);
+ assert(1000 == length(r));
+ return true;
+ }
+};
+
+bool testCppPerf() {
+ {
+ const lambda<bool()> fml = fibMapPerf();
+ cout << "Fibonacci map test " << (time(fml, 1, 1) / 1000) << " ms" << endl;
+ }
+
+ {
+ struct nested {
+ static double fib(double n) {
+ struct nested {
+ static double fib_aux(double n, double a, double b) {
+ if(n == 0.0)
+ return a;
+ return fib_aux(n - 1.0, b, a + b);
+ }
+ };
+ return nested::fib_aux(n, 0.0, 1.0);
+ }
+ };
+
+ const lambda<bool()> nfml = nestedFibMapPerf(lambda<double(const double)>(nested::fib));
+ cout << "Nested Fibonacci map test " << (time(nfml, 1, 1) / 1000) << " ms" << endl;
+ }
+ return true;
+}
+
+const id<int> idF(const int v) {
+ return v * 2;
+}
+
+const id<int> idG(const int v) {
+ return v * 3;
+}
+
+const id<int> idH(const int v) {
+ return idF(v) >> idG;
+}
+
+bool testIdMonad() {
+ const id<int> m(2);
+ assert(m >> idF == idF(2));
+ assert(m >> unit<int>() == m);
+ assert(m >> idF >> idG == m >> idH);
+ return true;
+}
+
+const maybe<int> maybeF(const int v) {
+ return v * 2;
+}
+
+const maybe<int> maybeG(const int v) {
+ return v * 3;
+}
+
+const maybe<int> maybeH(const int v) {
+ return maybeF(v) >> maybeG;
+}
+
+bool testMaybeMonad() {
+ const maybe<int> m(2);
+ assert(m >> maybeF == maybeF(2));
+ assert((m >> just<int>()) == m);
+ assert(m >> maybeF >> maybeG == m >> maybeH);
+
+ assert(maybe<int>() >> maybeF >> maybeG == maybe<int>());
+ return true;
+}
+
+const failable<int> failableF(const int v) {
+ return v * 2;
+}
+
+const failable<int> failableG(const int v) {
+ return v * 3;
+}
+
+const failable<int> failableH(const int v) {
+ return failableF(v) >> failableG;
+}
+
+bool testFailableMonad() {
+ const failable<int> m(2);
+ assert(m >> failableF == failableF(2));
+ assert((m >> success<int, string>()) == m);
+ assert(m >> failableF >> failableG == m >> failableH);
+
+ cout << "Failable monad test... " << endl;
+ failable<int> ooops = mkfailure<int>("test");
+ assert(reason(ooops) == "test");
+ assert(ooops >> failableF >> failableG == ooops);
+ return true;
+}
+
+struct tickInc {
+ const double v;
+ tickInc(const double v) : v(v) {
+ }
+ const scp<int, double> operator()(int s) const {
+ return scp<int, double>(s + 1, v);
+ }
+};
+
+const state<int, double> tick(const double v) {
+ return transformer<int, double>(tickInc(v));
+}
+
+const state<int, double> stateF(const double v) {
+ return result<int, double>(v * 2.0) >> tick;
+}
+
+const state<int, double> stateG(const double v) {
+ return result<int, double>(v + 5);
+}
+
+const state<int, double> stateH(const double v) {
+ return stateF(v) >> stateG;
+}
+
+bool testStateMonad() {
+ const lambda<state<int, double>(const double)> r(result<int, double>);
+
+ state<int, double> m = result<int, double>(2.0);
+ assert((m >> stateF)(0) == stateF(2.0)(0));
+ assert(1 == (int)(m >> stateF)(0));
+ assert((m >> r)(0) == m(0));
+ assert((m >> stateF >> stateG)(0) == (m >> stateH)(0));
+
+ return true;
+}
+
+bool testDynLib() {
+ const lib dl(string(".libs/libdynlib-test") + dynlibExt);
+ const failable<lambda<int(const int)> > sq(dynlambda<int(const int)>("csquare", dl));
+ assert(hasContent(sq));
+ lambda<int(const int)> l(content(sq));
+ assert(l(2) == 4);
+
+ const failable<lambda<lambda<int(const int)>()> > sql(dynlambda<lambda<int(const int)>()>("csquarel", dl));
+ assert(hasContent(sql));
+ lambda<lambda<int(const int)>()> ll(content(sql));
+ assert(ll()(3) == 9);
+ return true;
+}
+
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::testLambda();
+ tuscany::testLambdaGC();
+ tuscany::testCons();
+ tuscany::testListGC();
+ tuscany::testOut();
+ tuscany::testEquals();
+ tuscany::testLength();
+ tuscany::testAppend();
+ tuscany::testComplex();
+ tuscany::testMap();
+ tuscany::testReduce();
+ tuscany::testFilter();
+ tuscany::testMember();
+ tuscany::testReverse();
+ tuscany::testListRef();
+ tuscany::testAssoc();
+ tuscany::testZip();
+ tuscany::testTokenize();
+ tuscany::testSeq();
+ tuscany::testValue();
+ tuscany::testValueGC();
+ tuscany::testTree();
+ tuscany::testTreeAssoc();
+ tuscany::testCppPerf();
+ tuscany::testIdMonad();
+ tuscany::testMaybeMonad();
+ tuscany::testFailableMonad();
+ tuscany::testStateMonad();
+ tuscany::testDynLib();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/kernel/list.hpp b/sca-cpp/branches/gcc-4.4/kernel/list.hpp
new file mode 100644
index 0000000000..84eba6d82f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/list.hpp
@@ -0,0 +1,559 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_list_hpp
+#define tuscany_list_hpp
+
+/**
+ * Simple list functions.
+ */
+
+#include <assert.h>
+#include "string.hpp"
+#include "fstream.hpp"
+#include "function.hpp"
+
+namespace tuscany {
+
+#ifdef WANT_MAINTAINER_MODE
+
+/**
+ * Debug utilities. Counters used to track instances of lists, and
+ * macro used to write the contents of a list in a string, easier to
+ * watch in a debugger than the list itself.
+ */
+long countLists = 0;
+long countILists = 0;
+long countCLists = 0;
+long countELists = 0;
+
+bool resetListCounters() {
+ countLists = countILists = countCLists = countELists = 0;
+ return true;
+}
+
+bool checkListCounters() {
+ return countLists == 0;
+}
+
+bool printListCounters() {
+ cout << "countLists " << countLists << endl;
+ cout << "countELists " << countELists << endl;
+ cout << "countILists " << countILists << endl;
+ cout << "countCLists " << countCLists << endl;
+ return true;
+}
+
+#else
+
+#define resetListCounters()
+#define checkListCounters() true
+#define printListCounters()
+
+#endif
+
+#ifdef WANT_MAINTAINER_WATCH
+
+#define debug_watchList() do { \
+ this->watch = watchList(*this); \
+ } while (0)
+
+#else
+
+#define debug_watchList();
+
+#endif
+
+/**
+ * A car/cdr lisp-like pair, base structure to construct lists.
+ */
+
+template<typename T> class list {
+public:
+
+ list() {
+ debug_inc(countLists);
+ debug_inc(countELists);
+ debug_watchList();
+ }
+
+ list(const T car, const lambda<list<T>()>& cdr) : car(car), cdr(cdr) {
+ debug_inc(countLists);
+ debug_inc(countILists);
+ debug_watchList();
+ }
+
+ list(const list& p) : car(p.car), cdr(p.cdr) {
+ debug_inc(countLists);
+ debug_inc(countCLists);
+#ifdef WANT_MAINTAINER_WATCH
+ watch = p.watch;
+#endif
+ }
+
+ const list<T>& operator=(const list<T>& p) {
+ if(this == &p)
+ return *this;
+ car = p.car;
+ cdr = p.cdr;
+#ifdef WANT_MAINTAINER_WATCH
+ watch = p.watch;
+#endif
+ return *this;
+ }
+
+ ~list() {
+ debug_dec(countLists);
+ }
+
+ const bool operator==(const list<T>& p) const {
+ if(this == &p)
+ return true;
+ if(isNil(cdr))
+ return isNil(p.cdr);
+ if(isNil(p.cdr))
+ return false;
+ if(!(car == p.car))
+ return false;
+ if(cdr == p.cdr)
+ return true;
+ return cdr() == p.cdr();
+ }
+
+ const bool operator<(const list<T>& p) const {
+ if(this == &p)
+ return false;
+ if (isNil(cdr))
+ return !isNil(p.cdr);
+ if (isNil(p.cdr))
+ return false;
+ if (car < p.car)
+ return true;
+ if (car != p.car)
+ return false;
+ return cdr() < p.cdr();
+ }
+
+ const bool operator>(const list<T>& p) const {
+ if(this == &p)
+ return false;
+ if (isNil(cdr))
+ return false;
+ if (isNil(p.cdr))
+ return true;
+ if (car > p.car)
+ return true;
+ if (car != p.car)
+ return false;
+ return cdr() > p.cdr();
+ }
+
+ const bool operator!=(const list<T>& p) const {
+ return !this->operator==(p);
+ }
+
+ operator const list<list<T> >() const {
+ return (list<list<T> >)T(*this);
+ }
+
+private:
+#ifdef WANT_MAINTAINER_WATCH
+ template<typename X> friend const string watchList(const list<X>& p);
+ string watch;
+#endif
+
+ template<typename X> friend const bool isNil(const list<X>& p);
+ template<typename X> friend const X car(const list<X>& p);
+ template<typename X> friend const list<X> cdr(const list<X>& p);
+
+ T car;
+ lambda<list<T>()> cdr;
+};
+
+#ifdef WANT_MAINTAINER_WATCH
+
+/**
+ * Debug utility used to write the contents of a list to a string, easier
+ * to watch than the list itself in a debugger.
+ */
+template<typename T> const string watchList(const list<T>& p) {
+ if(isNil(p))
+ return "()";
+ odebugstream os;
+ os << "(" << car(p) << " ...)";
+ return str(os);
+}
+
+#endif
+
+/**
+ * Returns true if the given list is nil.
+ */
+template<typename T> const bool isNil(const list<T>& p) {
+ return isNil(p.cdr);
+}
+
+/**
+ * Write a list to an output stream.
+ */
+template<typename T> ostream& writeHelper(ostream& out, const list<T>& l) {
+ if (isNil(l))
+ return out;
+ out << " " << car(l);
+ return writeHelper(out, cdr(l));
+}
+
+template<typename T> ostream& operator<<(ostream& out, const list<T>& l) {
+ if(isNil(l))
+ return out << "()";
+ out << "(" << car(l);
+ writeHelper<T>(out, cdr(l));
+ return out << ")";
+}
+
+/**
+ * Construct a (lazy) list from a value and a lambda function that returns the cdr.
+ */
+template<typename T> const list<T> cons(const T& car, const lambda<list<T>()>& cdr) {
+ return list<T> (car, cdr);
+}
+
+/**
+ * Construct a list from a value and a cdr list.
+ */
+template<typename T> const list<T> cons(const T& car, const list<T>& cdr) {
+ return list<T> (car, result(cdr));
+}
+
+/**
+ * Cons variations for use with the reduce and reduceRight functions.
+ */
+template<typename T> const list<T> lcons(const list<T>& cdr, const T& car) {
+ return cons<T>(car, cdr);
+}
+
+template<typename T> const list<T> rcons(const T& car, const list<T>& cdr) {
+ return cons<T>(car, cdr);
+}
+
+/**
+ * Construct a list of one value.
+ */
+template<typename T> const list<T> mklist(const T& car) {
+ return list<T> (car, result(list<T> ()));
+}
+
+/**
+ * Construct a list of two values.
+ */
+template<typename T> const list<T> mklist(const T& a, const T& b) {
+ return cons(a, mklist(b));
+}
+
+/**
+ * Construct a list of three values.
+ */
+template<typename T> const list<T> mklist(const T& a, const T& b, const T& c) {
+ return cons(a, cons(b, mklist(c)));
+}
+
+/**
+ * Construct a list of four values.
+ */
+template<typename T> const list<T> mklist(const T& a, const T& b, const T& c, const T& d) {
+ return cons(a, cons(b, cons(c, mklist(d))));
+}
+
+/**
+ * Construct a list of five values.
+ */
+template<typename T> const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e) {
+ return cons(a, cons(b, cons(c, cons(d, mklist(e)))));
+}
+
+/**
+ * Construct a list of six values.
+ */
+template<typename T> const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f) {
+ return cons(a, cons(b, cons(c, cons(d, cons(e, mklist(f))))));
+}
+
+/**
+ * Returns the car of a list.
+ */
+template<typename T> const T car(const list<T>& p) {
+ // Abort if trying to access the car of a nil list
+ assert(!isNil(p.cdr));
+ return p.car;
+}
+
+/**
+ * Returns the cdr of a list.
+ */
+template<typename T> const list<T> cdr(const list<T>& p) {
+ return p.cdr();
+}
+
+/**
+ * Returns the car of the cdr of a list.
+ */
+template<typename T> const T cadr(const list<T>& p) {
+ return car(cdr(p));
+}
+
+/**
+ * Returns the car of the cdr of the cdr of a list.
+ */
+template<typename T> const T caddr(const list<T>& p) {
+ return car(cdr(cdr(p)));
+}
+
+/**
+ * Returns the car of the cdr of the cdr of the cdr of a list.
+ */
+template<typename T> const T cadddr(const list<T>& p) {
+ return car(cdr(cdr(cdr(p))));
+}
+
+/**
+ * Returns the cdr of a cdr of a list.
+ */
+template<typename T> const list<T> cddr(const list<T>& p) {
+ return cdr(cdr(p));
+}
+
+/**
+ * Returns the cdr of a cdr of the cdr of a list.
+ */
+template<typename T> const list<T> cdddr(const list<T>& p) {
+ return cdr(cdr(cdr(p)));
+}
+
+/**
+ * Returns the length of a list.
+ */
+template<typename T> struct lengthRef {
+ const int operator()(const int c, const list<T>& p) {
+ if(isNil(p))
+ return c;
+ return (*this)(c + 1, cdr(p));
+ }
+};
+
+template<typename T> const int length(const list<T>& p) {
+ return lengthRef<T> ()(0, p);
+}
+
+/**
+ * Appends a list and a lambda function returning a list.
+ */
+template<typename T> struct appendCdr {
+ const list<T> a;
+ const lambda<list<T>()> fb;
+ appendCdr(const list<T>& a, const lambda<list<T>()>& fb) :
+ a(a), fb(fb) {
+ }
+ const list<T> operator()() const {
+ return append(a, fb);
+ }
+};
+
+template<typename T> const list<T> append(const list<T>&a, const lambda<list<T>()>& fb) {
+ if(isNil(a))
+ return fb();
+
+ return cons<T>(car(a), appendCdr<T> (cdr(a), fb));
+}
+
+/**
+ * Appends two lists.
+ */
+template<typename T> const list<T> append(const list<T>&a, const list<T>& b) {
+ return append(a, result(b));
+}
+
+/**
+ * Append a value to a list.
+ */
+template<typename T> const list<T> operator+(const list<T>& l, const T& v) {
+ return append(l, mklist(v));
+}
+
+template<typename T, typename V> const list<T> operator+(const list<T>& l, const V& v) {
+ return append(l, mklist<T>(v));
+}
+
+/**
+ * Map a lambda function on a list.
+ */
+template<typename T, typename R> const list<R> map(const lambda<R(const T)>& f, const list<T>& p) {
+ if(isNil(p))
+ return list<R> ();
+ return cons(f(car(p)), map(f, cdr(p)));
+}
+
+/**
+ * Run a reduce lambda function on a list.
+ */
+template<typename T, typename R> struct reduceAccumulate {
+ const lambda<R(const R&, const T&)> f;
+ reduceAccumulate(const lambda<R(const R, const T)>& f) :
+ f(f) {
+ }
+ R operator()(const R& acc, const list<T>& p) const {
+ if(isNil(p))
+ return acc;
+ return (*this)(f(acc, car(p)), cdr(p));
+ }
+};
+
+template<typename T, typename R> const R reduce(const lambda<R(const R, const T)>& f, const R& initial, const list<T>& p) {
+ return reduceAccumulate<T, R> (f)(initial, p);
+}
+
+template<typename T, typename R> struct reduceRightAccumulate {
+ const lambda<R(const T&, const R&)> f;
+ reduceRightAccumulate(const lambda<R(const T, const R)>& f) :
+ f(f) {
+ }
+ R operator()(const list<T>& p, const R& acc) const {
+ if(isNil(p))
+ return acc;
+ return (*this)(cdr(p), f(car(p), acc));
+ }
+};
+
+template<typename T, typename R> const R reduceRight(const lambda<R(const T, const R)>& f, const R& initial, const list<T>& p) {
+ return reduceRightAccumulate<T, R> (f)(p, initial);
+}
+
+/**
+ * Run a filter lambda function on a list.
+ */
+template<typename T> const list<T> filter(const lambda<bool(const T)>& f, const list<T>& p) {
+ if(isNil(p))
+ return list<T> ();
+ if(f(car(p))) {
+ const lambda<list<T>(const lambda<bool(const T)>, const list<T>)> ff(filter<T>);
+ return cons(car(p), curry(ff, f, cdr(p)));
+ }
+ return filter(f, cdr(p));
+}
+
+/**
+ * Returns a list pointing to a member of a list.
+ */
+template<typename T> const list<T> member(const T& t, const list<T>& p) {
+ if(isNil(p))
+ return list<T> ();
+ if(t == car(p))
+ return p;
+ return member(t, cdr(p));
+}
+
+/**
+ * Reverse a list.
+ */
+template<typename T> const list<T> reverseIter(const list<T>& acc, const list<T>& p) {
+ if(isNil(p))
+ return acc;
+ return reverseIter(cons(car(p), acc), cdr(p));
+}
+
+template<typename T> const list<T> reverse(const list<T>& p) {
+ return reverseIter(list<T> (), p);
+}
+
+template<typename T> const list<T> seq(const T& start, const T& end);
+
+template<typename T> struct seqGenerate {
+ const T start;
+ const T end;
+ seqGenerate(const T& start, const T&end) :
+ start(start), end(end) {
+ }
+ const list<T> operator()() const {
+ return seq<T> (start, end);
+ }
+};
+
+/**
+ * Returns a sequence of values between the given bounds.
+ */
+template<typename T> const list<T> seq(const T& start, const T& end) {
+ if(start == end)
+ return mklist(start);
+ if(start < end)
+ return cons<T>(start, seqGenerate<T> (start + 1, end));
+ return cons<T>(start, seqGenerate<T> (start - 1, end));
+}
+
+/**
+ * Returns the i-th element of a list.
+ */
+template<typename T> const T listRef(const list<T>& l, const int i) {
+ if (i == 0)
+ return car(l);
+ return listRef(cdr(l), i - 1);
+}
+
+/**
+ * Returns the first pair matching a key from a list of key value pairs.
+ */
+template<typename T> const list<T> assoc(const T& k, const list<list<T> >& p) {
+ if(isNil(p))
+ return list<T> ();
+ if(k == car(car(p)))
+ return car(p);
+ return assoc(k, cdr(p));
+}
+
+/**
+ * Returns a list of lists containing elements from two input lists.
+ */
+template<typename T> const list<list<T> > zip(const list<T>& a, const list<T>& b) {
+ if (isNil(a) || isNil(b))
+ return list<list<T> >();
+ return cons<list<T> >(mklist<T>(car(a), car(b)), zip(cdr(a), cdr(b)));
+}
+
+/**
+ * Converts a list of key value pairs to a list containing the list of keys and the list of values.
+ */
+template<typename T> const list<T> unzipKeys(const list<list<T> >& l) {
+ if (isNil(l))
+ return list<T>();
+ return cons(car(car(l)), unzipKeys(cdr(l)));
+}
+
+template<typename T> const list<T> unzipValues(const list<list<T> >& l) {
+ if (isNil(l))
+ return list<T>();
+ return cons(cadr(car(l)), unzipValues(cdr(l)));
+}
+
+template<typename T> const list<list<T> > unzip(const list<list<T> >& l) {
+ return mklist<list<T> >(unzipKeys(l), unzipValues(l));
+}
+
+}
+
+#endif /* tuscany_list_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/mem-test.cpp b/sca-cpp/branches/gcc-4.4/kernel/mem-test.cpp
new file mode 100644
index 0000000000..b1164a5a36
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/mem-test.cpp
@@ -0,0 +1,162 @@
+/*
+ * 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 memory allocation functions.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "gc.hpp"
+#include "function.hpp"
+#include "perf.hpp"
+
+namespace tuscany {
+
+int countElements = 0;
+int maxElements = 0;
+
+class Element {
+public:
+ Element() : i(0) {
+ countElements++;
+ if (countElements > maxElements)
+ maxElements = countElements;
+ }
+
+ Element(int i) : i(i) {
+ countElements++;
+ if (countElements > maxElements)
+ maxElements = countElements;
+ }
+
+ Element(const Element& o) : i(o.i) {
+ countElements++;
+ if (countElements > maxElements)
+ maxElements = countElements;
+ }
+
+ ~Element() {
+ countElements--;
+ }
+
+ const bool operator==(const Element& o) const {
+ return o.i == i;
+ }
+
+private:
+ friend ostream& operator<<(ostream& out, const Element& v);
+
+ int i;
+ char c[20];
+};
+
+ostream& operator<<(ostream& out, const Element& v) {
+ out << v.i ;
+ return out;
+}
+
+bool poolAlloc(Element** p, const int count) {
+ if (count == 0)
+ return true;
+ p[count - 1] = new (gc_new<Element>()) Element();
+ return poolAlloc(p, count - 1);
+};
+
+bool poolFree(Element** p, const int count) {
+ if (count == 0)
+ return true;
+ // Do nothing to free the element, but cycle through them just
+ // to get a fair comparison with the other memory alloc tests
+ return poolFree(p, count - 1);
+};
+
+struct poolAllocPerf {
+ const int n;
+ Element** p;
+ poolAllocPerf(const int n) : n(n), p(new Element*[n]) {
+ }
+ const bool operator()() const {
+ gc_scoped_pool gc;
+ poolAlloc(p, n);
+ return true;
+ }
+};
+
+bool testPoolAllocPerf() {
+ const int count = 100000;
+ const lambda<bool()> pl = poolAllocPerf(count);
+ maxElements = 0;
+ cout << "Memory pool alloc test " << (time(pl, 1, 1) / count) << " ms" << endl;
+ assert(countElements == 0);
+ assert(maxElements == count);
+ return true;
+}
+
+bool stdAlloc(Element** p, const int count) {
+ if (count == 0)
+ return true;
+ p[count - 1] = new Element();
+ return stdAlloc(p, count - 1);
+};
+
+bool stdFree(Element** p, const int count) {
+ if (count == 0)
+ return true;
+ delete p[count -1];
+ return stdFree(p, count - 1);
+};
+
+struct stdAllocPerf {
+ const int n;
+ Element** p;
+ stdAllocPerf(const int n) : n(n), p(new Element*[n]) {
+ }
+ const bool operator()() const {
+ stdAlloc(p, n);
+ stdFree(p, n);
+ return true;
+ }
+};
+
+bool testStdAllocPerf() {
+ const int count = 100000;
+ const lambda<bool()> sl = stdAllocPerf(count);
+ maxElements = 0;
+ cout << "Memory standard alloc test " << (time(sl, 1, 1) / count) << " ms" << endl;
+ assert(countElements == 0);
+ assert(maxElements == count);
+ return true;
+}
+
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::testPoolAllocPerf();
+ tuscany::testStdAllocPerf();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/kernel/monad.hpp b/sca-cpp/branches/gcc-4.4/kernel/monad.hpp
new file mode 100644
index 0000000000..8aa4bc1662
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/monad.hpp
@@ -0,0 +1,486 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_monad_hpp
+#define tuscany_monad_hpp
+
+/**
+ * Simple monad implementations.
+ */
+
+#include "function.hpp"
+#include "string.hpp"
+#include "stream.hpp"
+
+namespace tuscany
+{
+
+/**
+ * Identity monad. Just wraps a value.
+ * To get the value in the monad, just cast it to the value type.
+ */
+template<typename V> class id {
+public:
+ id(const V& v) : v(v) {
+ }
+
+ const id<V>& operator=(const id<V>& m) {
+ if(this == &m)
+ return *this;
+ v = m.v;
+ return *this;
+ }
+
+ const bool operator!=(const id<V>& m) const {
+ return !this->operator==(m);
+ }
+
+ const bool operator==(const id<V>& m) const {
+ if (&m == this)
+ return true;
+ return v == m.v;
+ }
+
+private:
+ const V v;
+
+ template<typename X> friend const X content(const id<X>& m);
+};
+
+/**
+ * Write an identity monad to a stream.
+ */
+template<typename V> ostream& operator<<(ostream& out, const id<V>& m) {
+ out << content(m);
+ return out;
+}
+
+/**
+ * Returns the content of an identity monad.
+ */
+template<typename V> const V content(const id<V>& m) {
+ return m.v;
+}
+
+/**
+ * Return an identity monad from a value.
+ */
+template<typename V> const id<V> mkunit(const V& v) {
+ return id<V>(v);
+}
+
+template<typename V> const lambda<id<V>(const V)> unit() {
+ return mkunit<V>;
+}
+
+/**
+ * Bind a function to an identity monad. Pass the value in the monad to the function.
+ */
+template<typename R, typename V> const id<R> operator>>(const id<V>& m, const lambda<id<R>(const V)>& f) {
+ return f(content(m));
+}
+
+template<typename R, typename V> const id<R> operator>>(const id<V>& m, const id<R> (* const f)(const V)) {
+ return f(content(m));
+}
+
+/**
+ * Maybe monad. Used to represent an optional value, which may be there or not.
+ * To get the value in the monad, just cast it to the value type.
+ */
+template<typename V> class maybe {
+public:
+ maybe(const V& v) : hasv(true), v(v) {
+ }
+
+ maybe() : hasv(false) {
+ }
+
+ const maybe<V>& operator=(const maybe<V>& m) {
+ if(this == &m)
+ return *this;
+ hasv = m.hasv;
+ if (hasv)
+ v = m.v;
+ return *this;
+ }
+
+ const bool operator!=(const maybe<V>& m) const {
+ return !this->operator==(m);
+ }
+
+ const bool operator==(const maybe<V>& m) const {
+ if (this == &m)
+ return true;
+ if (!hasv)
+ return !m.hasv;
+ return m.hasv && v == m.v;
+ }
+
+private:
+ const bool hasv;
+ V v;
+
+ template<typename X> friend const bool hasContent(const maybe<X>& m);
+ template<typename X> friend const X content(const maybe<X>& m);
+};
+
+/**
+ * Write a maybe monad to a stream.
+ */
+template<typename V> ostream& operator<<(ostream& out, const maybe<V>& m) {
+ if (!hasContent(m)) {
+ out << "nothing";
+ return out;
+ }
+ out << content(m);
+ return out;
+}
+
+/**
+ * Return a maybe monad with a value in it.
+ */
+template<typename V> const maybe<V> mkjust(const V& v) {
+ return maybe<V>(v);
+}
+
+template<typename V> const lambda<maybe<V>(const V)> just() {
+ return mkjust<V>;
+}
+
+/**
+ * Returns true if a maybe monad contains a content.
+ */
+template<typename V> const bool hasContent(const maybe<V>& m) {
+ return m.hasv;
+}
+
+/**
+ * Returns the content of a maybe monad.
+ */
+template<typename V> const V content(const maybe<V>& m) {
+ return m.v;
+}
+
+/**
+ * Bind a function to a maybe monad. Passes the value in the monad to the function
+ * if present, or does nothing if there's no value.
+ */
+template<typename R, typename V> const maybe<R> operator>>(const maybe<V>& m, const lambda<maybe<R>(const V)>& f) {
+ if (!hasContent(m))
+ return m;
+ return f(content(m));
+}
+
+template<typename R, typename V> const maybe<R> operator>>(const maybe<V>& m, const maybe<R> (* const f)(const V)) {
+ if (!hasContent(m))
+ return m;
+ return f(content(m));
+}
+
+/**
+ * Failable monad. Used to represent either a success value or a failure.
+ * To get the value in the monad, just cast it to the value type.
+ * To get the failure in the monad, cast it to the failure type.
+ */
+template<typename V, typename F = string> class failable {
+public:
+ failable() : hasv(false) {
+ }
+
+ failable(const V& v) : hasv(true), v(v) {
+ }
+
+ failable(const failable<V, F>& m) : hasv(m.hasv), v(m.v), f(m.f) {
+ }
+
+ const failable<V, F>& operator=(const failable<V, F>& m) {
+ if (&m == this)
+ return *this;
+ hasv = m.hasv;
+ v = m.v;
+ f = m.f;
+ return *this;
+ }
+
+ const bool operator!=(const failable<V, F>& m) const {
+ return !this->operator==(m);
+ }
+
+ const bool operator==(const failable<V, F>& m) const {
+ if (this == &m)
+ return true;
+ if (!hasv)
+ return !m.hasv && f == m.f;
+ return m.hasv && v == m.v;
+ }
+
+private:
+ failable(const bool hasv, const F& f) : hasv(hasv), f(f) {
+ }
+
+ template<typename A, typename B> friend const bool hasContent(const failable<A, B>& m);
+ template<typename A, typename B> friend const A content(const failable<A, B>& m);
+ template<typename A, typename B> friend const B reason(const failable<A, B>& m);
+ template<typename A, typename B> friend const failable<A, B> mkfailure(const B& f);
+ template<typename A> friend const failable<A, string> mkfailure();
+
+ bool hasv;
+ V v;
+ F f;
+};
+
+/**
+ * Write a failable monad to a stream.
+ */
+template<typename V, typename F> ostream& operator<<(ostream& out, const failable<V, F>& m) {
+ if (!hasContent(m)) {
+ out << reason(m);
+ return out;
+ }
+ out << content(m);
+ return out;
+}
+
+/**
+ * Returns a failable monad with a success value in it.
+ */
+template<typename V, typename F> const failable<V, F> mksuccess(const V& v) {
+ return failable<V, F>(v);
+}
+
+template<typename V, typename F> const lambda<failable<V, F>(const V)> success() {
+ return mksuccess<V, F>;
+}
+
+/**
+ * Returns a failable monad with a failure in it.
+ */
+template<typename V, typename F> const failable<V, F> mkfailure(const F& f) {
+ debug(f, "failable::mkfailure");
+ return failable<V, F>(false, f);
+}
+
+template<typename V> const failable<V> mkfailure(const char* f) {
+ return mkfailure<V, string>(string(f));
+}
+
+template<typename V> const failable<V> mkfailure() {
+ return failable<V, string>(false, string());
+}
+
+template<typename V, typename F> const lambda<failable<V, F>(const V)> failure() {
+ return mkfailure<V, F>;
+}
+
+/**
+ * Returns true if the monad contains a content.
+ */
+template<typename V, typename F> const bool hasContent(const failable<V, F>& m) {
+ return m.hasv;
+}
+
+/**
+ * Returns the content of a failable monad.
+ */
+template<typename V, typename F> const V content(const failable<V, F>& m) {
+ return m.v;
+}
+
+/**
+ * Returns the reason for failure of a failable monad.
+ */
+template<typename V, typename F> const F reason(const failable<V, F>& m) {
+ return m.f;
+}
+
+/**
+ * Bind a function to a failable monad. Passes the success value in the monad to the function
+ * if present, or does nothing if there's no value and a failure instead.
+ */
+template<typename R, typename FR, typename V, typename FV>
+const failable<R, FR> operator>>(const failable<V, FV>& m, const lambda<failable<R, FR>(const V)>& f) {
+ if (!hasContent(m))
+ return m;
+ return f(content(m));
+}
+
+template<typename R, typename FR, typename V, typename FV>
+const failable<R, FR> operator>>(const failable<V, FV>& m, const failable<R, FR> (* const f)(const V)) {
+ if (!hasContent(m))
+ return m;
+ return f(content(m));
+}
+
+/**
+ * State + content pair data type used by the state monad.
+ */
+template<typename S, typename V> class scp {
+public:
+ scp(const S& s, const V& v) : s(s), v(v) {
+ }
+
+ operator const S() const {
+ return s;
+ }
+
+ operator const V() const {
+ return v;
+ }
+
+ const scp<S, V>& operator=(const scp<S, V>& p) {
+ if(this == &p)
+ return *this;
+ s = p.s;
+ v = p.v;
+ return *this;
+ }
+
+ const bool operator!=(const scp<S, V>& p) const {
+ return !this->operator==(p);
+ }
+
+ const bool operator==(const scp<S, V>& p) const {
+ if (this == &p)
+ return true;
+ return s == p.s && v == p.v;
+ }
+
+private:
+ const S s;
+ const V v;
+
+ template<typename A, typename B> friend const A scpstate(const scp<A, B>& m);
+ template<typename A, typename B> friend const B content(const scp<A, B>& m);
+};
+
+/**
+ * Returns the state of a state-content pair.
+ */
+template<typename S, typename V> const S scpstate(const scp<S, V>& m) {
+ return m.s;
+}
+
+/**
+ * Returns the content of a state-content pair.
+ */
+template<typename S, typename V> const S content(const scp<S, V>& m) {
+ return m.v;
+}
+
+/**
+ * State monad. Used to represent the combination of a state and a content.
+ */
+template<typename S, typename V> class state {
+public:
+ state(const lambda<scp<S, V>(const S)>& f) : f(f) {
+ }
+
+ const scp<S, V> operator()(const S& s) const {
+ return f(s);
+ }
+
+ const state<S, V>& operator=(const state<S, V>& m) {
+ if(this == &m)
+ return *this;
+ f = m.f;
+ return *this;
+ }
+
+ const bool operator!=(const state<S, V>& m) const {
+ return !this->operator==(m);
+ }
+
+ const bool operator==(const state<S, V>& m) const {
+ if (this == &m)
+ return true;
+ return f == m.f;
+ }
+
+private:
+ const lambda<scp<S, V>(const S)> f;
+};
+
+/**
+ * Write a state monad to a stream.
+ */
+template<typename S, typename V> ostream& operator<<(ostream& out, const state<S, V>& m) {
+ const S s = m;
+ const V v = m;
+ out << '(' << s << ' ' << v << ')';
+ return out;
+}
+
+/**
+ * Return a state monad carrying a result content.
+ */
+template<typename S, typename V> struct returnState {
+ const V v;
+ returnState(const V& v) : v(v) {
+ }
+ const scp<S, V> operator()(const S& s) const {
+ return scp<S, V>(s, v);
+ }
+};
+
+template<typename S, typename V> const state<S, V> result(const V& v) {
+ return state<S, V>(returnState<S, V>(v));
+}
+
+/**
+ * Return a state monad with a transformer function.
+ * A transformer function takes a state and returns an scp pair carrying a content and a
+ * new (transformed) state.
+ */
+template<typename S, typename V> const state<S, V> transformer(const lambda<scp<S, V>(const S)>& f) {
+ return state<S, V>(f);
+}
+
+/**
+ * Bind a function to a state monad. The function takes a content and returns a state
+ * monad carrying a return content.
+ */
+template<typename S, typename A, typename B> struct stateBind {
+ const state<S, A> st;
+ const lambda<state<S, B>(const A)>f;
+
+ stateBind(const state<S, A>& st, const lambda<state<S, B>(const A)>& f) : st(st), f(f) {
+ }
+
+ const scp<S, B> operator()(const S& is) const {
+ const scp<S, A> iscp = st(is);
+ const state<S, B> m = f((A)iscp);
+ return m((S)iscp);
+ }
+};
+
+template<typename S, typename A, typename B>
+const state<S, B> operator>>(const state<S, A>& st, const lambda<state<S, B>(const A)>& f) {
+ return state<S, B>(stateBind<S, A , B>(st, f));
+}
+
+template<typename S, typename A, typename B>
+const state<S, B> operator>>(const state<S, A>& st, const state<S, B> (* const f)(const A)) {
+ return state<S, B>(stateBind<S, A , B>(st, f));
+}
+
+}
+#endif /* tuscany_monad_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/parallel-test.cpp b/sca-cpp/branches/gcc-4.4/kernel/parallel-test.cpp
new file mode 100644
index 0000000000..2969dd0637
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/parallel-test.cpp
@@ -0,0 +1,166 @@
+/*
+ * 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 parallel functions.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "perf.hpp"
+#include "parallel.hpp"
+
+namespace tuscany {
+
+#ifdef WANT_THREADS
+
+int inci = 0;
+
+struct incPerf {
+ incPerf() {
+ }
+ const bool operator()() const {
+ inci = inci + 1;
+ return true;
+ }
+};
+
+int addi = 0;
+
+struct addAndFetchPerf {
+ addAndFetchPerf() {
+ }
+ const bool operator()() const {
+ __sync_add_and_fetch(&addi, 1);
+ return true;
+ }
+};
+
+int muxi = 0;
+
+struct mutexPerf {
+ pthread_mutex_t* mutex;
+ mutexPerf(pthread_mutex_t* mutex) : mutex(mutex) {
+ }
+ const bool operator()() const {
+ pthread_mutex_lock(mutex);
+ muxi = muxi + 1;
+ pthread_mutex_unlock(mutex);
+ return true;
+ }
+};
+
+__thread int tlsi = 0;
+
+struct tlsPerf {
+ tlsPerf() {
+ }
+ const bool operator()() const {
+ tlsi = tlsi + 1;
+ return true;
+ }
+};
+
+bool testAtomicPerf() {
+ const int count = 100000;
+ {
+ const lambda<bool()> l = incPerf();
+ cout << "Non-atomic inc test " << time(l, 1000, count) << " ms" << endl;
+ assert(inci == count + 1000);
+ }
+ {
+ const lambda<bool()> l = addAndFetchPerf();
+ cout << "Atomic inc test " << time(l, 1000, count) << " ms" << endl;
+ assert(addi == count + 1000);
+ }
+ {
+ pthread_mutex_t mutex;
+ pthread_mutex_init(&mutex, NULL);
+ const lambda<bool()> l = mutexPerf(&mutex);
+ cout << "Locked inc test " << time(l, 1000, count) << " ms" << endl;
+ assert(muxi == count + 1000);
+ pthread_mutex_destroy(&mutex);
+ }
+ {
+ const lambda<bool()> l = tlsPerf();
+ cout << "Thread local inc test " << time(l, 1000, count) << " ms" << endl;
+ assert(tlsi == count + 1000);
+ }
+ return true;
+}
+
+const int mtsquare(const int x) {
+ for(int i = 0; i < 10000000; i++)
+ ;
+ return x * x;
+}
+
+bool checkResults(const list<future<int> > r, int i) {
+ if (isNil(r))
+ return true;
+ assert(car(r) == i * i);
+ checkResults(cdr(r), i + 1);
+ return true;
+}
+
+const list<future<int> > submitSquares(worker& w, const int max, const int i) {
+ if (i == max)
+ return list<future<int> >();
+ const lambda<int()> func = curry(lambda<int(const int)> (mtsquare), i);
+ return cons(submit(w, func), submitSquares(w, max, i + 1));
+}
+
+bool testWorker() {
+ worker w(20);
+ {
+ const lambda<int()> func = curry(lambda<int(const int)> (mtsquare), 2);
+ assert(submit(w, func) == 4);
+ }
+ {
+ const int max = 20;
+ const list<future<int> > r(submitSquares(w, max, 0));
+ checkResults(r, 0);
+ }
+ shutdown(w);
+ return true;
+}
+
+#endif
+
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+#ifdef WANT_THREADS
+ tuscany::testAtomicPerf();
+ tuscany::testWorker();
+#else
+ tuscany::cout << "Skipped multi-thread tests" << tuscany::endl;
+#endif
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/kernel/parallel.hpp b/sca-cpp/branches/gcc-4.4/kernel/parallel.hpp
new file mode 100644
index 0000000000..09cf0df9a3
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/parallel.hpp
@@ -0,0 +1,319 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_parallel_hpp
+#define tuscany_parallel_hpp
+
+/**
+ * Simple parallel work execution functions.
+ */
+
+#ifdef WANT_THREADS
+#include <pthread.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#endif
+
+#include "function.hpp"
+#include "list.hpp"
+
+namespace tuscany {
+
+#ifdef WANT_THREADS
+
+/**
+ * Returns the current thread id.
+ */
+unsigned int threadId() {
+ return syscall(__NR_gettid);
+}
+
+/**
+ * Represents a value which will be know in the future.
+ */
+template<typename T> class future {
+
+private:
+ template<typename X> class futureValue {
+ public:
+ futureValue() : hasValue(false) {
+ pthread_mutex_init(&valueMutex, NULL);
+ pthread_cond_init(&valueCond, NULL);
+ }
+
+ futureValue(const futureValue& fv) : valueMutex(fv.valueMutex), valueCond(fv.valueCond), hasValue(fv.hasValue), value(fv.value) {
+ }
+
+ ~futureValue() {
+ //pthread_mutex_destroy(&valueMutex);
+ //pthread_cond_destroy(&valueCond);
+ }
+
+ bool set(const T& v) {
+ pthread_mutex_lock(&valueMutex);
+ if(hasValue) {
+ pthread_mutex_unlock(&valueMutex);
+ return false;
+ }
+ hasValue = true;
+ value = v;
+ pthread_mutex_unlock(&valueMutex);
+ pthread_cond_broadcast(&valueCond);
+ return true;
+ }
+
+ const T get() {
+ pthread_mutex_lock(&valueMutex);
+ while(!hasValue) {
+ pthread_cond_wait(&valueCond, &valueMutex);
+ }
+ const T& v = value;
+ pthread_mutex_unlock(&valueMutex);
+ return v;
+ }
+
+ private:
+ pthread_mutex_t valueMutex;
+ pthread_cond_t valueCond;
+ bool hasValue;
+ X value;
+ };
+
+ gc_ptr<futureValue<T> > fvalue;
+
+ template<typename X> friend const X get(const future<X>& f);
+ template<typename X> friend bool set(const future<X>& f, const X& v);
+
+public:
+ future() : fvalue(new (gc_new<futureValue<T> >()) futureValue<T>()) {
+ }
+
+ ~future() {
+ }
+
+ future(const future& f) : fvalue(f.fvalue) {
+ }
+
+ const future& operator=(const future& f) {
+ if (&f == this)
+ return *this;
+ fvalue = f.fvalue;
+ return *this;
+ }
+
+ const future& operator=(const T& v) const {
+ fvalue->set(v);
+ return *this;
+ }
+
+ operator const T() const {
+ return fvalue->get();
+ }
+};
+
+/**
+ * A bounded thread safe queue.
+ */
+template<typename T> class wqueue {
+public:
+ wqueue(int max) : max(max), size(0), tail(0), head(0), values(new (gc_anew<T>(max)) T[max]) {
+ pthread_mutex_init(&mutex, NULL);
+ pthread_cond_init(&full, NULL);
+ pthread_cond_init(&empty, NULL);
+ }
+
+ wqueue(const wqueue& wq) : max(wq.max), size(wq.size), tail(wq.tail), head(wq.head), mutex(wq.mutex), full(wq.full), empty(wq.empty), values(wq.values) {
+ }
+
+ ~wqueue() {
+ //pthread_mutex_destroy(&mutex);
+ //pthread_cond_destroy(&full);
+ //pthread_cond_destroy(&empty);
+ }
+
+private:
+ const int max;
+ int size;
+ int tail;
+ int head;
+ pthread_mutex_t mutex;
+ pthread_cond_t full;
+ pthread_cond_t empty;
+ gc_ptr<T> values;
+
+ template<typename X> friend const int enqueue(wqueue<X>& q, const X& v);
+ template<typename X> friend const X dequeue(wqueue<X>& q);
+};
+
+/**
+ * Adds an element to the tail of the queue.
+ */
+template<typename T> const int enqueue(wqueue<T>&q, const T& v) {
+ pthread_mutex_lock(&q.mutex);
+ while(q.size == q.max)
+ pthread_cond_wait(&q.full, &q.mutex);
+ q.values[q.tail] = v;
+ q.tail = (q.tail + 1) % q.max;
+ q.size++;
+ pthread_mutex_unlock(&q.mutex);
+ pthread_cond_broadcast(&q.empty);
+ return q.size;
+}
+
+/**
+ * Returns the element at the head of the queue.
+ */
+template<typename T> const T dequeue(wqueue<T>& q) {
+ pthread_mutex_lock(&q.mutex);
+ while(q.size == 0)
+ pthread_cond_wait(&q.empty, &q.mutex);
+ const T v = q.values[q.head];
+ q.head = (q.head + 1) % q.max;
+ q.size--;
+ pthread_mutex_unlock(&q.mutex);
+ pthread_cond_broadcast(&q.full);
+ return v;
+}
+
+/**
+ * The worker thread function.
+ */
+void *workerThreadFunc(void *arg) {
+ int ost;
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &ost);
+ int ot;
+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &ot);
+
+ wqueue<lambda<bool()> >* work = reinterpret_cast<wqueue<lambda<bool()> >*>(arg);
+ while(dequeue(*work)())
+ ;
+ return NULL;
+}
+
+/**
+ * Returns a list of worker threads.
+ */
+const list<pthread_t> workerThreads(wqueue<lambda<bool()> >& wqueue, const int count) {
+ if (count == 0)
+ return list<pthread_t>();
+ pthread_t thread;
+ pthread_create(&thread, NULL, workerThreadFunc, &wqueue);
+ return cons(thread, workerThreads(wqueue, count - 1));
+}
+
+/**
+ * A worker, implemented with a work queue and a pool of threads.
+ */
+class worker {
+private:
+
+ // The worker holds a reference to a sharedWorker, to avoid non-thread-safe
+ // copies of the queue and thread pool when a worker is copied
+ class sharedWorker {
+ public:
+ sharedWorker(int max) : work(wqueue<lambda<bool()> >(max)), threads(workerThreads(work, max)) {
+ }
+
+ wqueue<lambda<bool()> > work;
+ const list<pthread_t> threads;
+ };
+
+public:
+ worker(int max) : w(*(new (gc_new<sharedWorker>()) sharedWorker(max))) {
+ }
+
+ worker(const worker& wk) : w(wk.w) {
+ }
+
+private:
+ sharedWorker& w;
+
+ template<typename X> friend const future<X> submit(worker& w, const lambda<X()>& func);
+ friend const bool shutdown(worker& w);
+ friend const bool cancel(worker& w);
+};
+
+/**
+ * Function used to wrap work submitted to a worker.
+ */
+template<typename R> bool submitFunc(const lambda<R()>& func, const future<R>& fut) {
+ fut = func();
+ return true;
+}
+
+/**
+ * Submits work to a worker.
+ */
+template<typename R> const future<R> submit(worker& w, const lambda<R()>& func) {
+ const future<R> fut;
+ const lambda<bool()> f = curry(lambda<bool(const lambda<R()>, future<R>)>(submitFunc<R>), func, fut);
+ enqueue(w.w.work, f);
+ return fut;
+}
+
+/**
+ * Enqueues shutdown requests.
+ */
+const bool shutdownEnqueue(const list<pthread_t>& threads, wqueue<lambda<bool()> >& work) {
+ if (isNil(threads))
+ return true;
+ enqueue(work, result(false));
+ return shutdownEnqueue(cdr(threads), work);
+}
+
+/**
+ * Waits for shut down threads to terminate.
+ */
+const bool shutdownJoin(const list<pthread_t>& threads) {
+ if (isNil(threads))
+ return true;
+ pthread_join(car(threads), NULL);
+ return shutdownJoin(cdr(threads));
+}
+
+/**
+ * Shutdown a worker.
+ */
+const bool shutdown(worker& w) {
+ shutdownEnqueue(w.w.threads, w.w.work);
+ shutdownJoin(w.w.threads);
+ return true;
+}
+
+/**
+ * Cancel a worker.
+ */
+const bool cancel(const list<pthread_t>& threads) {
+ if (isNil(threads))
+ return true;
+ pthread_cancel(car(threads));
+ return cancel(cdr(threads));
+}
+
+const bool cancel(worker& w) {
+ cancel(w.w.threads);
+ return true;
+}
+
+#endif
+
+}
+#endif /* tuscany_parallel_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/perf.hpp b/sca-cpp/branches/gcc-4.4/kernel/perf.hpp
new file mode 100644
index 0000000000..f5004d015b
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/perf.hpp
@@ -0,0 +1,68 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_perf_hpp
+#define tuscany_perf_hpp
+
+/**
+ * Functions to help measure performance.
+ */
+
+#include <sys/time.h>
+#include <time.h>
+
+#include "function.hpp"
+
+namespace tuscany
+{
+
+/**
+ * Measure the time required to perform a function in msec.
+ */
+struct timeLambda {
+ const lambda<bool()> f;
+ timeLambda(const lambda<bool()>& f) : f(f) {
+ }
+ bool operator()(const long count) const {
+ if (count == 0)
+ return true;
+ f();
+ (*this)(count - 1);
+ return true;
+ }
+};
+
+const double time(const lambda<bool()>& f, const long warmup, const long count) {
+ const lambda<bool(long)> tl = timeLambda(f);
+ struct timeval start;
+ struct timeval end;
+
+ tl(warmup);
+ gettimeofday(&start, NULL);
+ tl(count);
+ gettimeofday(&end, NULL);
+
+ const long t = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000);
+ return (double)t / (double)count;
+}
+
+}
+#endif /* tuscany_perf_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/sstream.hpp b/sca-cpp/branches/gcc-4.4/kernel/sstream.hpp
new file mode 100644
index 0000000000..f5006606dd
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/sstream.hpp
@@ -0,0 +1,240 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_sstream_hpp
+#define tuscany_sstream_hpp
+
+/**
+ * Char buffer based streams.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <memory.h>
+#include "string.hpp"
+#include "stream.hpp"
+#include "list.hpp"
+
+namespace tuscany {
+
+/**
+ * Instrumentable memcpy.
+ */
+void* stream_memcpy(void* t, const void* s, const size_t n) {
+ return memcpy(t, s, n);
+}
+
+/**
+ * Output stream backed by a char buffer.
+ */
+class ostringstream : public ostream {
+public:
+ ostringstream() : len(0) {
+ }
+
+ ~ostringstream() {
+ }
+
+ ostringstream(const ostringstream& os) {
+ len = os.len;
+ buf = os.buf;
+ }
+
+ ostringstream& vprintf(const char* fmt, ...) {
+ va_list args;
+ va_start (args, fmt);
+ string s;
+ s.len = vsnprintf(NULL, 0, fmt, args);
+ s.buf = gc_cnew(s.len + 1);
+ vsnprintf(s.buf, s.len + 1, fmt, args);
+ buf = cons(s, buf);
+ len += s.len;
+ va_end (args);
+ return *this;
+ }
+
+ ostringstream& write(const string& s) {
+ buf = cons(s, buf);
+ len += s.len;
+ return *this;
+ }
+
+ ostringstream& flush() {
+ return *this;
+ }
+
+private:
+ static const bool strHelper(const list<string> l, char* buf) {
+ if (isNil(l))
+ return true;
+ const string c = car(l);
+ char* b = buf - length(c);
+ memcpy(b, c_str(c), length(c));
+ return strHelper(cdr(l), b);
+ }
+
+ const string str() {
+ if (isNil(buf))
+ return string();
+ string s;
+ s.len = len;
+ s.buf = gc_cnew(s.len + 1);
+ strHelper(buf, s.buf + len);
+ s.buf[s.len] = '\0';
+ return s;
+ }
+
+ friend const string str(ostringstream& os);
+
+ int len;
+ list<string> buf;
+};
+
+/**
+ * Return a string representation of a stream.
+ */
+const string str(ostringstream& os) {
+ return os.str();
+}
+
+/**
+ * Input stream backed by a char buffer
+ */
+class istringstream : public istream {
+public:
+ istringstream(const string& s) {
+ cur = 0;
+ const int slen = length(s);
+ len = slen;
+ buf = c_str(s);
+ }
+
+ ~istringstream() {
+ }
+
+ istringstream(const istringstream& is) {
+ len = is.len;
+ cur = is.cur;
+ buf = is.buf;
+ }
+
+ const int read(void* b, int size) {
+ const int n = len - cur;
+ if (n == 0)
+ return 0;
+ if (n > size) {
+ stream_memcpy(b, buf + cur, size);
+ cur = cur + size;
+ return size;
+ }
+ stream_memcpy(b, buf + cur, n);
+ cur = cur + n;
+ return n;
+ }
+
+ const bool eof() {
+ return cur == len;
+ }
+
+ const bool fail() {
+ return false;
+ }
+
+ const int get() {
+ if (eof())
+ return -1;
+ const int c = buf[cur];
+ cur += 1;
+ return c;
+ }
+
+ const int peek() {
+ if (eof())
+ return -1;
+ return buf[cur];
+ }
+
+private:
+ int len;
+ int cur;
+ const char* buf;
+};
+
+/**
+ * Tokenize a string into a list of strings.
+ */
+const list<string> tokenize(const char* sep, const string& str) {
+ struct nested {
+ static const list<string> tokenize(const char* sep, const string& str, const int start = 0) {
+ if (start >= length(str))
+ return list<string>();
+ const int i = find(str, sep, start);
+ if (i == length(str))
+ return mklist(string(substr(str, start)));
+ return cons(string(substr(str, start, i - start)), tokenize(sep, str, i + 1));
+ }
+ };
+ return nested::tokenize(sep, str, 0);
+}
+
+/**
+ * Returns a lazy list view of an input stream.
+ */
+struct ilistRead{
+ istream &is;
+ ilistRead(istream& is) : is(is) {
+ }
+ const list<string> operator()() {
+ char buffer[1024];
+ const int n = read(is, buffer, sizeof(buffer));
+ if (n ==0)
+ return list<string>();
+ return cons(string(buffer, n), (*this)());
+ }
+};
+
+const list<string> streamList(istream& is) {
+ return ilistRead(is)();
+}
+
+/**
+ * Fragment the first element of a list of strings to fit the given max length.
+ */
+const list<string> fragment(list<string> l, int max) {
+ const string s = car(l);
+ if (length(s) <= max)
+ return l;
+ return cons(substr(s, 0, max), cons(substr(s, max), cdr(l)));
+}
+
+/**
+ * Write a list of strings to an output stream.
+ */
+ostream& write(const list<string>& l, ostream& os) {
+ if(isNil(l))
+ return os;
+ os << car(l);
+ return write(cdr(l), os);
+}
+
+}
+
+#endif /* tuscany_sstream_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/stream.hpp b/sca-cpp/branches/gcc-4.4/kernel/stream.hpp
new file mode 100644
index 0000000000..32b754f315
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/stream.hpp
@@ -0,0 +1,200 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_stream_hpp
+#define tuscany_stream_hpp
+
+/**
+ * Basic stream type and functions.
+ */
+
+#include <stdarg.h>
+#include "config.hpp"
+#include "gc.hpp"
+#include "string.hpp"
+
+namespace tuscany {
+
+/**
+ * Base output stream.
+ */
+class ostream {
+public:
+ virtual ostream& vprintf(const char* fmt, ...) = 0;
+ virtual ostream& write(const string& s) = 0;
+ virtual ostream& flush() = 0;
+};
+
+/**
+ * Flush a stream.
+ */
+ostream& flush(ostream& os) {
+ return os.flush();
+}
+
+/**
+ * Write simple values to a stream.
+ */
+ostream& operator<<(ostream& os, const char* v) {
+ return os.vprintf("%s", v);
+}
+
+ostream& operator<<(ostream& os, const unsigned char* v) {
+ return os.vprintf("%s", v);
+}
+
+ostream& operator<<(ostream& os, const char v) {
+ return os.vprintf("%c", v);
+}
+
+ostream& operator<<(ostream& os, const int v) {
+ return os.vprintf("%d", v);
+}
+
+ostream& operator<<(ostream& os, const unsigned int v) {
+ return os.vprintf("%u", v);
+}
+
+ostream& operator<<(ostream& os, const long int v) {
+ return os.vprintf("%ld", v);
+}
+
+ostream& operator<<(ostream& os, const long unsigned int v) {
+ return os.vprintf("%lu", v);
+}
+
+ostream& operator<<(ostream& os, const double v) {
+ return os.vprintf("%g", v);
+}
+
+ostream& operator<<(ostream& os, const void* v) {
+ return os.vprintf("%p", v);
+}
+
+ostream& operator<<(ostream& os, const string& v) {
+ return os.write(v);
+}
+
+class stream_endl {
+} endl;
+
+ostream& operator<<(ostream& os, unused const stream_endl e) {
+ os.vprintf("%s", "\n");
+ return os.flush();
+}
+
+/*
+ * Input stream.
+ */
+class istream {
+public:
+ virtual const int read(void* buf, int size) = 0;
+ virtual const bool eof() = 0;
+ virtual const bool fail() = 0;
+ virtual const int get() = 0;
+ virtual const int peek() = 0;
+};
+
+/**
+ * Read from an input stream.
+ */
+const int read(istream& is, void * buf, int size) {
+ return is.read(buf, size);
+}
+
+/**
+ * Return true if the end of an input stream has been reached.
+ */
+const bool eof(istream& is) {
+ return is.eof();
+}
+
+/**
+ * Return true if an input stream can't be accessed.
+ */
+const bool fail(istream& is) {
+ return is.fail();
+}
+
+/**
+ * Read a character from a stream.
+ */
+const int get(istream& is) {
+ return is.get();
+}
+
+/**
+ * Peek a character from a stream.
+ */
+const int peek(istream& is) {
+ return is.peek();
+}
+
+template<typename T> ostream& operator<<(ostream& out, const gc_ptr<T>& p) {
+ return out << p.ptr;
+}
+
+#ifdef WANT_MAINTAINER_MODE
+
+/**
+ * Debug stream implementation with no dependencies on anything else.
+ */
+class odebugstream : public ostream {
+public:
+ odebugstream() {
+ }
+
+ odebugstream& vprintf(const char* fmt, ...) {
+ va_list args;
+ va_start (args, fmt);
+ string s;
+ s.len = vsnprintf(NULL, 0, fmt, args);
+ s.buf = gc_cnew(s.len + 1);
+ vsnprintf(s.buf, s.len + 1, fmt, args);
+ buf = buf + s;
+ va_end (args);
+ return *this;
+ }
+
+ odebugstream& write(const string& s) {
+ buf = buf + s;
+ return *this;
+ }
+
+ odebugstream& flush() {
+ return *this;
+ }
+
+private:
+ friend const string str(odebugstream& os);
+
+ string buf;
+};
+
+const string str(odebugstream& os) {
+ return os.buf;
+}
+
+#endif
+
+}
+
+#endif /* tuscany_stream_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/string-test.cpp b/sca-cpp/branches/gcc-4.4/kernel/string-test.cpp
new file mode 100644
index 0000000000..323756c7e4
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/string-test.cpp
@@ -0,0 +1,196 @@
+/*
+ * 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 string functions.
+ */
+
+#include <assert.h>
+#include <string>
+#include "sstream.hpp"
+#include "string.hpp"
+#include "list.hpp"
+#include "perf.hpp"
+
+namespace tuscany {
+
+bool testCopies() {
+ resetStringCopyCounters();
+ string x("abcd");
+ assert(checkStringCopyCounters(1));
+ resetStringCopyCounters();
+ string y = string("abcd");
+ assert(checkStringCopyCounters(1));
+ resetStringCopyCounters();
+ string z = y;
+ assert(checkStringCopyCounters(0));
+ resetStringCopyCounters();
+ const list<string> pl = list<string>() + "abcd" + "efgh";
+ printStringCopyCounters();
+ resetStringCopyCounters();
+ const list<string> cl = cons<string>("efgh", mklist<string>("abcd"));
+ printStringCopyCounters();
+ return true;
+}
+
+bool testString() {
+ const string s("abcd");
+ assert(length(s) == 4);
+ assert(!strcmp(c_str(s), "abcd"));
+
+ assert(s == "abcd");
+ assert(s == string("abcd"));
+ assert(s != "zbcd");
+
+ assert(s < "zbcd");
+ assert(s < "zbc");
+ assert(s < "abzd");
+ assert(s < "abcdz");
+
+ assert(s > "Abcd");
+ assert(s > "Abc");
+ assert(s > "abCd");
+ assert(s > "Abcdz");
+
+ const string x = "abcd";
+ assert(!strcmp(c_str(x), "abcd"));
+
+ const string y = string("abcd");
+ assert(!strcmp(c_str(y), "abcd"));
+
+ assert(string("ab") + "cd" == "abcd");
+
+ assert(find("abcd", "cd") == 2);
+ assert(find("abcd", "xy") == length("abcd"));
+ assert(substr("abcdef", 4) == "ef");
+ assert(substr("abcdef", 4, 2) == "ef");
+ assert(substr("abcdef", 4, 3) == "ef");
+ assert(substr("abcdef", 6, 3) == "");
+ return true;
+}
+
+bool testStream() {
+ ostringstream os;
+ os << "ab" << "cd";
+ cout << str(os) << endl;
+ assert(str(os) == "abcd");
+
+ ostringstream cs;
+ cs << "\'";
+ assert(str(cs) == "\'");
+ cs << '\'';
+ assert(str(cs) == "\'\'");
+
+ istringstream is("abcd");
+ char b[2];
+ assert(read(is, b, 2) == 2);
+ assert(string("ab") == string(b, 2));
+ assert(eof(is) == false);
+ assert(read(is, b, 2) == 2);
+ assert(string("cd") == string(b, 2));
+ assert(eof(is) == true);
+ assert(read(is, b, 2) == 0);
+ return true;
+}
+
+std::string stdAdd(std::string& x, std::string& y) {
+ return x + y;
+}
+
+string add(string& x, string& y) {
+ return x + y;
+}
+
+char charBuffer[16384];
+
+struct addStrings{
+ const int size;
+ addStrings(const int size) : size(size) {
+ }
+ bool operator()() const {
+ const int sz = size / 4;
+ string x(charBuffer, sz);
+ string y(charBuffer, sz);
+ assert(length(add(x, y)) == sz * 2);
+ return true;
+ }
+};
+
+struct addStdStrings{
+ const int size;
+ addStdStrings(const int size) : size(size) {
+ }
+ bool operator()() const {
+ const int sz = size / 4;
+ std::string x(charBuffer, sz);
+ std::string y(charBuffer, sz);
+ assert(stdAdd(x, y).length() == (unsigned int)(sz * 2));
+ return true;
+ }
+};
+
+bool testStringPerf() {
+ memset(charBuffer, 'A', 16384);
+ charBuffer[16384] = '\0';
+
+ const int count = 100000;
+ {
+ const lambda<bool()> a16 = addStrings(16);
+ cout << "string test " << time(a16, 5, count) << " ms" << endl;
+ const lambda<bool()> a32 =addStrings(32);
+ cout << "string test " << time(a32, 5, count) << " ms" << endl;
+ const lambda<bool()> a256 =addStrings(256);
+ cout << "string test " << time(a256, 5, count) << " ms" << endl;
+ const lambda<bool()> a1024 =addStrings(1024);
+ cout << "string test " << time(a1024, 5, count) << " ms" << endl;
+ const lambda<bool()> a4096 =addStrings(4096);
+ cout << "string test " << time(a4096, 5, count) << " ms" << endl;
+ }
+ {
+ const lambda<bool()> a16 =addStdStrings(16);
+ cout << "Std string test " << time(a16, 5, count) << " ms" << endl;
+ const lambda<bool()> a32 =addStdStrings(32);
+ cout << "Std string test " << time(a32, 5, count) << " ms" << endl;
+ const lambda<bool()> a256 =addStdStrings(256);
+ cout << "Std string test " << time(a256, 5, count) << " ms" << endl;
+ const lambda<bool()> a1024 =addStdStrings(1024);
+ cout << "Std string test " << time(a1024, 5, count) << " ms" << endl;
+ const lambda<bool()> a4096 =addStdStrings(4096);
+ cout << "Std string test " << time(a4096, 5, count) << " ms" << endl;
+ }
+
+ return true;
+}
+
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::testCopies();
+ tuscany::testString();
+ tuscany::testStream();
+ tuscany::testStringPerf();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/kernel/string.hpp b/sca-cpp/branches/gcc-4.4/kernel/string.hpp
new file mode 100644
index 0000000000..931417e430
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/string.hpp
@@ -0,0 +1,291 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_string_hpp
+#define tuscany_string_hpp
+
+/**
+ * Simple and fast string type backed by a char buffer
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <memory.h>
+#include <stdio.h>
+#include "gc.hpp"
+
+namespace tuscany {
+
+#ifdef WANT_MAINTAINER_MODE
+
+/**
+ * Debug utilities. Counters used to track string copies.
+ */
+long countStringCopies = 0;
+
+bool resetStringCopyCounters() {
+ countStringCopies = 0;
+ return true;
+}
+
+bool checkStringCopyCounters(long c) {
+ return countStringCopies == c;
+}
+
+bool printStringCopyCounters() {
+ printf("countStringCopies %ld\n", countStringCopies);
+ return true;
+}
+
+#else
+
+#define resetStringCopyCounters()
+#define checkStringCopyCounters(c) true
+#define printStringCopyCounters()
+
+#endif
+
+/**
+ * Instrumented memcpy.
+ */
+void* string_memcpy(void* t, const void* s, const size_t n) {
+#ifdef WANT_MAINTAINER_MODE
+ countStringCopies += 1;
+#endif
+ return memcpy(t, s, n);
+}
+
+char stringEmptyBuffer[1] = { '\0' };
+
+/**
+ * String class. The maximum string size is specified as a template parameter.
+ */
+class string {
+public:
+ string() : len(0) {
+ buf = stringEmptyBuffer;
+ }
+
+ string(const char* s) {
+ len = strlen(s);
+ if (len == 0) {
+ buf = stringEmptyBuffer;
+ return;
+ }
+ buf = gc_cnew(len + 1);
+ string_memcpy(buf, s, len + 1);
+ }
+
+ string(const char* s, const int n) {
+ len = n;
+ if (len == 0) {
+ buf = stringEmptyBuffer;
+ return;
+ }
+ buf = gc_cnew(len + 1);
+ string_memcpy(buf, s, len);
+ buf[len] = '\0';
+ }
+
+ string(const int n, const char c) {
+ len = n;
+ if (len == 0) {
+ buf = stringEmptyBuffer;
+ return;
+ }
+ buf = gc_cnew(len + 1);
+ memset(buf, c, n);
+ buf[len] = '\0';
+ }
+
+ string(const string& s) {
+ len = s.len;
+ buf = s.buf;
+ }
+
+ const string& operator=(const string& s) {
+ if (&s == this)
+ return *this;
+ len = s.len;
+ buf = s.buf;
+ return *this;
+ }
+
+ const bool operator==(const string& s) const {
+ if (len != s.len)
+ return false;
+ if (buf == s.buf)
+ return true;
+ return memcmp(buf, s.buf, len) == 0;
+ }
+
+ const bool operator!=(const string& s) const {
+ return !(*this == s);
+ }
+
+ const bool operator==(const char* s) const {
+ if (buf == s)
+ return true;
+ return strcmp(buf, s) == 0;
+ }
+
+ const bool operator!=(const char* s) const {
+ return !(*this == s);
+ }
+
+ const bool operator<(const string& s) const {
+ const int n = len < s.len? len : s.len;
+ const int c = memcmp(buf, s.buf, n);
+ if (c < 0)
+ return true;
+ if (c == 0)
+ return len < s.len;
+ return false;
+ }
+
+ const bool operator>(const string& s) const {
+ const int n = len < s.len? len : s.len;
+ int c = memcmp(buf, s.buf, n);
+ if (c > 0)
+ return true;
+ if (c == 0)
+ return len > s.len;
+ return false;
+ }
+
+private:
+#ifdef WANT_MAINTAINER_MODE
+ friend class odebugstream;
+#endif
+ friend class ostringstream;
+ friend const string operator+(const string& a, const string& b);
+ friend const string operator+(const string& a, const char* b);
+ friend const int length(const string& s);
+ friend const char* c_str(const string& s);
+ friend const int find(const string& s1, const char* s2, const int start);
+ friend const string substr(const string& s, const int pos, const int n);
+
+ int len;
+ char* buf;
+};
+
+/**
+ * Adds two strings.
+ */
+const string operator+(const string& a, const string& b) {
+ string s;
+ s.len = a.len + b.len;
+ s.buf = gc_cnew(s.len + 1);
+ string_memcpy(s.buf, a.buf, a.len);
+ string_memcpy(s.buf + a.len, b.buf, b.len);
+ s.buf[s.len] = '\0';
+ return s;
+}
+
+const string operator+(const string& a, const char* b) {
+ string s;
+ const int blen = strlen(b);
+ s.len = a.len + blen;
+ s.buf = gc_cnew(s.len + 1);
+ string_memcpy(s.buf, a.buf, a.len);
+ string_memcpy(s.buf + a.len, b, blen);
+ s.buf[s.len] = '\0';
+ return s;
+}
+
+/**
+ * Returns the length of a string.
+ */
+const int length(const string& s) {
+ return s.len;
+}
+
+/**
+ * Returns a string as a C zero terminated string.
+ */
+const char* c_str(const string& s) {
+ return s.buf;
+}
+
+/**
+ * Find the first occurrence of string s2 in s1, starting at the given position.
+ */
+const int find(const string& s1, const char* s2, const int start) {
+ if (start >= s1.len)
+ return s1.len;
+ const char *f = strstr(s1.buf + start, s2);
+ if (f == NULL)
+ return s1.len;
+ return f - s1.buf;
+}
+
+const int find(const string& s1, const char* s2) {
+ return find(s1, s2, 0);
+}
+
+const bool contains(const string& s1, const char* s2) {
+ return find(s1, s2) != length(s1);
+}
+
+/**
+ * Find the first occurence of any character from a string in a string.
+ */
+const int find_first_of(const string& s1, const string& s2) {
+ return strcspn(c_str(s1), c_str(s2));
+}
+
+/**
+ * Find the last occurence of a character in a string.
+ */
+const int find_last(const string& s, const char c) {
+ const char* cs = c_str(s);
+ const char* f = strrchr(cs, c);
+ if (f == NULL)
+ return length(s);
+ return f - cs;
+}
+
+/**
+ * Return a substring of a string.
+ */
+const string substr(const string& s, const int pos, const int n) {
+ if (pos >= s.len)
+ return string();
+ if (pos + n > s.len)
+ return string(s.buf + pos, s.len - pos);
+ return string(s.buf + pos, n);
+}
+
+const string substr(const string& s, const int pos) {
+ return substr(s, pos, length(s));
+}
+
+/**
+ * Common string constants.
+ */
+
+string trueString("true");
+string falseString("false");
+string emptyString("");
+
+}
+
+#endif /* tuscany_string_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/tree.hpp b/sca-cpp/branches/gcc-4.4/kernel/tree.hpp
new file mode 100644
index 0000000000..436385aa1b
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/tree.hpp
@@ -0,0 +1,125 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_tree_hpp
+#define tuscany_tree_hpp
+
+/**
+ * Functions to work with trees.
+ */
+
+#include "stream.hpp"
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "monad.hpp"
+#include "value.hpp"
+
+namespace tuscany {
+
+/**
+ * Make a tree from a leaf and two branches.
+ */
+template<typename T> const list<T> mktree(const T& e, const list<T>& left, const list<T>& right) {
+ return mklist<T>(e, left, right);
+}
+
+/**
+ * Find a leaf with the given key in a tree.
+ */
+template<typename T> const list<T> assoctree(const T& k, const list<T>& tree) {
+ if (isNil(tree))
+ return tree;
+ if (k == car<T>(car(tree)))
+ return car(tree);
+ if (k < car<T>(car(tree)))
+ return assoctree<T>(k, cadr(tree));
+ return assoctree<T>(k, caddr(tree));
+}
+
+/**
+ * Construct a new tree from a leaf and a tree.
+ */
+template<typename T> const list<T> constree(const T& e, const list<T>& tree) {
+ if (isNil(tree))
+ return mktree(e, list<T>(), list<T>());
+ if (e == car(tree))
+ return tree;
+ if (e < car(tree))
+ return mktree<T>(car(tree), constree<T>(e, cadr(tree)), caddr(tree));
+ return mktree<T>(car(tree), cadr(tree), constree<T>(e, caddr(tree)));
+}
+
+/**
+ * Make a tree from an unordered list of leaves.
+ */
+template<typename T> const list<T> mktree(const list<T>& l) {
+ if (isNil(l))
+ return l;
+ return constree(car(l), mktree(cdr(l)));
+}
+
+/**
+ * Convert a tree to an ordered list of leaves.
+ */
+template<typename T> const list<T> flatten(const list<T>& tree) {
+ if (isNil(tree))
+ return tree;
+ return append<T>(flatten<T>(cadr(tree)), cons<T>(car(tree), flatten<T>(caddr(tree))));
+}
+
+/**
+ * Sort a list.
+ */
+template<typename T> const list<T> sort(const list<T>& l) {
+ return flatten(mktree(l));
+}
+
+/**
+ * Make a balanced tree from an ordered list of leaves.
+ */
+template<typename T> const list<T> btreeHelper(const list<T>& elements, const int n) {
+ if (n == 0)
+ return cons<T>(list<T>(), elements);
+ const int leftSize = (n - 1) / 2; {
+ const list<T> leftResult = btreeHelper<T>(elements, leftSize); {
+ const list<T> leftTree = car(leftResult);
+ const list<T> nonLeftElements = cdr(leftResult);
+ const int rightSize = n - (leftSize + 1); {
+ const T thisEntry = car(nonLeftElements);
+ const list<T> rightResult = btreeHelper<T>(cdr(nonLeftElements), rightSize); {
+ const list<T> rightTree = car(rightResult);
+ const list<T> remainingElements = cdr(rightResult); {
+ return cons<T>(mktree<T>(thisEntry, leftTree, rightTree), remainingElements);
+ }
+ }
+ }
+ }
+ }
+}
+
+template<typename T> const list<T> mkbtree(const list<T>& elements) {
+ return car(btreeHelper<T>(elements, length(elements)));
+}
+
+}
+
+#endif /* tuscany_tree_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/value.hpp b/sca-cpp/branches/gcc-4.4/kernel/value.hpp
new file mode 100644
index 0000000000..87d80a3e2a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/value.hpp
@@ -0,0 +1,593 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_value_hpp
+#define tuscany_value_hpp
+
+/**
+ * Generic value type.
+ */
+
+#include <stdlib.h>
+#include "string.hpp"
+#include "sstream.hpp"
+#include "gc.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "monad.hpp"
+
+namespace tuscany
+{
+
+#ifdef WANT_MAINTAINER_MODE
+
+/**
+ * Debug utilities. Counters used to track instances of values, and
+ * macro used to write the contents of a value in a string, easier to
+ * watch in a debugger than the value itself.
+ */
+long int countValues = 0;
+long int countEValues = 0;
+long int countCValues = 0;
+long int countVValues = 0;
+
+bool resetValueCounters() {
+ countValues = countEValues = countCValues = countVValues = 0;
+ return true;
+}
+
+bool checkValueCounters() {
+ return countValues == 0;
+}
+
+bool printValueCounters() {
+ cout << "countValues " << countValues << endl;
+ cout << "countEValues " << countEValues << endl;
+ cout << "countCValues " << countCValues << endl;
+ cout << "countVValues " << countVValues << endl;
+ return true;
+}
+
+#else
+
+#define resetValueCounters()
+#define checkValueCounters() true
+#define printValueCounters()
+
+#endif
+
+#ifdef WANT_MAINTAINER_WATCH
+
+#define debug_watchValue() do { \
+ this->watch = watchValue(*this); \
+ } while (0)
+
+#else
+
+#define debug_watchValue()
+
+#endif
+
+class value;
+
+class value {
+public:
+
+ enum ValueType {
+ Undefined, Symbol, String, List, Number, Bool, Lambda, Ptr
+ };
+
+ value() : type(value::Undefined) {
+ debug_inc(countValues);
+ debug_inc(countEValues);
+ debug_watchValue();
+ }
+
+ value(const value& v) {
+ debug_inc(countValues);
+ debug_inc(countCValues);
+ type = v.type;
+ switch(type) {
+ case value::List:
+ lst() = v.lst();
+ case value::Lambda:
+ func() = v.func();
+ case value::Symbol:
+ str() = v.str();
+ case value::String:
+ str() = v.str();
+ case value::Number:
+ num() = v.num();
+ case value::Bool:
+ boo() = v.boo();
+ case value::Ptr:
+ ptr() = v.ptr();
+ default:
+ break;
+ }
+#ifdef WANT_MAINTAINER_WATCH
+ watch = v.watch;
+#endif
+ }
+
+ virtual ~value() {
+ debug_dec(countValues);
+ }
+
+ value(const lambda<value(const list<value>&)>& func) : type(value::Lambda), data(vdata(func)) {
+ debug_inc(countValues);
+ debug_inc(countVValues);
+ debug_watchValue();
+ }
+
+ value(const string& str) : type(value::String), data(vdata(result(str))) {
+ debug_inc(countValues);
+ debug_inc(countVValues);
+ debug_watchValue();
+ }
+
+ value(const char* str) : type(value::Symbol), data(vdata(result(string(str)))) {
+ debug_inc(countValues);
+ debug_inc(countVValues);
+ debug_watchValue();
+ }
+
+ value(const list<value>& lst) : type(value::List), data(vdata(result(lst))) {
+ debug_inc(countValues);
+ debug_inc(countVValues);
+ debug_watchValue();
+ }
+
+ value(const list<list<value> >& l) : type(value::List), data(vdata(result(listOfValues(l)))) {
+ debug_inc(countValues);
+ debug_inc(countVValues);
+ debug_watchValue();
+ }
+
+ value(const double num) : type(value::Number), data(vdata(result(num))) {
+ debug_inc(countValues);
+ debug_inc(countVValues);
+ debug_watchValue();
+ }
+
+ value(const int num) : type(value::Number), data(vdata(result((double)num))) {
+ debug_inc(countValues);
+ debug_inc(countVValues);
+ debug_watchValue();
+ }
+
+ value(const bool boo) : type(value::Bool), data(vdata(result(boo))) {
+ debug_inc(countValues);
+ debug_inc(countVValues);
+ debug_watchValue();
+ }
+
+ value(const gc_ptr<value> ptr) : type(value::Ptr), data(vdata(result(ptr))) {
+ debug_inc(countValues);
+ debug_inc(countVValues);
+ debug_watchValue();
+ }
+
+ value(const failable<value>& m) : type(value::List),
+ data(vdata(result(hasContent(m)? mklist<value>(content(m)) : mklist<value>(value(), reason(m))))) {
+ debug_inc(countValues);
+ debug_inc(countVValues);
+ debug_watchValue();
+ }
+
+ value(const maybe<value>& m) : type(value::List),
+ data(vdata(result(hasContent(m)? mklist<value>(content(m)) : list<value>()))) {
+ debug_inc(countValues);
+ debug_inc(countVValues);
+ debug_watchValue();
+ }
+
+ const value& operator=(const value& v) {
+ if(this == &v)
+ return *this;
+ type = v.type;
+ switch(type) {
+ case value::List:
+ lst() = v.lst();
+ case value::Lambda:
+ func() = v.func();
+ case value::Symbol:
+ str() = v.str();
+ case value::String:
+ str() = v.str();
+ case value::Number:
+ num() = v.num();
+ case value::Bool:
+ boo() = v.boo();
+ case value::Ptr:
+ ptr() = v.ptr();
+ default:
+ break;
+ }
+#ifdef WANT_MAINTAINER_WATCH
+ watch = v.watch;
+#endif
+ return *this;
+ }
+
+ const bool operator!=(const value& v) const {
+ return !this->operator==(v);
+ }
+
+ const bool operator==(const value& v) const {
+ if(this == &v)
+ return true;
+ switch(type) {
+ case value::Undefined:
+ return true;
+ case value::List:
+ return v.type == value::List && lst()() == v.lst()();
+ case value::Lambda:
+ return v.type == value::Lambda && func() == v.func();
+ case value::Symbol:
+ case value::String:
+ return str()() == (string)v;
+ case value::Number:
+ return num()() == (double)v;
+ case value::Bool:
+ return boo()() == (bool)v;
+ case value::Ptr:
+ return v.type == value::Ptr && ptr()() == v.ptr()();
+ default:
+ return false;
+ }
+ }
+
+ const bool operator<(const value& v) const {
+ if(this == &v)
+ return false;
+ switch(type) {
+ case value::List:
+ return v.type == value::List && lst()() < v.lst()();
+ case value::Symbol:
+ case value::String:
+ return str()() < (string)v;
+ case value::Bool:
+ return boo()() < (bool)v;
+ case value::Number:
+ return num()() < (double)v;
+ default:
+ return false;
+ }
+ }
+
+ const bool operator>(const value& v) const {
+ if(this == &v)
+ return false;
+ switch(type) {
+ case value::List:
+ return v.type == value::List && lst()() > v.lst()();
+ case value::Symbol:
+ case value::String:
+ return str()() > (string)v;
+ case value::Bool:
+ return boo()() > (bool)v;
+ case value::Number:
+ return num()() > (double)v;
+ default:
+ return false;
+ }
+ }
+
+ const value operator()(const list<value>& args) const {
+ return func()(args);
+ }
+
+ operator const string() const {
+ switch(type) {
+ case value::Symbol:
+ case value::String:
+ return str()();
+ case value::Number: {
+ ostringstream os;
+ os << num()();
+ return tuscany::str(os);
+ }
+ case value::Bool:
+ return boo()()? trueString : falseString;
+ default:
+ return emptyString;
+ }
+ }
+
+ operator const double() const {
+ switch(type) {
+ case value::Symbol:
+ case value::String:
+ return atof(c_str(str()()));
+ case value::Number:
+ return (double)num()();
+ case value::Bool:
+ return boo()()? 1.0 : 0.0;
+ default:
+ return 0.0;
+ }
+ }
+
+ operator const int() const {
+ switch(type) {
+ case value::Symbol:
+ case value::String:
+ return atoi(c_str(str()()));
+ case value::Number:
+ return (int)num()();
+ case value::Bool:
+ return boo()()? 1 : 0;
+ default:
+ return 0;
+ }
+ }
+
+ operator const bool() const {
+ switch(type) {
+ case value::Symbol:
+ case value::String:
+ return str()() == string("true");
+ case value::Number:
+ return (int)num()() != 0;
+ case value::Bool:
+ return boo()();
+ default:
+ return 0;
+ }
+ }
+
+ operator const gc_ptr<value>() const {
+ return ptr()();
+ }
+
+ operator const list<value>() const {
+ return lst()();
+ }
+
+ operator const list<list<value> >() const {
+ return listOfListOfValues(lst()());
+ }
+
+ operator const lambda<value(const list<value>&)>() const {
+ return func();
+ }
+
+private:
+ template<typename T> lambda<T>& vdata() const {
+ return *reinterpret_cast<lambda<T> *> (const_cast<lambda<char()> *> (&data));
+ }
+
+ template<typename T> const lambda<char()>& vdata(const T& v) const {
+ return *reinterpret_cast<const lambda<char()> *> (&v);
+ }
+
+ lambda<double()>& num() const {
+ return vdata<double()> ();
+ }
+
+ lambda<bool()>& boo() const {
+ return vdata<bool()> ();
+ }
+
+ lambda<gc_ptr<value>()>& ptr() const {
+ return vdata<gc_ptr<value>()> ();
+ }
+
+ lambda<string()>& str() const {
+ return vdata<string()> ();
+ }
+
+ lambda<list<value>()>& lst() const {
+ return vdata<list<value>()> ();
+ }
+
+ lambda<value(const list<value>&)>& func() const {
+ return vdata<value(const list<value>&)> ();
+ }
+
+ const list<value> listOfValues(const list<list<value> >& l) const {
+ if (isNil(l))
+ return list<value>();
+ return cons<value>(car(l), listOfValues(cdr(l)));
+ }
+
+ const list<list<value> > listOfListOfValues(const list<value>& l) const {
+ if (isNil(l))
+ return list<list<value> >();
+ return cons<list<value> >(list<value>(car(l)), listOfListOfValues(cdr(l)));
+ }
+
+ friend ostream& operator<<(ostream&, const value&);
+ friend const value::ValueType type(const value& v);
+
+#ifdef WANT_MAINTAINER_WATCH
+ friend const string watchValue(const value& v);
+ string watch;
+#endif
+
+ ValueType type;
+ lambda<char()> data;
+};
+
+#ifdef WANT_MAINTAINER_WATCH
+
+/**
+ * Debug utility used to write the contents of a value to a string, easier
+ * to watch than the value itself in a debugger.
+ */
+const string watchValue(const value& v) {
+ if (v.type == value::List)
+ return watchList<value>(v);
+ odebugstream os;
+ os << v;
+ return str(os);
+}
+
+#endif
+
+/**
+ * Write a value to a stream.
+ */
+ostream& operator<<(ostream& out, const value& v) {
+ switch(v.type) {
+ case value::List:
+ return out << v.lst()();
+ case value::Lambda:
+ return out << "lambda::" << v.func();
+ case value::Symbol:
+ return out << v.str()();
+ case value::String:
+ return out << '\"' << v.str()() << '\"';
+ case value::Number:
+ return out << v.num()();
+ case value::Bool:
+ if(v.boo()())
+ return out << "true";
+ else
+ return out << "false";
+ case value::Ptr: {
+ const gc_ptr<value> p = v.ptr()();
+ if (p == gc_ptr<value>(NULL))
+ return out << "gc_ptr::null";
+ return out << "gc_ptr::" << p;
+ }
+ default:
+ return out << "undefined";
+ }
+}
+
+/**
+ * Returns the type of a value.
+ */
+const value::ValueType type(const value& v) {
+ return v.type;
+}
+
+/**
+ * Returns true if a value is nil.
+ */
+const bool isNil(const value& v) {
+ return type(v) == value::Undefined;
+}
+
+/**
+ * Returns true if a value is a lambda.
+ */
+const bool isLambda(const value& v) {
+ return type(v) == value::Lambda;
+}
+
+/**
+ * Returns true if a value is a string.
+ */
+const bool isString(const value& v) {
+ return type(v) == value::String;
+}
+
+/**
+ * Returns true if a value is a symbol.
+ */
+const bool isSymbol(const value& v) {
+ return type(v) == value::Symbol;
+}
+
+/**
+ * Returns true if a value is a list.
+ */
+const bool isList(const value& v) {
+ return type(v) == value::List;
+}
+
+/**
+ * Returns true if a value is a number.
+ */
+const bool isNumber(const value& v) {
+ return type(v) == value::Number;
+}
+
+/**
+ * Returns true if a value is a boolean.
+ */
+const bool isBool(const value& v) {
+ return type(v) == value::Bool;
+}
+
+/**
+ * Returns true if a value is a pointer.
+ */
+const bool isPtr(const value& v) {
+ return type(v) == value::Ptr;
+}
+
+/**
+ * Returns true if a value is a tagged list.
+ */
+const bool isTaggedList(const value& exp, value tag) {
+ if(isList(exp) && !isNil((list<value>)exp))
+ return car((list<value>)exp) == tag;
+ return false;
+}
+
+/**
+ * Make a list of values from a list of other things.
+ */
+template<typename T> const list<value> mkvalues(const list<T>& l) {
+ if (isNil(l))
+ return list<value>();
+ return cons<value>(car(l), mkvalues(cdr(l)));
+}
+
+/**
+ * Convert a list of values to a list of other things.
+ */
+template<typename T> const list<T> convertValues(const list<value>& l) {
+ if (isNil(l))
+ return list<T>();
+ return cons<T>(car(l), convertValues<T>(cdr(l)));
+}
+
+/**
+ * Convert a path string value to a list of values.
+ */
+const list<string> pathTokens(const char* p) {
+ if (p == NULL || p[0] == '\0')
+ return list<string>();
+ if (p[0] == '/')
+ return tokenize("/", p + 1);
+ return tokenize("/", p);
+}
+
+const list<value> pathValues(const value& p) {
+ return mkvalues(pathTokens(c_str(p)));
+}
+
+/**
+ * Convert a path represented as a list of values to a string value.
+ */
+const value path(const list<value>& p) {
+ if (isNil(p))
+ return "";
+ return string("/") + car(p) + path(cdr(p));
+}
+
+}
+#endif /* tuscany_value_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/xml-test.cpp b/sca-cpp/branches/gcc-4.4/kernel/xml-test.cpp
new file mode 100644
index 0000000000..c83a65fd92
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/xml-test.cpp
@@ -0,0 +1,180 @@
+/*
+ * 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 XML handling functions.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "element.hpp"
+#include "xml.hpp"
+
+namespace tuscany {
+
+const string currencyXML =
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+"<composite xmlns=\"http://docs.oasis-open.org/ns/opencsa/sca/200912\" "
+"xmlns:t=\"http://tuscany.apache.org/xmlns/sca/1.1\" "
+"targetNamespace=\"http://services\" "
+"name=\"currency\">"
+"<component name=\"CurrencyConverterWebService\">"
+"<implementation.java class=\"services.CurrencyConverterImpl\"/>"
+"<service name=\"CurrencyConverter\">"
+"<binding.ws/>"
+"</service>"
+"</component>"
+"<component name=\"CurrencyConverterWebService2\">"
+"<implementation.java class=\"services.CurrencyConverterImpl2\"/>"
+"<service name=\"CurrencyConverter2\">"
+"<binding.atom/>"
+"</service>"
+"<property name=\"currency\">US</property>"
+"</component>"
+"</composite>"
+"\n";
+
+const string customerXML =
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+"<customer>"
+"<name>jdoe</name>"
+"<address><city>san francisco</city><state>ca</state></address>"
+"<account><id>1234</id><balance>1000</balance></account>"
+"<account><id>6789</id><balance>2000</balance></account>"
+"<account><id>4567</id><balance>3000</balance></account>"
+"</customer>"
+"\n";
+
+
+const bool isName(const value& token) {
+ return isTaggedList(token, attribute) && attributeName(token) == "name";
+}
+
+bool testReadXML() {
+ {
+ istringstream is(customerXML);
+ const list<value> c = readXML(streamList(is));
+ }
+ {
+ istringstream is(currencyXML);
+ const list<value> c = readXML(streamList(is));
+
+ const value composite = car(c);
+ assert(isTaggedList(composite, element));
+ assert(elementName(composite) == "composite");
+ assert(attributeValue(car(filter<value>(isName, elementChildren(composite)))) == string("currency"));
+ }
+ return true;
+}
+
+ostream* xmlWriter(const string& s, ostream* os) {
+ (*os) << s;
+ return os;
+}
+
+bool testWriteXML() {
+ {
+ istringstream is(customerXML);
+ const list<value> c = readXML(streamList(is));
+ ostringstream os;
+ writeXML<ostream*>(xmlWriter, &os, c);
+ assert(str(os) == customerXML);
+ }
+ {
+ istringstream is(currencyXML);
+ const list<value> c = readXML(streamList(is));
+ ostringstream os;
+ writeXML<ostream*>(xmlWriter, &os, c);
+ assert(str(os) == currencyXML);
+ }
+ return true;
+}
+
+bool testElements() {
+ {
+ const list<value> ad = mklist<value>(mklist<value>("city", string("san francisco")), mklist<value>("state", string("ca")));
+ const list<value> ac1 = mklist<value>(mklist<value>("id", string("1234")), mklist<value>("balance", 1000));
+ const list<value> ac2 = mklist<value>(mklist<value>("id", string("6789")), mklist<value>("balance", 2000));
+ const list<value> ac3 = mklist<value>(mklist<value>("id", string("4567")), mklist<value>("balance", 3000));
+ {
+ const list<value> c = mklist<value>(mklist<value>("customer", mklist<value>("name", string("jdoe")), cons<value>("address", ad), mklist<value>("account", mklist<value>(ac1, ac2, ac3))));
+ const list<value> e = valuesToElements(c);
+ const list<value> v = elementsToValues(e);
+ assert(v == c);
+
+ ostringstream os;
+ writeXML<ostream*>(xmlWriter, &os, e);
+ assert(str(os) == customerXML);
+ }
+ {
+ const list<value> c = mklist<value>(mklist<value>("customer", mklist<value>("name", string("jdoe")), cons<value>("address", ad), cons<value>("account", ac1), cons<value>("account", ac2), cons<value>("account", ac3)));
+ const list<value> e = valuesToElements(c);
+ const list<value> v = elementsToValues(e);
+
+ ostringstream os;
+ writeXML<ostream*>(xmlWriter, &os, e);
+ assert(str(os) == customerXML);
+ }
+ }
+ {
+ istringstream is(customerXML);
+ const list<value> c = readXML(streamList(is));
+ const list<value> v = elementsToValues(c);
+ const list<value> e = valuesToElements(v);
+ ostringstream os;
+ writeXML<ostream*>(xmlWriter, &os, e);
+ assert(str(os) == customerXML);
+ }
+ return true;
+}
+
+bool testValues() {
+ {
+ const list<value> l = mklist<value>(list<value>() + "ns1:echoString" + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + (list<value>() + "text" + string("Hello World!")));
+ const list<value> e = valuesToElements(l);
+ const failable<list<string> > lx = writeXML(e);
+ ostringstream os;
+ write(content(lx), os);
+ istringstream is(str(os));
+ const list<value> x = readXML(streamList(is));
+ const list<value> v = elementsToValues(x);
+ assert(v == l);
+ }
+ return true;
+}
+
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::testReadXML();
+ tuscany::testWriteXML();
+ tuscany::testElements();
+ tuscany::testValues();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/kernel/xml.hpp b/sca-cpp/branches/gcc-4.4/kernel/xml.hpp
new file mode 100644
index 0000000000..fa1701d83a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/xml.hpp
@@ -0,0 +1,369 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_xml_hpp
+#define tuscany_xml_hpp
+
+/**
+ * XML read/write functions.
+ */
+
+#include <libxml/xmlreader.h>
+#include <libxml/xmlwriter.h>
+#include <libxml/xmlschemas.h>
+#include <libxml/globals.h>
+#include "string.hpp"
+#include "list.hpp"
+#include "stream.hpp"
+#include "value.hpp"
+#include "element.hpp"
+#include "monad.hpp"
+
+namespace tuscany {
+
+/**
+ * Initializes the libxml2 library.
+ */
+class XMLParser {
+public:
+ XMLParser() {
+ xmlInitParser();
+ }
+} xmlParser;
+
+/**
+ * Encapsulates a libxml2 xmlTextReader and its state.
+ */
+class XMLReader {
+public:
+ enum TokenType {
+ None = 0, Element = 1, Attribute = 2, Text = 3, EndElement = 15, Identifier = 100, End = 101
+ };
+
+ XMLReader(xmlTextReaderPtr xml) : xml(xml), tokenType(None), isEmptyElement(false), hasValue(false), hasAttributes(false) {
+ xmlTextReaderSetParserProp(xml, XML_PARSER_DEFAULTATTRS, 1);
+ xmlTextReaderSetParserProp(xml, XML_PARSER_SUBST_ENTITIES, 1);
+ }
+
+ ~XMLReader() {
+ xmlTextReaderClose(xml);
+ xmlFreeTextReader(xml);
+ }
+
+ /**
+ * Read the next XML token and return its type.
+ */
+ int read() {
+ if (tokenType == End)
+ return tokenType;
+ if (tokenType == Element) {
+ isEmptyElement = xmlTextReaderIsEmptyElement(xml);
+ hasAttributes = xmlTextReaderHasAttributes(xml);
+ return tokenType = Identifier;
+ }
+ if (tokenType == Identifier && hasAttributes && xmlTextReaderMoveToFirstAttribute(xml) == 1)
+ return tokenType = Attribute;
+ if (tokenType == Attribute && xmlTextReaderMoveToNextAttribute(xml) == 1)
+ return tokenType = Attribute;
+ if (isEmptyElement && (tokenType == Identifier || tokenType == Attribute))
+ return tokenType = EndElement;
+ if (!xmlTextReaderRead(xml))
+ return tokenType = End;
+ return tokenType = xmlTextReaderNodeType(xml);
+ }
+
+ operator xmlTextReaderPtr() const {
+ return xml;
+ }
+
+private:
+ const xmlTextReaderPtr xml;
+ int tokenType;
+ bool isEmptyElement;
+ bool hasValue;
+ bool hasAttributes;
+};
+
+/**
+ * Constants used to tag XML tokens.
+ */
+const value endElement("<");
+const value startElement(">");
+
+/**
+ * Read an XML identifier.
+ */
+const value readIdentifier(XMLReader& reader) {
+ const char* name = (const char*)xmlTextReaderConstName(reader);
+ return name;
+}
+
+/**
+ * Read XML text.
+ */
+const value readText(XMLReader& reader) {
+ const char *val = (const char*)xmlTextReaderConstValue(reader);
+ return string(val);
+}
+
+/**
+ * Read an XML attribute.
+ */
+const value readAttribute(XMLReader& reader) {
+ const char *name = (const char*)xmlTextReaderConstName(reader);
+ const char *val = (const char*)xmlTextReaderConstValue(reader);
+ return mklist<value>(attribute, name, string(val));
+}
+
+/**
+ * Read an XML token.
+ */
+const value readToken(XMLReader& reader) {
+ const int tokenType = reader.read();
+ if (tokenType == XMLReader::None || tokenType == XMLReader::End)
+ return value();
+ if (tokenType == XMLReader::Element)
+ return startElement;
+ if (tokenType == XMLReader::Identifier)
+ return readIdentifier(reader);
+ if (tokenType == XMLReader::Attribute)
+ return readAttribute(reader);
+ if (tokenType == XMLReader::Text)
+ return readText(reader);
+ if (tokenType == XMLReader::EndElement)
+ return endElement;
+ return readToken(reader);
+}
+
+/**
+ * Read a list of values from XML tokens.
+ */
+const list<value> readList(const list<value>& listSoFar, XMLReader& reader) {
+ const value token = readToken(reader);
+ if(isNil(token) || endElement == token)
+ return reverse(listSoFar);
+ if(startElement == token)
+ return readList(cons<value>(readList(mklist(element), reader), listSoFar), reader);
+ return readList(cons(token, listSoFar), reader);
+}
+
+/**
+ * Read a list of values from a libxml2 XML reader.
+ */
+const list<value> read(XMLReader& reader) {
+ value nextToken = readToken(reader);
+ if (startElement == nextToken)
+ return mklist<value>(readList(mklist(element), reader));
+ return list<value>();
+}
+
+/**
+ * Context passed to the read callback function.
+ */
+class XMLReadContext {
+public:
+ XMLReadContext(const list<string>& ilist) : ilist(ilist) {
+ }
+ list<string> ilist;
+};
+
+/**
+ * Callback function called by libxml2 to read XML.
+ */
+int readCallback(void *context, char* buffer, int len) {
+ XMLReadContext& rc = *static_cast<XMLReadContext*>(context);
+ if (isNil(rc.ilist))
+ return 0;
+ const list<string> f(fragment(rc.ilist, len));
+ const string s(car(f));
+ rc.ilist = cdr(f);
+ memcpy(buffer, c_str(s), length(s));
+ return length(s);
+}
+
+/**
+ * Read a list of values from a list of strings representing an XML document.
+ */
+const list<value> readXML(const list<string>& ilist) {
+ XMLReadContext cx(ilist);
+ xmlTextReaderPtr xml = xmlReaderForIO(readCallback, NULL, &cx, NULL, NULL, XML_PARSE_NONET);
+ if (xml == NULL)
+ return list<value>();
+ XMLReader reader(xml);
+ return read(reader);
+}
+
+/**
+ * Default encoding used to write XML documents.
+ */
+const char* encoding = "UTF-8";
+
+
+/**
+ * Write a list of XML element or attribute tokens.
+ */
+const list<value> expandElementValues(const value& n, const list<value>& l) {
+ if (isNil(l))
+ return l;
+ return cons<value>(value(cons<value>(element, cons<value>(n, (list<value>)car(l)))), expandElementValues(n, cdr(l)));
+}
+
+const failable<bool> writeList(const list<value>& l, const xmlTextWriterPtr xml) {
+ if (isNil(l))
+ return true;
+
+ // Write an attribute
+ const value token(car(l));
+ if (isTaggedList(token, attribute)) {
+ if (xmlTextWriterWriteAttribute(xml, (const xmlChar*)c_str(string(attributeName(token))), (const xmlChar*)c_str(string(attributeValue(token)))) < 0)
+ return mkfailure<bool>("xmlTextWriterWriteAttribute failed");
+
+ } else if (isTaggedList(token, element)) {
+
+ // Write an element containing a value
+ if (elementHasValue(token)) {
+ const value v = elementValue(token);
+ if (isList(v)) {
+
+ // Write an element per entry in a list of values
+ const list<value> e = expandElementValues(elementName(token), v);
+ writeList(e, xml);
+
+ } else {
+
+ // Write an element with a single value
+ if (xmlTextWriterStartElement(xml, (const xmlChar*)c_str(string(elementName(token)))) < 0)
+ return mkfailure<bool>("xmlTextWriterStartElement failed");
+
+ // Write its children
+ const failable<bool> w = writeList(elementChildren(token), xml);
+ if (!hasContent(w))
+ return w;
+
+ if (xmlTextWriterEndElement(xml) < 0)
+ return mkfailure<bool>("xmlTextWriterEndElement failed");
+ }
+ }
+ else {
+
+ // Write an element
+ if (xmlTextWriterStartElement(xml, (const xmlChar*)c_str(string(elementName(token)))) < 0)
+ return mkfailure<bool>("xmlTextWriterStartElement failed");
+
+ // Write its children
+ const failable<bool> w = writeList(elementChildren(token), xml);
+ if (!hasContent(w))
+ return w;
+
+ if (xmlTextWriterEndElement(xml) < 0)
+ return mkfailure<bool>("xmlTextWriterEndElement failed");
+ }
+ } else {
+
+ // Write XML text
+ if (xmlTextWriterWriteString(xml, (const xmlChar*)c_str(string(token))) < 0)
+ return mkfailure<bool>("xmlTextWriterWriteString failed");
+ }
+
+ // Go on
+ return writeList(cdr(l), xml);
+}
+
+/**
+ * Write a list of values to a libxml2 XML writer.
+ */
+const failable<bool> write(const list<value>& l, const xmlTextWriterPtr xml, bool xmlTag) {
+ if (xmlTag) {
+ if (xmlTextWriterStartDocument(xml, NULL, encoding, NULL) < 0)
+ return mkfailure<bool>(string("xmlTextWriterStartDocument failed"));
+ }
+
+ const failable<bool> w = writeList(l, xml);
+ if (!hasContent(w))
+ return w;
+
+ if (xmlTag) {
+ if (xmlTextWriterEndDocument(xml) < 0)
+ return mkfailure<bool>("xmlTextWriterEndDocument failed");
+ }
+ return true;
+}
+
+/**
+ * Context passed to the write callback function.
+ */
+template<typename R> class XMLWriteContext {
+public:
+ XMLWriteContext(const lambda<R(const string&, const R)>& reduce, const R& accum) : reduce(reduce), accum(accum) {
+ }
+ const lambda<R(const string&, const R)> reduce;
+ R accum;
+};
+
+/**
+ * Callback function called by libxml2 to write XML out.
+ */
+template<typename R> int writeCallback(void *context, const char* buffer, int len) {
+ XMLWriteContext<R>& cx = *static_cast<XMLWriteContext<R>*>(context);
+ cx.accum = cx.reduce(string(buffer, len), cx.accum);
+ return len;
+}
+
+/**
+ * Convert a list of values to an XML document.
+ */
+template<typename R> const failable<R> writeXML(const lambda<R(const string&, const R)>& reduce, const R& initial, const list<value>& l, const bool xmlTag) {
+ XMLWriteContext<R> cx(reduce, initial);
+ xmlOutputBufferPtr out = xmlOutputBufferCreateIO(writeCallback<R>, NULL, &cx, NULL);
+ if (out == NULL)
+ return mkfailure<R>("xmlOutputBufferCreateIO failed");
+ xmlTextWriterPtr xml = xmlNewTextWriter(out);
+ if (xml == NULL)
+ return mkfailure<R>("xmlNewTextWriter failed");
+
+ const failable<bool> w = write(l, xml, xmlTag);
+ xmlFreeTextWriter(xml);
+ if (!hasContent(w)) {
+ return mkfailure<R>(reason(w));
+ }
+ return cx.accum;
+}
+
+template<typename R> const failable<R> writeXML(const lambda<R(const string&, const R)>& reduce, const R& initial, const list<value>& l) {
+ return writeXML(reduce, initial, l, true);
+}
+
+/**
+ * Convert a list of values to a list of strings representing an XML document.
+ */
+const failable<list<string> > writeXML(const list<value>& l, const bool xmlTag) {
+ const failable<list<string> > ls = writeXML<list<string> >(rcons<string>, list<string>(), l, xmlTag);
+ if (!hasContent(ls))
+ return ls;
+ return reverse(list<string>(content(ls)));
+}
+
+const failable<list<string> > writeXML(const list<value>& l) {
+ return writeXML(l, true);
+}
+
+}
+#endif /* tuscany_xml_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/kernel/xsd-test.cpp b/sca-cpp/branches/gcc-4.4/kernel/xsd-test.cpp
new file mode 100644
index 0000000000..0fc432c649
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/kernel/xsd-test.cpp
@@ -0,0 +1,107 @@
+/*
+ * 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 validation of a composite file against an SCDL schema.
+ */
+
+#include "string.hpp"
+#include "fstream.hpp"
+#include <libxml/xmlreader.h>
+#include <libxml/xmlschemas.h>
+
+namespace tuscany {
+
+bool printNode(xmlTextReaderPtr reader) {
+ const xmlChar* name = xmlTextReaderConstName(reader);
+ if(name == NULL)
+ name = (xmlChar *)"<unknown>";
+ const xmlChar* value = xmlTextReaderConstValue(reader);
+ cout << xmlTextReaderDepth(reader) << " " << xmlTextReaderNodeType(reader) << " " << name << " "
+ << xmlTextReaderIsEmptyElement(reader) << " " << xmlTextReaderHasValue(reader);
+ if(value == NULL)
+ cout << endl;
+ else
+ cout << value << endl;
+ return true;
+}
+
+int xmlRead(void *context, char* buffer, int len) {
+ return fread(buffer, 1, len, (FILE*)context);
+}
+
+int xmlClose(void *context) {
+ fclose((FILE*)context);
+ return 0;
+}
+
+bool readFile(const char*xsdfilename, const char *filename) {
+ cout << "Loading schemas...\n";
+ const xmlDocPtr xsddoc = xmlReadFile(xsdfilename, NULL, XML_PARSE_NONET);
+ const xmlSchemaParserCtxtPtr xsdctx = xmlSchemaNewDocParserCtxt(xsddoc);
+ const xmlSchemaPtr xsd = xmlSchemaParse(xsdctx);
+ const xmlSchemaValidCtxtPtr validctx = xmlSchemaNewValidCtxt(xsd);
+
+ cout << "Reading file...\n";
+ FILE* file = fopen(filename, "r");
+ if (file != NULL) {
+ const xmlTextReaderPtr reader = xmlReaderForIO(xmlRead, xmlClose, file, filename, NULL, XML_PARSE_NONET);
+ xmlTextReaderSetParserProp(reader, XML_PARSER_DEFAULTATTRS, 1);
+ xmlTextReaderSetParserProp(reader, XML_PARSER_SUBST_ENTITIES, 1);
+
+ if(reader != NULL) {
+ xmlTextReaderSchemaValidateCtxt(reader, validctx, 0);
+
+ int rc;
+ while((rc = xmlTextReaderRead(reader)) == 1) {
+ printNode(reader);
+ }
+ if(xmlTextReaderIsValid(reader) != 1)
+ cout << "Could not validate document" << endl;
+ xmlFreeTextReader(reader);
+ if(rc != 0)
+ cout << "Could not parse document" << endl;
+ } else
+ cout << "Could not create parser" << endl;
+ } else
+ cout << "Could not open document" << endl;
+
+ xmlSchemaFreeValidCtxt(validctx);
+ xmlSchemaFree(xsd);
+ xmlSchemaFreeParserCtxt(xsdctx);
+
+ return true;
+}
+
+}
+
+int main(int argc, char **argv) {
+ tuscany::cout << "Testing..." << tuscany::endl;
+ if(argc != 3)
+ return 1;
+
+ tuscany::readFile(argv[1], argv[2]);
+
+ xmlCleanupParser();
+
+ tuscany::cout << "OK" << tuscany::endl;
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/Makefile.am b/sca-cpp/branches/gcc-4.4/modules/Makefile.am
new file mode 100644
index 0000000000..5ce2787fcf
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/Makefile.am
@@ -0,0 +1,22 @@
+# 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.
+
+SUBDIRS = scheme atom json scdl http server python wsgi java
+
+includedir = $(prefix)/include/modules
+nobase_include_HEADERS = */*.hpp
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/atom/Makefile.am b/sca-cpp/branches/gcc-4.4/modules/atom/Makefile.am
new file mode 100644
index 0000000000..6eccee83c7
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/atom/Makefile.am
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+atom_test_SOURCES = atom-test.cpp
+atom_test_LDFLAGS = -lxml2
+
+noinst_PROGRAMS = atom-test
+TESTS = atom-test
diff --git a/sca-cpp/branches/gcc-4.4/modules/atom/atom-test.cpp b/sca-cpp/branches/gcc-4.4/modules/atom/atom-test.cpp
new file mode 100644
index 0000000000..316e8b44db
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/atom/atom-test.cpp
@@ -0,0 +1,192 @@
+/*
+ * 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 ATOM data conversion functions.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "atom.hpp"
+
+namespace tuscany {
+namespace atom {
+
+ostream* writer(const string& s, ostream* os) {
+ (*os) << s;
+ return os;
+}
+
+string itemEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\">"
+ "<title type=\"text\">item</title>"
+ "<id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</id>"
+ "<content type=\"application/xml\">"
+ "<item>"
+ "<name>Apple</name><price>$2.99</price>"
+ "</item>"
+ "</content>"
+ "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\"/>"
+ "</entry>\n");
+
+string incompleteEntry("<entry xmlns=\"http://www.w3.org/2005/Atom\">"
+ "<title>item</title><content type=\"text/xml\">"
+ "<Item xmlns=\"http://services/\">"
+ "<name xmlns=\"\">Orange</name>"
+ "<price xmlns=\"\">3.55</price>"
+ "</Item>"
+ "</content>"
+ "</entry>");
+
+string completedEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\">"
+ "<title type=\"text\">item</title>"
+ "<id></id>"
+ "<content type=\"application/xml\">"
+ "<Item xmlns=\"http://services/\">"
+ "<name xmlns=\"\">Orange</name>"
+ "<price xmlns=\"\">3.55</price>"
+ "</Item>"
+ "</content><link href=\"\"/>"
+ "</entry>\n");
+
+bool testEntry() {
+ {
+ const list<value> i = list<value>() + element + value("item")
+ + value(list<value>() + element + value("name") + value(string("Apple")))
+ + value(list<value>() + element + value("price") + value(string("$2.99")));
+ const list<value> a = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
+ ostringstream os;
+ writeATOMEntry<ostream*>(writer, &os, a);
+ assert(str(os) == itemEntry);
+ }
+ {
+ const list<value> a = content(readATOMEntry(mklist(itemEntry)));
+ ostringstream os;
+ writeATOMEntry<ostream*>(writer, &os, a);
+ assert(str(os) == itemEntry);
+ }
+ {
+ const list<value> a = content(readATOMEntry(mklist(incompleteEntry)));
+ ostringstream os;
+ writeATOMEntry<ostream*>(writer, &os, a);
+ assert(str(os) == completedEntry);
+ }
+ return true;
+}
+
+string emptyFeed("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<feed xmlns=\"http://www.w3.org/2005/Atom\">"
+ "<title type=\"text\">Feed</title>"
+ "<id>1234</id>"
+ "</feed>\n");
+
+string itemFeed("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<feed xmlns=\"http://www.w3.org/2005/Atom\">"
+ "<title type=\"text\">Feed</title>"
+ "<id>1234</id>"
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\">"
+ "<title type=\"text\">item</title>"
+ "<id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</id>"
+ "<content type=\"application/xml\">"
+ "<item>"
+ "<name>Apple</name><price>$2.99</price>"
+ "</item>"
+ "</content>"
+ "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\"/>"
+ "</entry>"
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\">"
+ "<title type=\"text\">item</title>"
+ "<id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c</id>"
+ "<content type=\"application/xml\">"
+ "<item>"
+ "<name>Orange</name><price>$3.55</price>"
+ "</item>"
+ "</content>"
+ "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c\"/>"
+ "</entry>"
+ "</feed>\n");
+
+bool testFeed() {
+ {
+ ostringstream os;
+ writeATOMFeed<ostream*>(writer, &os, mklist<value>("Feed", "1234"));
+ assert(str(os) == emptyFeed);
+ }
+ {
+ const list<value> a = content(readATOMFeed(mklist(emptyFeed)));
+ ostringstream os;
+ writeATOMFeed<ostream*>(writer, &os, a);
+ assert(str(os) == emptyFeed);
+ }
+ {
+ const list<value> i = list<value>()
+ + (list<value>() + "item" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"
+ + (list<value>() + element + "item"
+ + (list<value>() + element + "name" + "Apple")
+ + (list<value>() + element + "price" + "$2.99")))
+ + (list<value>() + "item" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c"
+ + (list<value>() + element + "item"
+ + (list<value>() + element + "name" + "Orange")
+ + (list<value>() + element + "price" + "$3.55")));
+ const list<value> a = cons<value>("Feed", cons<value>("1234", i));
+ ostringstream os;
+ writeATOMFeed<ostream*>(writer, &os, a);
+ assert(str(os) == itemFeed);
+ }
+ {
+ const list<value> i = list<value>()
+ + (list<value>() + "item" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"
+ + valueToElement(list<value>() + "item"
+ + (list<value>() + "name" + "Apple")
+ + (list<value>() + "price" + "$2.99")))
+ + (list<value>() + "item" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c"
+ + valueToElement(list<value>() + "item"
+ + (list<value>() + "name" + "Orange")
+ + (list<value>() + "price" + "$3.55")));
+ const list<value> a = cons<value>("Feed", cons<value>("1234", i));
+ ostringstream os;
+ writeATOMFeed<ostream*>(writer, &os, a);
+ assert(str(os) == itemFeed);
+ }
+ {
+ const list<value> a = content(readATOMFeed(mklist(itemFeed)));
+ ostringstream os;
+ writeATOMFeed<ostream*>(writer, &os, a);
+ assert(str(os) == itemFeed);
+ }
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::atom::testEntry();
+ tuscany::atom::testFeed();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/atom/atom.hpp b/sca-cpp/branches/gcc-4.4/modules/atom/atom.hpp
new file mode 100644
index 0000000000..fadb482e0d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/atom/atom.hpp
@@ -0,0 +1,178 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_atom_hpp
+#define tuscany_atom_hpp
+
+/**
+ * ATOM data conversion functions.
+ */
+
+#include "string.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "xml.hpp"
+
+namespace tuscany {
+namespace atom {
+
+/**
+ * Convert a list of elements to a list of values representing an ATOM entry.
+ */
+const list<value> entryElementsToValues(const list<value>& e) {
+ const list<value> lt = filter<value>(selector(mklist<value>(element, "title")), e);
+ const value t = isNil(lt)? value(emptyString) : elementValue(car(lt));
+ const list<value> li = filter<value>(selector(mklist<value>(element, "id")), e);
+ const value i = isNil(li)? value(emptyString) : elementValue(car(li));
+ const list<value> lc = filter<value>(selector(mklist<value>(element, "content")), e);
+ return mklist<value>(t, i, cadr(elementChildren(car(lc))));
+}
+
+/**
+ * Convert a list of elements to a list of values representing ATOM entries.
+ */
+const list<value> entriesElementsToValues(const list<value>& e) {
+ if (isNil(e))
+ return e;
+ return cons<value>(entryElementsToValues(car(e)), entriesElementsToValues(cdr(e)));
+}
+
+/**
+ * Convert a list of strings to a list of values representing an ATOM entry.
+ */
+const failable<list<value> > readATOMEntry(const list<string>& ilist) {
+ const list<value> e = readXML(ilist);
+ if (isNil(e))
+ return mkfailure<list<value> >("Empty entry");
+ return entryElementsToValues(car(e));
+}
+
+/**
+ * Convert a list of values representing an ATOM entry to a value.
+ */
+const value entryValue(const list<value>& e) {
+ const list<value> v = elementsToValues(mklist<value>(caddr(e)));
+ return cons(car(e), mklist<value>(cadr(e), cdr<value>(car(v))));
+}
+
+/**
+ * Convert a list of strings to a list of values representing an ATOM feed.
+ */
+const failable<list<value> > readATOMFeed(const list<string>& ilist) {
+ const list<value> f = readXML(ilist);
+ if (isNil(f))
+ return mkfailure<list<value> >("Empty feed");
+ const list<value> t = filter<value>(selector(mklist<value>(element, "title")), car(f));
+ const list<value> i = filter<value>(selector(mklist<value>(element, "id")), car(f));
+ const list<value> e = filter<value>(selector(mklist<value>(element, "entry")), car(f));
+ if (isNil(e))
+ return mklist<value>(elementValue(car(t)), elementValue(car(i)));
+ return cons<value>(elementValue(car(t)), cons(elementValue(car(i)), entriesElementsToValues(e)));
+}
+
+/**
+ * Convert a list of values representing an ATOM entry to a list of elements.
+ * The first two values in the list are the entry title and id.
+ */
+const list<value> entryElement(const list<value>& l) {
+ return list<value>()
+ + element + "entry" + (list<value>() + attribute + "xmlns" + "http://www.w3.org/2005/Atom")
+ + (list<value>() + element + "title" + (list<value>() + attribute + "type" + "text") + car(l))
+ + (list<value>() + element + "id" + cadr(l))
+ + (list<value>() + element + "content" + (list<value>() + attribute + "type" + "application/xml") + caddr(l))
+ + (list<value>() + element + "link" + (list<value>() + attribute + "href" + cadr(l)));
+}
+
+/**
+ * Convert a list of values representing ATOM entries to a list of elements.
+ */
+const list<value> entriesElements(const list<value>& l) {
+ if (isNil(l))
+ return l;
+ return cons<value>(entryElement(car(l)), entriesElements(cdr(l)));
+}
+
+/**
+ * Convert a list of values representing an ATOM entry to an ATOM entry.
+ * The first two values in the list are the entry id and title.
+ */
+template<typename R> const failable<R> writeATOMEntry(const lambda<R(const string&, const R)>& reduce, const R& initial, const list<value>& l) {
+ return writeXML<R>(reduce, initial, mklist<value>(entryElement(l)));
+}
+
+const failable<list<string> > writeATOMEntry(const list<value>& l) {
+ const failable<list<string> > ls = writeATOMEntry<list<string> >(rcons<string>, list<string>(), l);
+ if (!hasContent(ls))
+ return ls;
+ return reverse(list<string>(content(ls)));
+}
+
+/**
+ * Convert a list of values representing an ATOM feed to an ATOM feed.
+ * The first two values in the list are the feed id and title.
+ */
+template<typename R> const failable<R> writeATOMFeed(const lambda<R(const string&, const R)>& reduce, const R& initial, const list<value>& l) {
+ const list<value> f = list<value>()
+ + element + "feed" + (list<value>() + attribute + "xmlns" + "http://www.w3.org/2005/Atom")
+ + (list<value>() + element + "title" + (list<value>() + attribute + "type" + "text") + car(l))
+ + (list<value>() + element + "id" + cadr(l));
+ if (isNil(cddr(l)))
+ return writeXML<R>(reduce, initial, mklist<value>(f));
+ const list<value> fe = append(f, entriesElements(cddr(l)));
+ return writeXML<R>(reduce, initial, mklist<value>(fe));
+}
+
+/**
+ * Convert a list of values representing an ATOM feed to a list of strings.
+ * The first two values in the list are the feed id and title.
+ */
+const failable<list<string> > writeATOMFeed(const list<value>& l) {
+ const failable<list<string> > ls = writeATOMFeed<list<string>>(rcons<string>, list<string>(), l);
+ if (!hasContent(ls))
+ return ls;
+ return reverse(list<string>(content(ls)));
+}
+
+/**
+ * Convert an ATOM entry containing a value to an ATOM entry containing an item element.
+ */
+const list<value> entryValuesToElements(const list<value> val) {
+ return cons(car(val), cons(cadr(val), valuesToElements(mklist<value>(cons<value>("item", (list<value>)caddr(val))))));
+}
+
+/**
+ * Convert an ATOM feed containing values to an ATOM feed containing elements.
+ */
+const list<value> feedValuesToElementsLoop(const list<value> val) {
+ if (isNil(val))
+ return val;
+ return cons<value>(entryValuesToElements(car(val)), feedValuesToElementsLoop(cdr(val)));
+}
+
+const list<value> feedValuesToElements(const list<value>& val) {
+ return cons(car<value>(val), cons<value>(cadr<value>(val), feedValuesToElementsLoop(cddr<value>(val))));
+}
+
+}
+}
+
+#endif /* tuscany_atom_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/http/Makefile.am b/sca-cpp/branches/gcc-4.4/modules/http/Makefile.am
new file mode 100644
index 0000000000..180529620c
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/http/Makefile.am
@@ -0,0 +1,34 @@
+# 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.
+
+INCLUDES = -I${HTTPD_INCLUDE}
+
+moddir=$(prefix)/modules/http
+mod_SCRIPTS = httpd-conf httpd-start httpd-stop httpd-restart
+
+curl_test_SOURCES = curl-test.cpp
+curl_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+
+prefix_DATA = httpd.prefix curl.prefix
+prefixdir=$(prefix)/modules/http
+httpd.prefix: $(top_builddir)/config.status
+ echo ${HTTPD_PREFIX} >httpd.prefix
+curl.prefix: $(top_builddir)/config.status
+ echo ${CURL_PREFIX} >curl.prefix
+
+noinst_PROGRAMS = curl-test
+TESTS = httpd-test http-test
diff --git a/sca-cpp/branches/gcc-4.4/modules/http/conf/mime.types b/sca-cpp/branches/gcc-4.4/modules/http/conf/mime.types
new file mode 100644
index 0000000000..4279f51bca
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/http/conf/mime.types
@@ -0,0 +1,607 @@
+# 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.
+
+# This file controls what Internet media types are sent to the client for
+# given file extension(s). Sending the correct media type to the client
+# is important so they know how to handle the content of the file.
+# Extra types can either be added here or by using an AddType directive
+# in your config files. For more information about Internet media types,
+# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type
+# registry is at <http://www.iana.org/assignments/media-types/>.
+
+# MIME type Extensions
+application/activemessage
+application/andrew-inset ez
+application/applefile
+application/atom+xml atom
+application/atomicmail
+application/batch-smtp
+application/beep+xml
+application/cals-1840
+application/cnrp+xml
+application/commonground
+application/cpl+xml
+application/cybercash
+application/dca-rft
+application/dec-dx
+application/dvcs
+application/edi-consent
+application/edifact
+application/edi-x12
+application/eshop
+application/font-tdpfr
+application/http
+application/hyperstudio
+application/iges
+application/index
+application/index.cmd
+application/index.obj
+application/index.response
+application/index.vnd
+application/iotp
+application/ipp
+application/isup
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/macwriteii
+application/marc
+application/mathematica
+application/mathml+xml mathml
+application/msword doc
+application/news-message-id
+application/news-transmission
+application/ocsp-request
+application/ocsp-response
+application/octet-stream bin dms lha lzh exe class so dll dmg
+application/oda oda
+application/ogg ogg
+application/parityfec
+application/pdf pdf
+application/pgp-encrypted
+application/pgp-keys
+application/pgp-signature
+application/pkcs10
+application/pkcs7-mime
+application/pkcs7-signature
+application/pkix-cert
+application/pkix-crl
+application/pkixcmp
+application/postscript ai eps ps
+application/prs.alvestrand.titrax-sheet
+application/prs.cww
+application/prs.nprend
+application/prs.plucker
+application/qsig
+application/rdf+xml rdf
+application/reginfo+xml
+application/remote-printing
+application/riscos
+application/rtf
+application/sdp
+application/set-payment
+application/set-payment-initiation
+application/set-registration
+application/set-registration-initiation
+application/sgml
+application/sgml-open-catalog
+application/sieve
+application/slate
+application/smil smi smil
+application/srgs gram
+application/srgs+xml grxml
+application/timestamp-query
+application/timestamp-reply
+application/tve-trigger
+application/vemmi
+application/vnd.3gpp.pic-bw-large
+application/vnd.3gpp.pic-bw-small
+application/vnd.3gpp.pic-bw-var
+application/vnd.3gpp.sms
+application/vnd.3m.post-it-notes
+application/vnd.accpac.simply.aso
+application/vnd.accpac.simply.imp
+application/vnd.acucobol
+application/vnd.acucorp
+application/vnd.adobe.xfdf
+application/vnd.aether.imp
+application/vnd.amiga.ami
+application/vnd.anser-web-certificate-issue-initiation
+application/vnd.anser-web-funds-transfer-initiation
+application/vnd.audiograph
+application/vnd.blueice.multipass
+application/vnd.bmi
+application/vnd.businessobjects
+application/vnd.canon-cpdl
+application/vnd.canon-lips
+application/vnd.cinderella
+application/vnd.claymore
+application/vnd.commerce-battelle
+application/vnd.commonspace
+application/vnd.contact.cmsg
+application/vnd.cosmocaller
+application/vnd.criticaltools.wbs+xml
+application/vnd.ctc-posml
+application/vnd.cups-postscript
+application/vnd.cups-raster
+application/vnd.cups-raw
+application/vnd.curl
+application/vnd.cybank
+application/vnd.data-vision.rdz
+application/vnd.dna
+application/vnd.dpgraph
+application/vnd.dreamfactory
+application/vnd.dxr
+application/vnd.ecdis-update
+application/vnd.ecowin.chart
+application/vnd.ecowin.filerequest
+application/vnd.ecowin.fileupdate
+application/vnd.ecowin.series
+application/vnd.ecowin.seriesrequest
+application/vnd.ecowin.seriesupdate
+application/vnd.enliven
+application/vnd.epson.esf
+application/vnd.epson.msf
+application/vnd.epson.quickanime
+application/vnd.epson.salt
+application/vnd.epson.ssf
+application/vnd.ericsson.quickcall
+application/vnd.eudora.data
+application/vnd.fdf
+application/vnd.ffsns
+application/vnd.fints
+application/vnd.flographit
+application/vnd.framemaker
+application/vnd.fsc.weblaunch
+application/vnd.fujitsu.oasys
+application/vnd.fujitsu.oasys2
+application/vnd.fujitsu.oasys3
+application/vnd.fujitsu.oasysgp
+application/vnd.fujitsu.oasysprs
+application/vnd.fujixerox.ddd
+application/vnd.fujixerox.docuworks
+application/vnd.fujixerox.docuworks.binder
+application/vnd.fut-misnet
+application/vnd.grafeq
+application/vnd.groove-account
+application/vnd.groove-help
+application/vnd.groove-identity-message
+application/vnd.groove-injector
+application/vnd.groove-tool-message
+application/vnd.groove-tool-template
+application/vnd.groove-vcard
+application/vnd.hbci
+application/vnd.hhe.lesson-player
+application/vnd.hp-hpgl
+application/vnd.hp-hpid
+application/vnd.hp-hps
+application/vnd.hp-pcl
+application/vnd.hp-pclxl
+application/vnd.httphone
+application/vnd.hzn-3d-crossword
+application/vnd.ibm.afplinedata
+application/vnd.ibm.electronic-media
+application/vnd.ibm.minipay
+application/vnd.ibm.modcap
+application/vnd.ibm.rights-management
+application/vnd.ibm.secure-container
+application/vnd.informix-visionary
+application/vnd.intercon.formnet
+application/vnd.intertrust.digibox
+application/vnd.intertrust.nncp
+application/vnd.intu.qbo
+application/vnd.intu.qfx
+application/vnd.irepository.package+xml
+application/vnd.is-xpr
+application/vnd.japannet-directory-service
+application/vnd.japannet-jpnstore-wakeup
+application/vnd.japannet-payment-wakeup
+application/vnd.japannet-registration
+application/vnd.japannet-registration-wakeup
+application/vnd.japannet-setstore-wakeup
+application/vnd.japannet-verification
+application/vnd.japannet-verification-wakeup
+application/vnd.jisp
+application/vnd.kde.karbon
+application/vnd.kde.kchart
+application/vnd.kde.kformula
+application/vnd.kde.kivio
+application/vnd.kde.kontour
+application/vnd.kde.kpresenter
+application/vnd.kde.kspread
+application/vnd.kde.kword
+application/vnd.kenameaapp
+application/vnd.koan
+application/vnd.liberty-request+xml
+application/vnd.llamagraphics.life-balance.desktop
+application/vnd.llamagraphics.life-balance.exchange+xml
+application/vnd.lotus-1-2-3
+application/vnd.lotus-approach
+application/vnd.lotus-freelance
+application/vnd.lotus-notes
+application/vnd.lotus-organizer
+application/vnd.lotus-screencam
+application/vnd.lotus-wordpro
+application/vnd.mcd
+application/vnd.mediastation.cdkey
+application/vnd.meridian-slingshot
+application/vnd.micrografx.flo
+application/vnd.micrografx.igx
+application/vnd.mif mif
+application/vnd.minisoft-hp3000-save
+application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.mobius.daf
+application/vnd.mobius.dis
+application/vnd.mobius.mbk
+application/vnd.mobius.mqy
+application/vnd.mobius.msl
+application/vnd.mobius.plc
+application/vnd.mobius.txf
+application/vnd.mophun.application
+application/vnd.mophun.certificate
+application/vnd.motorola.flexsuite
+application/vnd.motorola.flexsuite.adsi
+application/vnd.motorola.flexsuite.fis
+application/vnd.motorola.flexsuite.gotap
+application/vnd.motorola.flexsuite.kmr
+application/vnd.motorola.flexsuite.ttc
+application/vnd.motorola.flexsuite.wem
+application/vnd.mozilla.xul+xml xul
+application/vnd.ms-artgalry
+application/vnd.ms-asf
+application/vnd.ms-excel xls
+application/vnd.ms-lrm
+application/vnd.ms-powerpoint ppt
+application/vnd.ms-project
+application/vnd.ms-tnef
+application/vnd.ms-works
+application/vnd.ms-wpl
+application/vnd.mseq
+application/vnd.msign
+application/vnd.music-niff
+application/vnd.musician
+application/vnd.netfpx
+application/vnd.noblenet-directory
+application/vnd.noblenet-sealer
+application/vnd.noblenet-web
+application/vnd.novadigm.edm
+application/vnd.novadigm.edx
+application/vnd.novadigm.ext
+application/vnd.obn
+application/vnd.osa.netdeploy
+application/vnd.palm
+application/vnd.pg.format
+application/vnd.pg.osasli
+application/vnd.powerbuilder6
+application/vnd.powerbuilder6-s
+application/vnd.powerbuilder7
+application/vnd.powerbuilder7-s
+application/vnd.powerbuilder75
+application/vnd.powerbuilder75-s
+application/vnd.previewsystems.box
+application/vnd.publishare-delta-tree
+application/vnd.pvi.ptid1
+application/vnd.pwg-multiplexed
+application/vnd.pwg-xhtml-print+xml
+application/vnd.quark.quarkxpress
+application/vnd.rapid
+application/vnd.s3sms
+application/vnd.sealed.net
+application/vnd.seemail
+application/vnd.shana.informed.formdata
+application/vnd.shana.informed.formtemplate
+application/vnd.shana.informed.interchange
+application/vnd.shana.informed.package
+application/vnd.smaf
+application/vnd.sss-cod
+application/vnd.sss-dtf
+application/vnd.sss-ntf
+application/vnd.street-stream
+application/vnd.svd
+application/vnd.swiftview-ics
+application/vnd.triscape.mxs
+application/vnd.trueapp
+application/vnd.truedoc
+application/vnd.ufdl
+application/vnd.uplanet.alert
+application/vnd.uplanet.alert-wbxml
+application/vnd.uplanet.bearer-choice
+application/vnd.uplanet.bearer-choice-wbxml
+application/vnd.uplanet.cacheop
+application/vnd.uplanet.cacheop-wbxml
+application/vnd.uplanet.channel
+application/vnd.uplanet.channel-wbxml
+application/vnd.uplanet.list
+application/vnd.uplanet.list-wbxml
+application/vnd.uplanet.listcmd
+application/vnd.uplanet.listcmd-wbxml
+application/vnd.uplanet.signal
+application/vnd.vcx
+application/vnd.vectorworks
+application/vnd.vidsoft.vidconference
+application/vnd.visio
+application/vnd.visionary
+application/vnd.vividence.scriptfile
+application/vnd.vsf
+application/vnd.wap.sic
+application/vnd.wap.slc
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo
+application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf
+application/vnd.wv.csp+wbxml
+application/vnd.xara
+application/vnd.xfdl
+application/vnd.yamaha.hv-dic
+application/vnd.yamaha.hv-script
+application/vnd.yamaha.hv-voice
+application/vnd.yellowriver-custom-menu
+application/voicexml+xml vxml
+application/watcherinfo+xml
+application/whoispp-query
+application/whoispp-response
+application/wita
+application/wordperfect5.1
+application/x-bcpio bcpio
+application/x-cdlink vcd
+application/x-chess-pgn pgn
+application/x-compress
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-futuresplash spl
+application/x-gtar gtar
+application/x-gzip
+application/x-hdf hdf
+application/x-javascript js
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-netcdf nc cdf
+application/x-sh sh
+application/x-shar shar
+application/x-shockwave-flash swf
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/x400-bp
+application/xhtml+xml xhtml xht
+application/xslt+xml xslt
+application/xml xml xsl
+application/xml-dtd dtd
+application/xml-external-parsed-entity
+application/zip zip
+audio/32kadpcm
+audio/amr
+audio/amr-wb
+audio/basic au snd
+audio/cn
+audio/dat12
+audio/dsr-es201108
+audio/dvi4
+audio/evrc
+audio/evrc0
+audio/g722
+audio/g.722.1
+audio/g723
+audio/g726-16
+audio/g726-24
+audio/g726-32
+audio/g726-40
+audio/g728
+audio/g729
+audio/g729D
+audio/g729E
+audio/gsm
+audio/gsm-efr
+audio/l8
+audio/l16
+audio/l20
+audio/l24
+audio/lpc
+audio/midi mid midi kar
+audio/mpa
+audio/mpa-robust
+audio/mp4a-latm
+audio/mpeg mpga mp2 mp3
+audio/parityfec
+audio/pcma
+audio/pcmu
+audio/prs.sid
+audio/qcelp
+audio/red
+audio/smv
+audio/smv0
+audio/telephone-event
+audio/tone
+audio/vdvi
+audio/vnd.3gpp.iufp
+audio/vnd.cisco.nse
+audio/vnd.cns.anp1
+audio/vnd.cns.inf1
+audio/vnd.digital-winds
+audio/vnd.everad.plj
+audio/vnd.lucent.voice
+audio/vnd.nortel.vbk
+audio/vnd.nuera.ecelp4800
+audio/vnd.nuera.ecelp7470
+audio/vnd.nuera.ecelp9600
+audio/vnd.octel.sbc
+audio/vnd.qcelp
+audio/vnd.rhetorex.32kadpcm
+audio/vnd.vmx.cvsd
+audio/x-aiff aif aiff aifc
+audio/x-alaw-basic
+audio/x-mpegurl m3u
+audio/x-pn-realaudio ram ra
+audio/x-pn-realaudio-plugin
+application/vnd.rn-realmedia rm
+audio/x-wav wav
+chemical/x-pdb pdb
+chemical/x-xyz xyz
+image/bmp bmp
+image/cgm cgm
+image/g3fax
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/naplps
+image/png png
+image/prs.btif
+image/prs.pti
+image/svg+xml svg
+image/t38
+image/tiff tiff tif
+image/tiff-fx
+image/vnd.cns.inf2
+image/vnd.djvu djvu djv
+image/vnd.dwg
+image/vnd.dxf
+image/vnd.fastbidsheet
+image/vnd.fpx
+image/vnd.fst
+image/vnd.fujixerox.edmics-mmr
+image/vnd.fujixerox.edmics-rlc
+image/vnd.globalgraphics.pgb
+image/vnd.mix
+image/vnd.ms-modi
+image/vnd.net-fpx
+image/vnd.svf
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff
+image/x-cmu-raster ras
+image/x-icon ico
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+message/delivery-status
+message/disposition-notification
+message/external-body
+message/http
+message/news
+message/partial
+message/rfc822
+message/s-http
+message/sip
+message/sipfrag
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.dwf
+model/vnd.flatland.3dml
+model/vnd.gdl
+model/vnd.gs-gdl
+model/vnd.gtw
+model/vnd.mts
+model/vnd.parasolid.transmit.binary
+model/vnd.parasolid.transmit.text
+model/vnd.vtu
+model/vrml wrl vrml
+multipart/alternative
+multipart/appledouble
+multipart/byteranges
+multipart/digest
+multipart/encrypted
+multipart/form-data
+multipart/header-set
+multipart/mixed
+multipart/parallel
+multipart/related
+multipart/report
+multipart/signed
+multipart/voice-message
+text/calendar ics ifb
+text/css css
+text/directory
+text/enriched
+text/html html htm
+text/parityfec
+text/plain asc txt
+text/prs.lines.tag
+text/rfc822-headers
+text/richtext rtx
+text/rtf rtf
+text/sgml sgml sgm
+text/t140
+text/tab-separated-values tsv
+text/uri-list
+text/vnd.abc
+text/vnd.curl
+text/vnd.dmclientscript
+text/vnd.fly
+text/vnd.fmi.flexstor
+text/vnd.in3d.3dml
+text/vnd.in3d.spot
+text/vnd.iptc.nitf
+text/vnd.iptc.newsml
+text/vnd.latex-z
+text/vnd.motorola.reflex
+text/vnd.ms-mediapackage
+text/vnd.net2phone.commcenter.command
+text/vnd.sun.j2me.app-descriptor
+text/vnd.wap.si
+text/vnd.wap.sl
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/x-setext etx
+text/xml
+text/xml-external-parsed-entity
+video/bmpeg
+video/bt656
+video/celb
+video/dv
+video/h261
+video/h263
+video/h263-1998
+video/h263-2000
+video/jpeg
+video/mp1s
+video/mp2p
+video/mp2t
+video/mp4v-es
+video/mpv
+video/mpeg mpeg mpg mpe
+video/nv
+video/parityfec
+video/pointer
+video/quicktime qt mov
+video/smpte292m
+video/vnd.fvt
+video/vnd.motorola.video
+video/vnd.motorola.videop
+video/vnd.mpegurl mxu m4u
+video/vnd.nokia.interleaved-multimedia
+video/vnd.objectvideo
+video/vnd.vivo
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
diff --git a/sca-cpp/branches/gcc-4.4/modules/http/curl-test.cpp b/sca-cpp/branches/gcc-4.4/modules/http/curl-test.cpp
new file mode 100644
index 0000000000..c9b85ad962
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/http/curl-test.cpp
@@ -0,0 +1,91 @@
+/*
+ * 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 <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "perf.hpp"
+#include "curl.hpp"
+
+namespace tuscany {
+namespace http {
+
+string testURI = "http://localhost:8090";
+
+ostream* curlWriter(const string& s, ostream* os) {
+ (*os) << s;
+ return os;
+}
+
+const bool testGet() {
+ CURLSession ch;
+ {
+ ostringstream os;
+ const failable<list<ostream*> > r = get<ostream*>(curlWriter, &os, testURI, ch);
+ assert(hasContent(r));
+ assert(contains(str(os), "HTTP/1.1 200 OK"));
+ assert(contains(str(os), "It works"));
+ }
+ {
+ const failable<value> r = getcontent(testURI, ch);
+ assert(hasContent(r));
+ assert(contains(car(reverse(list<value>(content(r)))), "It works"));
+ }
+ return true;
+}
+
+struct getLoop {
+ CURLSession& ch;
+ getLoop(CURLSession& ch) : ch(ch) {
+ }
+ const bool operator()() const {
+ const failable<value> r = getcontent(testURI, ch);
+ assert(hasContent(r));
+ assert(contains(car(reverse(list<value>(content(r)))), "It works"));
+ return true;
+ }
+};
+
+const bool testGetPerf() {
+ CURLSession ch;
+ lambda<bool()> gl = getLoop(ch);
+ cout << "Static GET test " << time(gl, 5, 200) << " ms" << endl;
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+ tuscany::http::testURI = tuscany::string("http://") + tuscany::http::hostname() + ":8090";
+
+ tuscany::http::testGet();
+ tuscany::http::testGetPerf();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/http/curl.hpp b/sca-cpp/branches/gcc-4.4/modules/http/curl.hpp
new file mode 100644
index 0000000000..95c81d9b94
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/http/curl.hpp
@@ -0,0 +1,441 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_curl_hpp
+#define tuscany_curl_hpp
+
+/**
+ * CURL HTTP client functions.
+ */
+
+#include <curl/curl.h>
+#include <curl/types.h>
+#include <curl/easy.h>
+#include "string.hpp"
+#include "gc.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "element.hpp"
+#include "monad.hpp"
+#include "parallel.hpp"
+#include "../atom/atom.hpp"
+#include "../json/json.hpp"
+
+namespace tuscany {
+namespace http {
+
+/**
+ * CURL library runtime, one per process.
+ */
+class CURLRuntime {
+public:
+ CURLRuntime() {
+ curl_global_init(CURL_GLOBAL_ALL);
+ }
+} curlRuntime;
+
+/**
+ * Represents a CURL session handle.
+ */
+class CURLSession {
+public:
+ CURLSession(const string& ca = "", const string& cert = "", const string& key = "") : h(curl_easy_init()), owner(true), ca(ca), cert(cert), key(key) {
+ }
+
+ CURLSession(const CURLSession& c) : h(c.h), owner(false), ca(c.ca), cert(c.cert), key(c.key) {
+ }
+
+ ~CURLSession() {
+ if (!owner)
+ return;
+ if (h == NULL)
+ return;
+ curl_easy_cleanup(h);
+ }
+
+private:
+ CURL* h;
+ const bool owner;
+
+ friend CURL* handle(const CURLSession& c);
+
+public:
+ const string ca;
+ const string cert;
+ const string key;
+};
+
+/**
+ * Returns the CURL handle used by a CURL session.
+ */
+CURL* handle(const CURLSession& c) {
+ return c.h;
+}
+
+/**
+ * Context passed to the read callback function.
+ */
+class CURLReadContext {
+public:
+ CURLReadContext(const list<string>& ilist) : ilist(ilist) {
+ }
+ list<string> ilist;
+};
+
+/**
+ * Called by CURL to read data to send.
+ */
+size_t readCallback(void *ptr, size_t size, size_t nmemb, void *data) {
+ CURLReadContext& rcx = *static_cast<CURLReadContext*>(data);
+ if (isNil(rcx.ilist))
+ return 0;
+ const list<string> f(fragment(rcx.ilist, size * nmemb));
+ const string s = car(f);
+ rcx.ilist = cdr(f);
+ memcpy(ptr, c_str(s), length(s));
+ return length(s);
+}
+
+/**
+ * Context passed to CURL write callback function.
+ */
+template<typename R> class CURLWriteContext {
+public:
+ CURLWriteContext(const lambda<R(const string&, const R)>& reduce, const R& accum) : reduce(reduce), accum(accum) {
+ }
+ const lambda<R(const string&, const R)> reduce;
+ R accum;
+};
+
+/**
+ * Called by CURL to write received data.
+ */
+template<typename R> size_t writeCallback(void *ptr, size_t size, size_t nmemb, void *data) {
+ CURLWriteContext<R>& wcx = *(static_cast<CURLWriteContext<R>*> (data));
+ const size_t realsize = size * nmemb;
+ wcx.accum = wcx.reduce(string((const char*)ptr, realsize), wcx.accum);
+ return realsize;
+}
+
+/**
+ * Apply an HTTP verb to a list containing a list of headers and a list of content, and
+ * a reduce function used to process the response.
+ */
+curl_slist* headers(curl_slist* cl, const list<string>& h) {
+ if (isNil(h))
+ return cl;
+ return headers(curl_slist_append(cl, c_str(string(car(h)))), cdr(h));
+}
+
+template<typename R> const failable<list<R> > apply(const list<list<string> >& hdr, const lambda<R(const string&, const R)>& reduce, const R& initial, const string& url, const string& verb, const CURLSession& cs) {
+
+ // Init the curl session
+ CURL* ch = handle(cs);
+ curl_easy_reset(ch);
+ curl_easy_setopt(ch, CURLOPT_USERAGENT, "libcurl/1.0");
+
+ //TODO use HTTP chunking, for now just convert request to a single string
+ ostringstream os;
+ write(cadr(hdr), os);
+ const string s = str(os);
+ const int sz = length(s);
+
+ // Setup the read, header and write callbacks
+ CURLReadContext rcx(mklist(s));
+ curl_easy_setopt(ch, CURLOPT_READFUNCTION, (size_t (*)(void*, size_t, size_t, void*))readCallback);
+ curl_easy_setopt(ch, CURLOPT_READDATA, &rcx);
+ CURLWriteContext<R> hcx(reduce, initial);
+ curl_easy_setopt(ch, CURLOPT_HEADERFUNCTION, (size_t (*)(void*, size_t, size_t, void*))(writeCallback<R>));
+ curl_easy_setopt(ch, CURLOPT_HEADERDATA, &hcx);
+ CURLWriteContext<R> wcx(reduce, initial);
+ curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, (size_t (*)(void*, size_t, size_t, void*))(writeCallback<R>));
+ curl_easy_setopt(ch, CURLOPT_WRITEDATA, &wcx);
+
+ // Setup protocol options
+ curl_easy_setopt(ch, CURLOPT_TCP_NODELAY, true);
+ curl_easy_setopt(ch, CURLOPT_FOLLOWLOCATION, true);
+ curl_easy_setopt(ch, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
+
+ // Setup SSL options
+ if (cs.ca != "") {
+ debug(cs.ca, "http::apply::ca");
+ curl_easy_setopt(ch, CURLOPT_CAINFO, c_str(cs.ca));
+ curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, true);
+ curl_easy_setopt(ch, CURLOPT_SSL_VERIFYHOST, 2);
+ }
+ if (cs.cert != "") {
+ debug(cs.cert, "http::apply::cert");
+ curl_easy_setopt(ch, CURLOPT_SSLCERT, c_str(cs.cert));
+ curl_easy_setopt(ch, CURLOPT_SSLCERTTYPE, "PEM");
+ }
+ if (cs.key != "") {
+ debug(cs.key, "http::apply::key");
+ curl_easy_setopt(ch, CURLOPT_SSLKEY, c_str(cs.key));
+ curl_easy_setopt(ch, CURLOPT_SSLKEYTYPE, "PEM");
+ }
+
+ // Set the request headers
+ curl_slist* hl = headers(NULL, car(hdr));
+ if (hl != NULL)
+ curl_easy_setopt(ch, CURLOPT_HTTPHEADER, hl);
+
+ // Apply the HTTP verb
+ curl_easy_setopt(ch, CURLOPT_URL, c_str(url));
+ if (verb == "POST") {
+ curl_easy_setopt(ch, CURLOPT_POST, true);
+ curl_easy_setopt(ch, CURLOPT_POSTFIELDSIZE, sz);
+ } else if (verb == "PUT") {
+ curl_easy_setopt(ch, CURLOPT_UPLOAD, true);
+ curl_easy_setopt(ch, CURLOPT_INFILESIZE, sz);
+ } else if (verb == "DELETE")
+ curl_easy_setopt(ch, CURLOPT_CUSTOMREQUEST, "DELETE");
+ const CURLcode rc = curl_easy_perform(ch);
+
+ if (hl != NULL)
+ curl_slist_free_all(hl);
+
+ // Return the HTTP return code or content
+ if (rc)
+ return mkfailure<list<R> >(string(curl_easy_strerror(rc)));
+ long httprc;
+ curl_easy_getinfo (ch, CURLINFO_RESPONSE_CODE, &httprc);
+ if (httprc != 200 && httprc != 201) {
+ ostringstream es;
+ es << "HTTP code " << httprc;
+ return mkfailure<list<R> >(str(es));
+ }
+ return mklist<R>(hcx.accum, wcx.accum);
+}
+
+/**
+ * Evaluate an expression remotely, at the given URL.
+ */
+const failable<value> evalExpr(const value& expr, const string& url, const CURLSession& ch) {
+ debug(url, "http::evalExpr::url");
+ debug(expr, "http::evalExpr::input");
+
+ // Convert expression to a JSON-RPC request
+ json::JSONContext cx;
+ const failable<list<string> > jsreq = json::jsonRequest(1, car<value>(expr), cdr<value>(expr), cx);
+ if (!hasContent(jsreq))
+ return mkfailure<value>(reason(jsreq));
+
+ // POST it to the URL
+ const list<string> h = mklist<string>("Content-Type: application/json-rpc");
+ const failable<list<list<string> > > res = apply<list<string> >(mklist<list<string> >(h, content(jsreq)), rcons<string>, list<string>(), url, "POST", ch);
+ if (!hasContent(res))
+ return mkfailure<value>(reason(res));
+
+ // Parse and return JSON-RPC result
+ const failable<value> rval = json::jsonResultValue(cadr<list<string> >(content(res)), cx);
+ if (!hasContent(rval))
+ return mkfailure<value>(reason(rval));
+ debug(content(rval), "http::evalExpr::result");
+ return content(rval);
+}
+
+/**
+ * Find and return a header.
+ */
+const failable<string> header(const char* prefix, const list<string>& h) {
+ if (isNil(h))
+ return mkfailure<string>(string("Couldn't find header: ") + prefix);
+ const string s = car(h);
+ if (find(s, prefix) != 0)
+ return header(prefix, cdr(h));
+ const string l(substr(s, length(prefix)));
+ return substr(l, 0, find_first_of(l, "\r\n"));
+}
+
+/**
+ * Find and return a location header.
+ */
+const failable<string> location(const list<string>& h) {
+ return header("Location: ", h);
+}
+
+/**
+ * Convert a location to an entry id.
+ */
+const failable<value> entryId(const failable<string> l) {
+ if (!hasContent(l))
+ return mkfailure<value>(reason(l));
+ const string ls(content(l));
+ return value(mklist<value>(string(substr(ls, find_last(ls, '/') + 1))));
+}
+
+/**
+ * Find and return a content-type header.
+ */
+const failable<string> contentType(const list<string>& h) {
+ return header("Content-Type: ", h);
+}
+
+/**
+ * HTTP GET, return the resource at the given URL.
+ */
+template<typename R> const failable<list<R> > get(const lambda<R(const string&, const R)>& reduce, const R& initial, const string& url, const CURLSession& ch) {
+ debug(url, "http::get::url");
+ const list<list<string> > req = mklist(list<string>(), list<string>());
+ return apply(req, reduce, initial, url, "GET", ch);
+}
+
+/**
+ * HTTP GET, return a list of values representing the resource at the given URL.
+ */
+const failable<value> getcontent(const string& url, const CURLSession& ch) {
+ debug(url, "http::get::url");
+
+ // Get the contents of the resource at the given URL
+ const failable<list<list<string> > > res = get<list<string>>(rcons<string>, list<string>(), url, ch);
+ if (!hasContent(res))
+ return mkfailure<value>(reason(res));
+ const list<string> ls(reverse(cadr(content(res))));
+
+ // Return the content as a list of values
+ const value val(mkvalues(ls));
+ debug(val, "http::get::result");
+ return val;
+}
+
+/**
+ * HTTP GET, return a list of values representing the resource at the given URL.
+ */
+const failable<value> get(const string& url, const CURLSession& ch) {
+ debug(url, "http::get::url");
+
+ // Get the contents of the resource at the given URL
+ const failable<list<list<string> > > res = get<list<string> >(rcons<string>, list<string>(), url, ch);
+ if (!hasContent(res))
+ return mkfailure<value>(reason(res));
+ const list<string> ls(reverse(cadr(content(res))));
+
+ const string ct(content(contentType(car(content(res)))));
+ if (ct == "application/atom+xml;type=entry") {
+ const value val(atom::entryValue(content(atom::readATOMEntry(ls))));
+ debug(val, "http::get::result");
+ return val;
+ }
+
+ // Return the content as a list of values
+ const value val(mkvalues(ls));
+ debug(val, "http::get::result");
+ return val;
+}
+
+/**
+ * HTTP POST.
+ */
+const failable<value> post(const value& val, const string& url, const CURLSession& ch) {
+
+ // Convert value to an ATOM entry
+ const failable<list<string> > entry = atom::writeATOMEntry(atom::entryValuesToElements(val));
+ if (!hasContent(entry))
+ return mkfailure<value>(reason(entry));
+ debug(url, "http::post::url");
+ debug(content(entry), "http::post::input");
+
+ // POST it to the URL
+ const list<string> h = mklist<string>("Content-Type: application/atom+xml");
+ const list<list<string> > req = mklist<list<string> >(h, content(entry));
+ const failable<list<list<string> > > res = apply<list<string>>(req, rcons<string>, list<string>(), url, "POST", ch);
+ if (!hasContent(res))
+ return mkfailure<value>(reason(res));
+
+ // Return the new entry id from the HTTP location header
+ const failable<value> eid(entryId(location(car(content(res)))));
+ debug(eid, "http::post::result");
+ return eid;
+}
+
+/**
+ * HTTP PUT.
+ */
+const failable<value> put(const value& val, const string& url, const CURLSession& ch) {
+
+ // Convert value to an ATOM entry
+ const failable<list<string> > entry = atom::writeATOMEntry(atom::entryValuesToElements(val));
+ if (!hasContent(entry))
+ return mkfailure<value>(reason(entry));
+ debug(url, "http::put::url");
+ debug(content(entry), "http::put::input");
+
+ // PUT it to the URL
+ const list<string> h = mklist<string>("Content-Type: application/atom+xml");
+ const list<list<string> > req = mklist<list<string> >(h, content(entry));
+ const failable<list<list<string> > > res = apply<list<string> >(req, rcons<string>, list<string>(), url, "PUT", ch);
+ if (!hasContent(res))
+ return mkfailure<value>(reason(res));
+
+ debug(true, "http::put::result");
+ return value(true);
+}
+
+/**
+ * HTTP DELETE.
+ */
+const failable<value, string> del(const string& url, const CURLSession& ch) {
+ debug(url, "http::delete::url");
+
+ const list<list<string> > req = mklist(list<string>(), list<string>());
+ const failable<list<list<string> > > res = apply<list<string> >(req, rcons<string>, list<string>(), url, "DELETE", ch);
+ if (!hasContent(res))
+ return mkfailure<value>(reason(res));
+
+ debug(true, "http::delete::result");
+ return value(true);
+}
+
+/**
+ * Returns the current host name.
+ */
+const string hostname() {
+ char h[256];
+ if (gethostname(h, 256) == -1)
+ return "localhost";
+ return h;
+}
+
+/**
+ * HTTP client proxy function.
+ */
+struct proxy {
+ proxy(const string& uri, const string& ca, const string& cert, const string& key) : uri(uri), ca(ca), cert(cert), key(key) {
+ }
+
+ const value operator()(const list<value>& args) const {
+ CURLSession cs(ca, cert, key);
+ failable<value> val = evalExpr(args, uri, cs);
+ if (!hasContent(val))
+ return value();
+ return content(val);
+ }
+
+ const string uri;
+ const string ca;
+ const string cert;
+ const string key;
+};
+
+}
+}
+
+#endif /* tuscany_curl_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/http/htdocs/index.html b/sca-cpp/branches/gcc-4.4/modules/http/htdocs/index.html
new file mode 100644
index 0000000000..1bfb3e30c2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/http/htdocs/index.html
@@ -0,0 +1,21 @@
+<!--
+ 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><body><h1>It works!</h1></body></html>
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/http/http-test b/sca-cpp/branches/gcc-4.4/modules/http/http-test
new file mode 100755
index 0000000000..0db47fe189
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/http/http-test
@@ -0,0 +1,32 @@
+#!/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
+./httpd-conf tmp localhost 8090 htdocs
+./httpd-start tmp
+sleep 2
+
+# Test
+./curl-test
+rc=$?
+
+# Cleanup
+./httpd-stop tmp
+sleep 2
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/modules/http/httpd-ca-conf b/sca-cpp/branches/gcc-4.4/modules/http/httpd-ca-conf
new file mode 100755
index 0000000000..c5a3f8e894
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/http/httpd-ca-conf
@@ -0,0 +1,89 @@
+#!/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.
+
+# Generate a test certification authority certificate
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+host=$2
+
+# Don't override existing certificate
+if [ -f $root/conf/ca.crt ]; then
+ return 0
+fi
+
+# Generate openssl configuration
+mkdir -p $root/conf
+umask 0007
+cat >$root/conf/openssl-ca.conf <<EOF
+[ req ]
+default_bits = 1024
+encrypt_key = no
+prompt = no
+distinguished_name = req_distinguished_name
+x509_extensions = v3_ca
+
+[ req_distinguished_name ]
+C = US
+ST = CA
+L = San Francisco
+O = Test Authority Organization
+OU = Test Authority Unit
+CN = $host
+emailAddress = root@$host
+
+[ v3_ca ]
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always,issuer:always
+basicConstraints = CA:true
+
+[ca]
+default_ca = ca_default
+
+[ca_default]
+certificate = $root/conf/ca.crt
+private_key = $root/conf/ca.key
+serial = $root/conf/ca-serial
+database = $root/conf/ca-database
+new_certs_dir = $root/conf
+default_md = sha1
+email_in_dn = no
+default_days = 365
+default_crl_days = 30
+policy = policy_any
+copy_extensions = none
+
+[ policy_any ]
+countryName = supplied
+stateOrProvinceName = optional
+localityName = optional
+organizationName = optional
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+EOF
+
+rm -rf $root/conf/*.pem
+rm -f $root/conf/ca-database
+echo 1000 > $root/conf/ca-serial
+touch $root/conf/ca-database
+
+# Generate the certification authority certificate
+openssl req -new -x509 -config $root/conf/openssl-ca.conf -out $root/conf/ca.crt -keyout $root/conf/ca.key
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/http/httpd-cert-conf b/sca-cpp/branches/gcc-4.4/modules/http/httpd-cert-conf
new file mode 100755
index 0000000000..b6dc8ebd6f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/http/httpd-cert-conf
@@ -0,0 +1,58 @@
+#!/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.
+
+# Generate a test certificate
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+host=$2
+
+# Don't regenerate the certificate if it already exists
+if [ -f $root/conf/server.crt ]; then
+ return 0
+fi
+
+# Generate openssl configuration
+mkdir -p $root/conf
+umask 0007
+cat >$root/conf/openssl-cert.conf <<EOF
+[ req ]
+default_bits = 1024
+encrypt_key = no
+prompt = no
+distinguished_name = req_distinguished_name
+
+[ req_distinguished_name ]
+C = US
+ST = CA
+L = San Francisco
+O = Test Organization
+OU = Test Unit
+CN = $host
+emailAddress = root@$host
+EOF
+
+# Generate a certificate request
+openssl req -new -config $root/conf/openssl-cert.conf -out $root/conf/server-req.crt -keyout $root/conf/server.key
+
+# Generate a certificate, signed with our test certification authority certificate
+openssl ca -batch -config $root/conf/openssl-ca.conf -out $root/conf/server.crt -infiles $root/conf/server-req.crt
+
+# Export it to PKCS12 format, that's the format Web browsers want to import
+openssl pkcs12 -export -passout pass: -out $root/conf/server.p12 -inkey $root/conf/server.key -in $root/conf/server.crt -certfile $root/conf/ca.crt
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/http/httpd-conf b/sca-cpp/branches/gcc-4.4/modules/http/httpd-conf
new file mode 100755
index 0000000000..fa3ce09fc9
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/http/httpd-conf
@@ -0,0 +1,93 @@
+#!/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.
+
+# Generate a minimal HTTPD configuration
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+host=$2
+port=$3
+htdocs=`readlink -f $4`
+user=`id -un`
+group=`id -gn`
+
+mkdir -p $root
+mkdir -p $root/logs
+mkdir -p $root/conf
+cat >$root/conf/httpd.conf <<EOF
+# Apache HTTPD server configuration
+
+# Set server name
+ServerName $host
+
+# Basic security precautions
+User $user
+Group $group
+ServerSignature Off
+ServerTokens Prod
+Timeout 45
+LimitRequestBody 1048576
+HostNameLookups Off
+
+# Logging
+ErrorLog $root/logs/error_log
+LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
+CustomLog $root/logs/access_log combined
+LogLevel warn
+
+# Configure Mime types
+DefaultType text/plain
+TypesConfig $here/conf/mime.types
+
+# Set document root
+DocumentRoot $htdocs
+DirectoryIndex index.html
+
+# Protect server files
+<Directory />
+Options None
+AllowOverride None
+Order deny,allow
+Deny from all
+</Directory>
+<FilesMatch "^\.ht">
+Order deny,allow
+Deny from all
+Satisfy Any
+</FilesMatch>
+
+# Allow access to document root
+<Directory "$htdocs">
+Options +SymLinksIfOwnerMatch
+Allow from all
+</Directory>
+
+# Allow access to service components
+<Location />
+Options +SymLinksIfOwnerMatch
+Allow from all
+</Location>
+
+# Setup HTTP virtual host
+Listen $port
+<VirtualHost _default_:$port>
+
+</VirtualHost>
+
+EOF
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/http/httpd-restart b/sca-cpp/branches/gcc-4.4/modules/http/httpd-restart
new file mode 100755
index 0000000000..92f27eb0df
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/http/httpd-restart
@@ -0,0 +1,25 @@
+#!/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.
+
+# Restart httpd server
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+
+httpd_prefix=`cat $here/httpd.prefix`
+$httpd_prefix/bin/apachectl -k graceful -d $root
diff --git a/sca-cpp/branches/gcc-4.4/modules/http/httpd-ssl-conf b/sca-cpp/branches/gcc-4.4/modules/http/httpd-ssl-conf
new file mode 100755
index 0000000000..6f763c6a66
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/http/httpd-ssl-conf
@@ -0,0 +1,94 @@
+#!/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.
+
+# Generate a minimal HTTPD SSL configuration
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+host=$2
+sslport=$3
+htdocs=`readlink -f $4`
+httpd_prefix=`cat $here/httpd.prefix`
+
+# Extract organization name from our CA certificate
+org=`openssl x509 -noout -subject -nameopt multiline -in $root/conf/ca.crt | grep organizationName | awk -F "= " '{ print $2 }'`
+
+# Generate HTTPD configuration
+cat >>$root/conf/httpd.conf <<EOF
+# Redirect all HTTP traffic to HTTPS
+<Location />
+RewriteEngine on
+RewriteCond %{SERVER_PORT} !^$sslport$
+RewriteRule .* https://%{SERVER_NAME}:$sslport%{REQUEST_URI} [R,L]
+</Location>
+
+# Setup SSL support
+AddType application/x-x509-ca-cert .crt
+AddType application/x-pkcs7-crl .crl
+SSLPassPhraseDialog builtin
+SSLSessionCache "shmcb:$root/logs/ssl_scache(512000)"
+SSLSessionCacheTimeout 300
+SSLMutex "file:$root/logs/ssl_mutex"
+SSLRandomSeed startup builtin
+SSLRandomSeed connect builtin
+
+# HTTPS virtual host
+Listen $sslport
+<VirtualHost _default_:$sslport>
+
+# Enable SSL
+SSLEngine on
+SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
+SSLCACertificateFile "$root/conf/ca.crt"
+SSLCertificateFile "$root/conf/server.crt"
+SSLCertificateKeyFile "$root/conf/server.key"
+BrowserMatch ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
+
+# Logging
+CustomLog "$root/logs/ssl_request_log" "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
+LogFormat "%h %l %u %t %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" sslcombined
+CustomLog $root/logs/ssl_access_log sslcombined
+LogLevel warn
+
+# Require clients to present either:
+# a certificate signed with our certification authority certificate
+# or a userid + password for HTTP basic authentication
+<Location />
+Satisfy Any
+
+SSLVerifyClient optional
+SSLVerifyDepth 1
+SSLOptions +FakeBasicAuth
+SSLRequireSSL
+SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128 and %{SSL_CLIENT_I_DN_O} == "$org"
+
+AuthType Basic
+AuthName "$host"
+AuthUserFile "$root/conf/httpd.passwd"
+Require valid-user
+</location>
+
+</VirtualHost>
+
+EOF
+
+# Create test users for HTTP basic authentication
+$httpd_prefix/bin/htpasswd -bc $root/conf/httpd.passwd test test 2>/dev/null
+$httpd_prefix/bin/htpasswd -b $root/conf/httpd.passwd foo foo 2>/dev/null
+$httpd_prefix/bin/htpasswd -b $root/conf/httpd.passwd bar bar 2>/dev/null
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/http/httpd-start b/sca-cpp/branches/gcc-4.4/modules/http/httpd-start
new file mode 100755
index 0000000000..91fc5284af
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/http/httpd-start
@@ -0,0 +1,25 @@
+#!/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.
+
+# Start httpd server
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+
+httpd_prefix=`cat $here/httpd.prefix`
+$httpd_prefix/bin/apachectl -E $root/logs/error_log -k start -d $root
diff --git a/sca-cpp/branches/gcc-4.4/modules/http/httpd-stop b/sca-cpp/branches/gcc-4.4/modules/http/httpd-stop
new file mode 100755
index 0000000000..7f4fe94629
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/http/httpd-stop
@@ -0,0 +1,25 @@
+#!/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.
+
+# Stop httpd server
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+
+httpd_prefix=`cat $here/httpd.prefix`
+$httpd_prefix/bin/apachectl -k graceful-stop -d $root
diff --git a/sca-cpp/branches/gcc-4.4/modules/http/httpd-test b/sca-cpp/branches/gcc-4.4/modules/http/httpd-test
new file mode 100755
index 0000000000..a3b9145871
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/http/httpd-test
@@ -0,0 +1,40 @@
+#!/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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../http/curl.prefix`
+
+# Setup
+./httpd-conf tmp localhost 8090 htdocs
+./httpd-start tmp
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/index.html 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/index.html
+rc=$?
+
+# Cleanup
+./httpd-stop tmp
+sleep 2
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/modules/http/httpd.hpp b/sca-cpp/branches/gcc-4.4/modules/http/httpd.hpp
new file mode 100644
index 0000000000..dfc3dcc47e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/http/httpd.hpp
@@ -0,0 +1,404 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_httpd_hpp
+#define tuscany_httpd_hpp
+
+/**
+ * HTTPD module implementation functions.
+ */
+
+#include "apr_strings.h"
+#include "apr_fnmatch.h"
+#include "apr_lib.h"
+#define APR_WANT_STRFUNC
+#include "apr_want.h"
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_core.h"
+#include "http_request.h"
+#include "http_protocol.h"
+#include "http_log.h"
+#include "http_main.h"
+#include "util_script.h"
+#include "util_md5.h"
+#include "http_config.h"
+#include "ap_mpm.h"
+#include "mod_core.h"
+
+#include "string.hpp"
+#include "stream.hpp"
+#include "list.hpp"
+#include "value.hpp"
+
+
+namespace tuscany {
+namespace httpd {
+
+/**
+ * Returns a server-scoped module configuration.
+ */
+template<typename C> void* makeServerConf(apr_pool_t *p, server_rec *s) {
+ return new (gc_new<C>(p)) C(s);
+}
+
+template<typename C> const C& serverConf(const request_rec* r, const module* mod) {
+ return *(C*)ap_get_module_config(r->server->module_config, mod);
+}
+
+template<typename C> C& serverConf(const server_rec* s, const module* mod) {
+ return *(C*)ap_get_module_config(s->module_config, mod);
+}
+
+template<typename C> C& serverConf(const cmd_parms *cmd, const module* mod) {
+ return *(C*)ap_get_module_config(cmd->server->module_config, mod);
+}
+
+
+/**
+ * Return the content type of a request.
+ */
+const char* optional(const char* s) {
+ if (s == NULL)
+ return "";
+ return s;
+}
+
+const string contentType(const request_rec* r) {
+ return optional(apr_table_get(r->headers_in, "Content-Type"));
+}
+
+#ifdef WANT_MAINTAINER_MODE
+
+/**
+ * Debug log.
+ */
+int debugHeader(unused void* r, const char* key, const char* value) {
+ cerr << " header key: " << key << ", value: " << value << endl;
+ return 1;
+}
+
+const bool debugRequest(request_rec* r, const string& msg) {
+ cerr << msg << ":" << endl;
+ cerr << " protocol: " << optional(r->protocol) << endl;
+ cerr << " method: " << optional(r->method) << endl;
+ cerr << " method number: " << r->method_number << endl;
+ cerr << " content type: " << contentType(r) << endl;
+ cerr << " content encoding: " << optional(r->content_encoding) << endl;
+ apr_table_do(debugHeader, r, r->headers_in, NULL);
+ cerr << " unparsed uri: " << optional(r->unparsed_uri) << endl;
+ cerr << " uri: " << optional(r->uri) << endl;
+ cerr << " path info: " << optional(r->path_info) << endl;
+ cerr << " filename: " << optional(r->filename) << endl;
+ cerr << " uri tokens: " << pathTokens(r->uri) << endl;
+ cerr << " args: " << optional(r->args) << endl;
+ return true;
+}
+
+#define httpdDebugRequest(r, msg) httpd::debugRequest(r, msg)
+
+#else
+
+#define httpdDebugRequest(r, msg)
+
+#endif
+
+/**
+ * Return the remaining part of a uri after the given path (aka the path info.)
+ */
+const list<value> pathInfo(const list<value>& uri, const list<value>& path) {
+ if (isNil(path))
+ return uri;
+ return pathInfo(cdr(uri), cdr(path));
+}
+
+/**
+ * Returns a list of key value pairs from the args in a query string.
+ */
+const list<value> queryArg(const string& s) {
+ const list<string> t = tokenize("=", s);
+ return mklist<value>(c_str(car(t)), cadr(t));
+}
+
+const list<list<value> > queryArgs(const request_rec* r) {
+ const char* a = r->args;
+ if (a == NULL)
+ return list<list<value> >();
+ return map<string, list<value>>(queryArg, tokenize("&", a));
+}
+
+/**
+ * Returns a list of param values other than the id and method args from a list
+ * of key value pairs.
+ */
+const list<value> queryParams(const list<list<value> >& a) {
+ if (isNil(a))
+ return list<value>();
+ const list<value> p = car(a);
+ if (car(p) == value("id") || car(p) == value("method"))
+ return queryParams(cdr(a));
+ return cons(cadr(p), queryParams(cdr(a)));
+}
+
+/**
+ * Converts the args received in a POST to a list of key value pairs.
+ */
+const list<list<value> > postArgs(const list<value>& a) {
+ if (isNil(a))
+ return list<list<value> >();
+ const list<value> l = car(a);
+ return cons(l, postArgs(cdr(a)));
+}
+
+/**
+ * Setup the HTTP read policy.
+ */
+const int setupReadPolicy(request_rec* r) {
+ const int rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK);
+ if(rc != OK)
+ return rc;
+ ap_should_client_block(r);
+ if(r->read_chunked == true && r->remaining == 0)
+ r->chunked = true;
+ //apr_table_setn(r->headers_out, "Connection", "close");
+ return OK;
+}
+
+/**
+ * Read the content of a POST or PUT.
+ */
+const list<string> read(request_rec* r) {
+ char b[1024];
+ const int n = ap_get_client_block(r, b, sizeof(b));
+ if (n <= 0)
+ return list<string>();
+ return cons(string(b, n), read(r));
+}
+
+/**
+ * Convert a URI represented as a list to an absolute URL.
+ */
+const char* url(const list<value>& v, request_rec* r) {
+ const string u = string(r->uri) + path(v);
+ return ap_construct_url(r->pool, c_str(u), r);
+}
+
+/**
+ * Write an HTTP result.
+ */
+const failable<int> writeResult(const failable<list<string> >& ls, const string& ct, request_rec* r) {
+ if (!hasContent(ls))
+ return mkfailure<int>(reason(ls));
+ ostringstream os;
+ write(content(ls), os);
+ const string ob(str(os));
+ debug(ob, "httpd::result");
+
+ // Make sure browsers come back and check for updated dynamic content
+ apr_table_setn(r->headers_out, "Expires", "Tue, 01 Jan 1980 00:00:00 GMT");
+
+ // Compute and return an Etag for the returned content
+ const string etag(ap_md5(r->pool, (const unsigned char*)c_str(ob)));
+
+ // Check for an If-None-Match header and just return a 304 not-modified status
+ // if the Etag matches the Etag presented by the client, to save bandwith
+ const char* match = apr_table_get(r->headers_in, "If-None-Match");
+ apr_table_setn(r->headers_out, "ETag", apr_pstrdup(r->pool, c_str(etag)));
+ if (match != NULL && etag == match) {
+
+ r->status = HTTP_NOT_MODIFIED;
+ return OK;
+ }
+ ap_set_content_type(r, apr_pstrdup(r->pool, c_str(ct)));
+ ap_rputs(c_str(ob), r);
+ return OK;
+}
+
+/**
+ * Report request execution status.
+ */
+const int reportStatus(const failable<int>& rc) {
+ if (!hasContent(rc))
+ return HTTP_INTERNAL_SERVER_ERROR;
+ return content(rc);
+}
+
+/**
+ * Construct a redirect URI.
+ */
+const string redirectURI(const string& file, const string& pi) {
+ return file + pi;
+}
+
+const string redirectURI(const string& file, const string& pi, const string& args) {
+ return file + pi + "?" + args;
+}
+
+/**
+ * Convert a value to an HTTPD request struc
+ */
+request_rec* request(const value& v) {
+ return (request_rec*)(long)(double)v;
+}
+
+/**
+ * Convert an HTTPD request struct to a value
+ */
+const value requestValue(request_rec* r) {
+ return value((double)(long)r);
+}
+
+/**
+ * Update filters in an HTTPD redirect request.
+ * Similar to httpd/modules/http/http_request.c::update_r_in_filters.
+ */
+const bool redirectFilters(ap_filter_t* f, request_rec* from, request_rec* to) {
+ if (f == NULL)
+ return true;
+ if (f->r == from)
+ f->r = to;
+ return redirectFilters(f->next, from, to);
+}
+
+/**
+ * Create an HTTPD redirect request.
+ * Similar to httpd/modules/http/http_request.c::internal_internal_redirect.
+ */
+extern "C" {
+ AP_DECLARE(ap_conf_vector_t*) ap_create_request_config(apr_pool_t *p);
+}
+
+const failable<request_rec*, int> internalRedirectRequest(const string& nr_uri, request_rec* r) {
+ if (ap_is_recursion_limit_exceeded(r))
+ return mkfailure<request_rec*, int>(HTTP_INTERNAL_SERVER_ERROR);
+
+ // Create a new request
+ request_rec* nr = (request_rec*)apr_pcalloc(r->pool, sizeof(request_rec));
+ nr->connection = r->connection;
+ nr->server = r->server;
+ nr->pool = r->pool;
+ nr->method = r->method;
+ nr->method_number = r->method_number;
+ nr->allowed_methods = ap_make_method_list(nr->pool, 2);
+ ap_parse_uri(nr, apr_pstrdup(nr->pool, c_str(nr_uri)));
+ nr->request_config = ap_create_request_config(r->pool);
+ nr->per_dir_config = r->server->lookup_defaults;
+ nr->prev = r;
+ r->next = nr;
+
+ // Run create request hook
+ ap_run_create_request(nr);
+
+ // Inherit protocol info from the original request
+ nr->the_request = r->the_request;
+ nr->allowed = r->allowed;
+ nr->status = r->status;
+ nr->assbackwards = r->assbackwards;
+ nr->header_only = r->header_only;
+ nr->protocol = r->protocol;
+ nr->proto_num = r->proto_num;
+ nr->hostname = r->hostname;
+ nr->request_time = r->request_time;
+ nr->main = r->main;
+ nr->headers_in = r->headers_in;
+ nr->headers_out = apr_table_make(r->pool, 12);
+ nr->err_headers_out = r->err_headers_out;
+ nr->subprocess_env = r->subprocess_env;
+ nr->notes = apr_table_make(r->pool, 5);
+ nr->allowed_methods = ap_make_method_list(nr->pool, 2);
+ nr->htaccess = r->htaccess;
+ nr->no_cache = r->no_cache;
+ nr->expecting_100 = r->expecting_100;
+ nr->no_local_copy = r->no_local_copy;
+ nr->read_length = r->read_length;
+ nr->vlist_validator = r->vlist_validator;
+
+ // Setup input and output filters
+ nr->proto_output_filters = r->proto_output_filters;
+ nr->proto_input_filters = r->proto_input_filters;
+ nr->output_filters = nr->proto_output_filters;
+ nr->input_filters = nr->proto_input_filters;
+ if (nr->main)
+ ap_add_output_filter_handle(ap_subreq_core_filter_handle, NULL, nr, nr->connection);
+ redirectFilters(nr->input_filters, r, nr);
+ redirectFilters(nr->output_filters, r, nr);
+ const int rrc = ap_run_post_read_request(nr);
+ if (rrc != OK && rrc != DECLINED)
+ return mkfailure<request_rec*, int>(rrc);
+
+ return nr;
+}
+
+/**
+ * Process an HTTPD internal redirect request.
+ * Similar to httpd/modules/http/http_request.c::ap_internal_redirect.
+ */
+extern "C" {
+ AP_DECLARE(int) ap_invoke_handler(request_rec *r);
+}
+
+const int internalRedirect(request_rec* nr) {
+ int status = ap_run_quick_handler(nr, 0);
+ if (status == DECLINED) {
+ status = ap_process_request_internal(nr);
+ if (status == OK)
+ status = ap_invoke_handler(nr);
+ }
+ if (status != OK) {
+ nr->status = status;
+ return OK;
+ }
+ ap_finalize_request_protocol(nr);
+ return OK;
+}
+
+/**
+ * Create and process an HTTPD redirect request.
+ */
+const int internalRedirect(const string& uri, request_rec* r) {
+ const failable<request_rec*, int> nr = httpd::internalRedirectRequest(uri, r);
+ if (!hasContent(nr))
+ return reason(nr);
+ return httpd::internalRedirect(content(nr));
+}
+
+/**
+ * Put a value in the process user data.
+ */
+const bool putUserData(const string& k, const void* v, const server_rec* s) {
+ apr_pool_userdata_set((const void *)v, c_str(k), apr_pool_cleanup_null, s->process->pool);
+ return true;
+}
+
+/**
+ * Return a user data value.
+ */
+const void* userData(const string& k, const server_rec* s) {
+ void* v = NULL;
+ apr_pool_userdata_get(&v, c_str(k), s->process->pool);
+ return v;
+}
+
+}
+}
+
+#endif /* tuscany_httpd_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/Makefile.am b/sca-cpp/branches/gcc-4.4/modules/java/Makefile.am
new file mode 100644
index 0000000000..293b9431b5
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/Makefile.am
@@ -0,0 +1,64 @@
+# 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.
+
+JAVAROOT = $(top_builddir)/modules/java
+libdir = $(prefix)/modules/java
+
+if WANT_JAVA
+
+INCLUDES = -I${JAVA_INCLUDE}
+
+mod_SCRIPTS = java-conf
+moddir = $(prefix)/modules/java
+
+prefix_DATA = java.prefix
+prefixdir = $(prefix)/modules/java
+java.prefix: $(top_builddir)/config.status
+ echo ${JAVA_PREFIX} >java.prefix
+
+lib_LTLIBRARIES = libmod_tuscany_java.la
+libmod_tuscany_java_la_SOURCES = mod-java.cpp
+libmod_tuscany_java_la_LDFLAGS = -lxml2 -lcurl -lmozjs ${JAVA_LDFLAGS}
+noinst_DATA = libmod_tuscany_java.so
+libmod_tuscany_java.so:
+ ln -s .libs/libmod_tuscany_java.so libmod_tuscany_java.so
+
+jni_test_SOURCES = jni-test.cpp
+jni_test_LDFLAGS = ${JAVA_LDFLAGS}
+
+java_test_SOURCES = java-test.cpp
+java_test_LDFLAGS = ${JAVA_LDFLAGS}
+
+java_shell_SOURCES = java-shell.cpp
+java_shell_LDFLAGS = ${JAVA_LDFLAGS}
+
+noinst_JAVA = org/apache/tuscany/*.java test/*.java
+jardir = ${prefix}/modules/java
+jarfile = libmod-tuscany-java-${PACKAGE_VERSION}.jar
+jar_DATA = ${jarfile}
+${jarfile}: ${noinst_JAVA}
+ ${JAR} cf $@ org/apache/tuscany/*.class
+
+CLEANFILES = ${jarfile} org/apache/tuscany/*.class test/*.class
+
+client_test_SOURCES = client-test.cpp
+client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+
+noinst_PROGRAMS = jni-test java-test java-shell client-test
+TESTS = jni-test java-test server-test
+
+endif
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/client-test.cpp b/sca-cpp/branches/gcc-4.4/modules/java/client-test.cpp
new file mode 100644
index 0000000000..d06c57721e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/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 "../server/client-test.hpp"
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+ tuscany::server::testURI = "http://localhost:8090/java";
+
+ tuscany::server::testServer();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/domain-test.composite b/sca-cpp/branches/gcc-4.4/modules/java/domain-test.composite
new file mode 100644
index 0000000000..190f2ff5bb
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/domain-test.composite
@@ -0,0 +1,42 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://domain/test"
+ name="domain-test">
+
+ <component name="java-test">
+ <implementation.java class="test.ServerImpl"/>
+ <service name="test">
+ <t:binding.http uri="java"/>
+ </service>
+ </component>
+
+ <component name="client-test">
+ <implementation.java class="test.ClientImpl"/>
+ <service name="client">
+ <t:binding.http uri="client"/>
+ </service>
+ <reference name="ref" target="java-test">
+ <t:binding.http/>
+ </reference>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/driver.hpp b/sca-cpp/branches/gcc-4.4/modules/java/driver.hpp
new file mode 100644
index 0000000000..ddfc057940
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/driver.hpp
@@ -0,0 +1,61 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_java_driver_hpp
+#define tuscany_java_driver_hpp
+
+/**
+ * Java evaluator main driver loop.
+ */
+
+#include "string.hpp"
+#include "stream.hpp"
+#include "monad.hpp"
+#include "../scheme/driver.hpp"
+#include "eval.hpp"
+
+namespace tuscany {
+namespace java {
+
+const value evalDriverLoop(const JavaRuntime& jr, const JavaClass jc, istream& in, ostream& out) {
+ scheme::promptForInput(scheme::evalInputPrompt, out);
+ value input = scheme::readValue(in);
+ if (isNil(input))
+ return input;
+ const failable<value> output = evalClass(jr, input, jc);
+ scheme::announceOutput(scheme::evalOutputPrompt, out);
+ scheme::userPrint(content(output), out);
+ return evalDriverLoop(jr, jc, in, out);
+}
+
+const bool evalDriverRun(const char* name, istream& in, ostream& out) {
+ scheme::setupDisplay(out);
+ JavaRuntime javaRuntime;
+ const failable<JavaClass> jc = readClass(javaRuntime, ".", name);
+ if (!hasContent(jc))
+ return true;
+ evalDriverLoop(javaRuntime, content(jc), in, out);
+ return true;
+}
+
+}
+}
+#endif /* tuscany_java_driver_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/eval.hpp b/sca-cpp/branches/gcc-4.4/modules/java/eval.hpp
new file mode 100644
index 0000000000..a1cf6ae576
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/eval.hpp
@@ -0,0 +1,567 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_java_eval_hpp
+#define tuscany_java_eval_hpp
+
+/**
+ * Java component implementation evaluation logic.
+ */
+#include <jni.h>
+#include <apr_uuid.h>
+
+#include "list.hpp"
+#include "value.hpp"
+
+namespace tuscany {
+namespace java {
+
+/**
+ * Handle differences between various JNI APIs.
+ */
+#ifdef JAVA_HARMONY_VM
+#define JNI_VERSION JNI_VERSION_1_4
+#else
+#define JNI_VERSION JNI_VERSION_1_6
+#endif
+
+/**
+ * Represent a Java VM runtime.
+ */
+jobject JNICALL nativeInvoke(JNIEnv *env, jobject self, jobject proxy, jobject method, jobjectArray args);
+jobject JNICALL nativeUUID(JNIEnv *env);
+
+class JavaRuntime {
+public:
+ JavaRuntime() {
+
+ // Get existing JVM
+ jsize nvms = 0;
+ JNI_GetCreatedJavaVMs(&jvm, 1, &nvms);
+ if (nvms == 0) {
+
+ // Create a new JVM
+ JavaVMInitArgs args;
+ args.version = JNI_VERSION;
+ args.ignoreUnrecognized = JNI_FALSE;
+ JavaVMOption options[3];
+ args.options = options;
+ args.nOptions = 0;
+
+ // Configure classpath
+ const char* envcp = getenv("CLASSPATH");
+ const string cp = string("-Djava.class.path=") + (envcp == NULL? "." : envcp);
+ options[args.nOptions].optionString = const_cast<char*>(c_str(cp));
+ options[args.nOptions++].extraInfo = NULL;
+
+#ifdef WANT_MAINTAINER_MODE
+ // Enable assertions
+ options[args.nOptions++].optionString = const_cast<char*>("-ea");
+#endif
+
+ // Configure Java debugging
+ const char* jpdaopts = getenv("JPDA_OPTS");
+ if (jpdaopts != NULL) {
+ options[args.nOptions].optionString = const_cast<char*>(jpdaopts);
+ options[args.nOptions++].extraInfo = NULL;
+ } else {
+ const char* jpdaaddr = getenv("JPDA_ADDRESS");
+ if (jpdaaddr != NULL) {
+ const string jpda = string("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=") + jpdaaddr;
+ options[args.nOptions].optionString = const_cast<char*>(c_str(jpda));
+ options[args.nOptions++].extraInfo = NULL;
+ }
+ }
+
+ // Create the JVM
+#ifdef JAVA_HARMONY_VM
+ JNI_CreateJavaVM(&jvm, &env, &args);
+#else
+ JNI_CreateJavaVM(&jvm, (void**)&env, &args);
+#endif
+
+ } else {
+
+ // Just point to existing JVM
+ jvm->GetEnv((void**)&env, JNI_VERSION);
+ }
+
+ // Lookup System classes and methods
+ classClass = env->FindClass("java/lang/Class");
+ methodClass = env->FindClass("java/lang/reflect/Method");
+ objectClass = env->FindClass("java/lang/Object");
+ doubleClass = env->FindClass("java/lang/Double");
+ booleanClass = env->FindClass("java/lang/Boolean");
+ stringClass = env->FindClass("java/lang/String");
+ objectArrayClass = env->FindClass("[Ljava/lang/Object;");
+ iterableClass = env->FindClass("java/lang/Iterable");
+ classForName = env->GetStaticMethodID(classClass, "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;");
+ doubleValueOf = env->GetStaticMethodID(doubleClass, "valueOf", "(D)Ljava/lang/Double;");
+ doubleValue = env->GetMethodID(doubleClass, "doubleValue", "()D");
+ booleanValueOf = env->GetStaticMethodID(booleanClass, "valueOf", "(Z)Ljava/lang/Boolean;");
+ booleanValue = env->GetMethodID(booleanClass, "booleanValue", "()Z");
+ declaredMethods = env->GetMethodID(classClass, "getDeclaredMethods", "()[Ljava/lang/reflect/Method;");
+ methodName = env->GetMethodID(methodClass, "getName", "()Ljava/lang/String;");
+ parameterTypes = env->GetMethodID(methodClass, "getParameterTypes", "()[Ljava/lang/Class;");
+
+ // Lookup Tuscany classes and methods
+ loaderClass = env->FindClass("org/apache/tuscany/ClassLoader");
+ loaderValueOf = env->GetStaticMethodID(loaderClass, "valueOf", "(Ljava/lang/String;)Ljava/lang/ClassLoader;");
+ loaderForName = env->GetStaticMethodID(loaderClass, "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;");
+ invokerClass = env->FindClass("org/apache/tuscany/InvocationHandler");
+ invokerValueOf = env->GetStaticMethodID(invokerClass, "valueOf", "(Ljava/lang/Class;J)Ljava/lang/Object;");
+ invokerStackTrace = env->GetStaticMethodID(invokerClass, "stackTrace", "(Ljava/lang/Throwable;)Ljava/lang/String;");
+ invokerLambda = env->GetFieldID(invokerClass, "lambda", "J");
+ iterableUtilClass = env->FindClass("org/apache/tuscany/IterableUtil");
+ iterableValueOf = env->GetStaticMethodID(iterableUtilClass, "list", "([Ljava/lang/Object;)Ljava/lang/Iterable;");
+ iterableIsNil = env->GetStaticMethodID(iterableUtilClass, "isNil", "(Ljava/lang/Object;)Z");
+ iterableCar = env->GetStaticMethodID(iterableUtilClass, "car", "(Ljava/lang/Object;)Ljava/lang/Object;");
+ iterableCdr = env->GetStaticMethodID(iterableUtilClass, "cdr", "(Ljava/lang/Object;)Ljava/lang/Iterable;");
+ uuidClass = env->FindClass("org/apache/tuscany/UUIDUtil");
+
+ // Register our native invocation handler function
+ JNINativeMethod invokenm;
+ invokenm.name = const_cast<char*>("invoke");
+ invokenm.signature = const_cast<char*>("(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
+ invokenm.fnPtr = (void*)nativeInvoke;
+ env->RegisterNatives(invokerClass, &invokenm, 1);
+
+ // Register our native UUID function
+ JNINativeMethod uuidnm;
+ uuidnm.name = const_cast<char*>("uuid");
+ uuidnm.signature = const_cast<char*>("()Ljava/lang/String;");
+ uuidnm.fnPtr = (void*)nativeUUID;
+ env->RegisterNatives(uuidClass, &uuidnm, 1);
+ }
+
+ JavaVM* jvm;
+ JNIEnv* env;
+
+ jclass classClass;
+ jclass methodClass;
+ jclass objectClass;
+ jclass doubleClass;
+ jclass booleanClass;
+ jclass stringClass;
+ jclass objectArrayClass;
+ jclass iterableClass;
+ jmethodID doubleValueOf;
+ jmethodID doubleValue;
+ jmethodID booleanValueOf;
+ jmethodID booleanValue;
+ jmethodID declaredMethods;
+ jmethodID methodName;
+ jmethodID parameterTypes;
+ jmethodID classForName;
+ jclass loaderClass;
+ jmethodID loaderValueOf;
+ jmethodID loaderForName;
+ jclass invokerClass;
+ jmethodID invokerValueOf;
+ jmethodID invokerStackTrace;
+ jfieldID invokerLambda;
+ jclass iterableUtilClass;
+ jmethodID iterableValueOf;
+ jmethodID iterableCar;
+ jmethodID iterableCdr;
+ jmethodID iterableIsNil;
+ jclass uuidClass;
+};
+
+/**
+ * Return the last exception that occurred in a JVM.
+ */
+string lastException(const JavaRuntime& jr) {
+ if (!jr.env->ExceptionCheck())
+ return "No Exception";
+ const jthrowable ex = jr.env->ExceptionOccurred();
+ const jstring trace = (jstring)jr.env->CallStaticObjectMethod(jr.invokerClass, jr.invokerStackTrace, ex);
+ const char* c = jr.env->GetStringUTFChars(trace, NULL);
+ const string msg(c);
+ jr.env->ReleaseStringUTFChars(trace, c);
+ jr.env->ExceptionClear();
+ return msg;
+}
+
+/**
+ * Declare conversion functions.
+ */
+const jobject valueToJobject(const JavaRuntime& jr, const value& jtype, const value& v);
+const value jobjectToValue(const JavaRuntime& jr, const jobject o);
+const jobjectArray valuesToJarray(const JavaRuntime& jr, const list<value>& v);
+const list<value> jarrayToValues(const JavaRuntime& jr, const jobjectArray o);
+const list<value> jiterableToValues(const JavaRuntime& jr, const jobject o);
+
+/**
+ * Convert a Java class name to a JNI class name.
+ */
+const bool jniClassNameHelper(char* to, const char* from) {
+ if (*from == '\0') {
+ *to = '\0';
+ return true;
+ }
+ *to = *from == '.'? '/' : *from;
+ return jniClassNameHelper(to + 1, from + 1);
+}
+
+const string jniClassName(const string& from) {
+ char buf[length(from) + 1];
+ jniClassNameHelper(buf, c_str(from));
+ return string(buf);
+}
+
+/**
+ * Create a new Java object representing a lambda expression.
+ */
+class javaLambda {
+public:
+ javaLambda(const JavaRuntime& jr, const value& iface, const lambda<value(const list<value>&)>& func) : jr(jr), iface(iface), func(func) {
+ }
+
+ const value operator()(const list<value>& expr) const {
+ if (isNil(expr))
+ return func(expr);
+ const value& op(car(expr));
+ if (op == "equals")
+ return value(cadr(expr) == this);
+ if (op == "hashCode")
+ return value((double)(long)this);
+ if (op == "toString") {
+ ostringstream os;
+ os << this;
+ return value(string("org.apache.tuscany.InvocationHandler@") + (c_str(str(os)) + 2));
+ }
+ return func(expr);
+ }
+
+ const JavaRuntime& jr;
+ const value iface;
+ const lambda<value(const list<value>&)> func;
+};
+
+/**
+ * Native implementation of the InvocationHandler.invoke Java method.
+ * Dispatches the call to the lambda function wrapped in the invocation handler.
+ */
+jobject JNICALL nativeInvoke(JNIEnv* env, jobject self, unused jobject proxy, jobject method, jobjectArray args) {
+
+ // Retrieve the lambda function from the invocation handler
+ jclass clazz = env->GetObjectClass(self);
+ jfieldID f = env->GetFieldID(clazz, "lambda", "J");
+ const javaLambda& jl = *(javaLambda*)(long)env->GetLongField(self, f);
+
+ // Retrieve the function name
+ const jstring s = (jstring)env->CallObjectMethod(method, jl.jr.methodName);
+ const char* c = env->GetStringUTFChars(s, NULL);
+ const value func(c);
+ env->ReleaseStringUTFChars(s, c);
+
+ // Build the expression to evaluate, either (func, args[0], args[1], args[2]...)
+ // or just args[0] for the special eval(...) function
+ const list<value> expr = func == "eval"? (list<value>)car<value>(jarrayToValues(jl.jr, args)) : cons<value>(func, jarrayToValues(jl.jr, args));
+ debug(expr, "java::nativeInvoke::expr");
+
+ // Invoke the lambda function
+ value result = jl(expr);
+ debug(result, "java::nativeInvoke::result");
+
+ // Convert result to a jobject
+ return valueToJobject(jl.jr, value(), result);
+}
+
+/**
+ * Native implementation of IterableUtil.uuid. We are providing a native implementation
+ * of this function as java.util.UUID seems to behave differently with different JDKs.
+ */
+jobject JNICALL nativeUUID(JNIEnv* env) {
+ apr_uuid_t uuid;
+ apr_uuid_get(&uuid);
+ char buf[APR_UUID_FORMATTED_LENGTH];
+ apr_uuid_format(buf, &uuid);
+ string s(buf, APR_UUID_FORMATTED_LENGTH);
+ return env->NewStringUTF(c_str(s));
+}
+
+/**
+ * Convert a lambda function to Java proxy.
+ */
+const jobject mkJavaLambda(const JavaRuntime& jr, unused const value& iface, const lambda<value(const list<value>&)>& l) {
+ const gc_ptr<javaLambda> jl = new (gc_new<javaLambda>()) javaLambda(jr, iface, l);
+ jclass jc = (jclass)(long)(double)iface;
+ const jobject obj = jr.env->CallStaticObjectMethod(jr.invokerClass, jr.invokerValueOf, jc, (long)(javaLambda*)jl);
+ return obj;
+}
+
+/**
+ * Convert a list of values to a Java jobjectArray.
+ */
+const jobjectArray valuesToJarrayHelper(const JavaRuntime& jr, jobjectArray a, const list<value>& v, const int i) {
+ if (isNil(v))
+ return a;
+ jr.env->SetObjectArrayElement(a, i, valueToJobject(jr, value(), car(v)));
+ return valuesToJarrayHelper(jr, a, cdr(v), i + 1);
+}
+
+const jobjectArray valuesToJarray(const JavaRuntime& jr, const list<value>& v) {
+ jobjectArray a = jr.env->NewObjectArray(length(v), jr.objectClass, NULL);
+ return valuesToJarrayHelper(jr, a, v, 0);
+}
+
+/**
+ * Convert a Java jobjectArray to a Java iterable.
+ */
+const jobject jarrayToJiterable(const JavaRuntime& jr, jobjectArray a) {
+ return jr.env->CallStaticObjectMethod(jr.iterableClass, jr.iterableValueOf, a);
+}
+
+/**
+ * Convert a value to a Java jobject.
+ */
+const jobject valueToJobject(const JavaRuntime& jr, const value& jtype, const value& v) {
+ switch (type(v)) {
+ case value::List:
+ return jarrayToJiterable(jr, valuesToJarray(jr, v));
+ case value::Lambda:
+ return mkJavaLambda(jr, jtype, v);
+ case value::Symbol:
+ return jr.env->NewStringUTF(c_str(string("'") + v));
+ case value::String:
+ return jr.env->NewStringUTF(c_str(v));
+ case value::Number:
+ return jr.env->CallStaticObjectMethod(jr.doubleClass, jr.doubleValueOf, (double)v);
+ case value::Bool:
+ return jr.env->CallStaticObjectMethod(jr.booleanClass, jr.booleanValueOf, (bool)v);
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Convert a list of values to an array of jvalues.
+ */
+const jvalue* valuesToJvaluesHelper(const JavaRuntime& jr, jvalue* a, const list<value>& types, const list<value>& v) {
+ if (isNil(v))
+ return a;
+ a->l = valueToJobject(jr, car(types), car(v));
+ return valuesToJvaluesHelper(jr, a + 1, cdr(types), cdr(v));
+}
+
+const jvalue* valuesToJvalues(const JavaRuntime& jr, const list<value>& types, const list<value>& v) {
+ const int n = length(v);
+ jvalue* a = new (gc_anew<jvalue>(n)) jvalue[n];
+ valuesToJvaluesHelper(jr, a, types, v);
+ return a;
+}
+
+/**
+ * Convert a Java jobjectArray to a list of values.
+ */
+const list<value> jarrayToValuesHelper(const JavaRuntime& jr, jobjectArray a, const int i, const int size) {
+ if (i == size)
+ return list<value>();
+ return cons(jobjectToValue(jr, jr.env->GetObjectArrayElement(a, i)), jarrayToValuesHelper(jr, a, i + 1, size));
+}
+
+const list<value> jarrayToValues(const JavaRuntime& jr, jobjectArray o) {
+ if (o == NULL)
+ return list<value>();
+ return jarrayToValuesHelper(jr, o, 0, jr.env->GetArrayLength(o));
+}
+
+/**
+ * Convert a Java Iterable to a list of values.
+ */
+const list<value> jiterableToValuesHelper(const JavaRuntime& jr, jobject o) {
+ if ((bool)jr.env->CallStaticBooleanMethod(jr.iterableUtilClass, jr.iterableIsNil, o))
+ return list<value>();
+ jobject car = jr.env->CallStaticObjectMethod(jr.iterableUtilClass, jr.iterableCar, o);
+ jobject cdr = jr.env->CallStaticObjectMethod(jr.iterableUtilClass, jr.iterableCdr, o);
+ return cons(jobjectToValue(jr, car), jiterableToValuesHelper(jr, cdr));
+}
+
+const list<value> jiterableToValues(const JavaRuntime& jr, jobject o) {
+ if (o == NULL)
+ return list<value>();
+ return jiterableToValuesHelper(jr, o);
+}
+
+/**
+ * Lambda function used to represent a Java callable object.
+ */
+struct javaCallable {
+ const JavaRuntime& jr;
+ const jobject obj;
+
+ javaCallable(const JavaRuntime& jr, const jobject obj) : jr(jr), obj(obj) {
+ }
+
+ const value operator()(const list<value>& args) const {
+ jobjectArray jargs = valuesToJarray(jr, args);
+ jobject result = jargs; //CallObject(func, jargs);
+ return jobjectToValue(jr, result);
+ }
+};
+
+/**
+ * Convert a Java jobject to a value.
+ */
+const value jobjectToValue(const JavaRuntime& jr, const jobject o) {
+ if (o == NULL)
+ return value();
+ const jclass clazz = jr.env->GetObjectClass(o);
+ if ((jr.env->IsSameObject(clazz, jr.stringClass))) {
+ const char* s = jr.env->GetStringUTFChars((jstring)o, NULL);
+ if (*s == '\'') {
+ const value v(s + 1);
+ jr.env->ReleaseStringUTFChars((jstring)o, s);
+ return v;
+ }
+ const value v = string(s);
+ jr.env->ReleaseStringUTFChars((jstring)o, s);
+ return v;
+ }
+ if (jr.env->IsSameObject(clazz, jr.booleanClass))
+ return value((bool)jr.env->CallBooleanMethod(o, jr.booleanValue));
+ if (jr.env->IsSameObject(clazz, jr.doubleClass))
+ return value((double)jr.env->CallDoubleMethod(o, jr.doubleValue));
+ if (jr.env->IsAssignableFrom(clazz, jr.iterableClass))
+ return jiterableToValues(jr, o);
+ if (jr.env->IsAssignableFrom(clazz, jr.objectArrayClass))
+ return jarrayToValues(jr, (jobjectArray)o);
+ return lambda<value(const list<value>&)>(javaCallable(jr, o));
+}
+
+/**
+ * Returns a balanced tree of the methods of a class.
+ */
+const value parameterTypeToValue(const jobject t) {
+ return value((double)(long)t);
+}
+
+const list<value> parameterTypesToValues(const JavaRuntime& jr, const jobjectArray t, const int i) {
+ if (i == 0)
+ return list<value>();
+ return cons<value>(parameterTypeToValue(jr.env->GetObjectArrayElement(t, i - 1)), parameterTypesToValues(jr, t, i - 1));
+}
+
+const value methodToValue(const JavaRuntime& jr, const jobject m) {
+ const jobject s = jr.env->CallObjectMethod(m, jr.methodName);
+ const char* c = jr.env->GetStringUTFChars((jstring)s, NULL);
+ const string& name = string(c);
+ jr.env->ReleaseStringUTFChars((jstring)s, c);
+
+ const jmethodID mid = jr.env->FromReflectedMethod(m);
+
+ const jobjectArray t = (jobjectArray)jr.env->CallObjectMethod(m, jr.parameterTypes);
+ const list<value> types = reverse(parameterTypesToValues(jr, t, jr.env->GetArrayLength(t)));
+
+ return cons<value>(c_str(name), cons<value>((double)(long)mid, types));
+}
+
+const list<value> methodsToValues(const JavaRuntime& jr, const jobjectArray m, const int i) {
+ if (i == 0)
+ return list<value>();
+ return cons<value>(methodToValue(jr, jr.env->GetObjectArrayElement(m, i - 1)), methodsToValues(jr, m, i - 1));
+}
+
+const list<value> methodsToValues(const JavaRuntime& jr, const jclass clazz) {
+ const jobjectArray m = (jobjectArray)jr.env->CallObjectMethod(clazz, jr.declaredMethods);
+ return methodsToValues(jr, m, jr.env->GetArrayLength(m));
+}
+
+/**
+ * Represents a Java Class.
+ */
+class JavaClass {
+public:
+ JavaClass() : loader(NULL), clazz(NULL), obj(NULL) {
+ }
+ JavaClass(const jobject loader, const jclass clazz, const jobject obj, const list<value> m) : loader(loader), clazz(clazz), obj(obj), m(m) {
+ }
+
+ const jobject loader;
+ const jclass clazz;
+ const jobject obj;
+ const list<value> m;
+};
+
+/**
+ * Read a class.
+ */
+const failable<JavaClass> readClass(const JavaRuntime& jr, const string& path, const string& name) {
+
+ // Create a class loader from the given path
+ const jobject jpath = jr.env->NewStringUTF(c_str(path));
+ jobject loader = jr.env->CallStaticObjectMethod(jr.loaderClass, jr.loaderValueOf, jpath);
+
+ // Load the class
+ const jobject jname = jr.env->NewStringUTF(c_str(name));
+ const jclass clazz = (jclass)jr.env->CallStaticObjectMethod(jr.loaderClass, jr.loaderForName, jname, JNI_TRUE, loader);
+ if (clazz == NULL)
+ return mkfailure<JavaClass>(string("Couldn't load class: ") + name + " : " + lastException(jr));
+
+ // Create an instance
+ const jmethodID constr = jr.env->GetMethodID(clazz, "<init>", "()V");
+ if (constr == NULL)
+ return mkfailure<JavaClass>(string("Couldn't find constructor: ") + name + " : " + lastException(jr));
+ const jobject obj = jr.env->NewObject(clazz, constr);
+ if (obj == NULL)
+ return mkfailure<JavaClass>(string("Couldn't construct object: ") + name + " : " + lastException(jr));
+
+ return JavaClass(loader, clazz, obj, methodsToValues(jr, clazz));
+}
+
+/**
+ * Evaluate an expression against a Java class.
+ */
+const failable<value> evalClass(const JavaRuntime& jr, const value& expr, const JavaClass jc) {
+ debug(expr, "java::evalClass::expr");
+
+ // Lookup the Java function named as the expression operand
+ const list<value> func = assoc<value>(car<value>(expr), jc.m);
+ if (isNil(func)) {
+
+ // The start, stop, and restart functions are optional
+ const value fn = car<value>(expr);
+ if (fn == "start" || fn == "stop")
+ return value(lambda<value(const list<value>&)>());
+
+ return mkfailure<value>(string("Couldn't find function: ") + car<value>(expr) + " : " + lastException(jr));
+ }
+ const jmethodID fid = (jmethodID)(long)(double)cadr(func);
+
+ // Convert args to Java jvalues
+ const jvalue* args = valuesToJvalues(jr, cddr(func), cdr<value>(expr));
+
+ // Call the Java function
+ const jobject result = jr.env->CallObjectMethodA(jc.obj, fid, const_cast<jvalue*>(args));
+ if (result == NULL)
+ return mkfailure<value>(string("Function call failed: ") + car<value>(expr) + " : " + lastException(jr));
+
+ // Convert Java result to a value
+ const value v = jobjectToValue(jr, result);
+ debug(v, "java::evalClass::result");
+ return v;
+}
+
+}
+}
+#endif /* tuscany_java_eval_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/java-conf b/sca-cpp/branches/gcc-4.4/modules/java/java-conf
new file mode 100755
index 0000000000..4c03035ca4
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/java-conf
@@ -0,0 +1,29 @@
+#!/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.
+
+# Generate a Java server conf
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+
+cat >>$root/conf/httpd.conf <<EOF
+# Support for Java SCA components
+LoadModule mod_tuscany_eval $here/libmod_tuscany_java.so
+
+EOF
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/java-shell.cpp b/sca-cpp/branches/gcc-4.4/modules/java/java-shell.cpp
new file mode 100644
index 0000000000..51df513990
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/java-shell.cpp
@@ -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.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Java evaluator shell, used for interactive testing of Java classes.
+ */
+
+#include <assert.h>
+#include "gc.hpp"
+#include "stream.hpp"
+#include "string.hpp"
+#include "driver.hpp"
+
+int main(const int argc, char** argv) {
+ tuscany::gc_scoped_pool pool;
+ if (argc != 2) {
+ tuscany::cerr << "Usage: java-shell <class name>" << tuscany::endl;
+ return 1;
+ }
+ tuscany::java::evalDriverRun(argv[1], tuscany::cin, tuscany::cout);
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/java-test.cpp b/sca-cpp/branches/gcc-4.4/modules/java/java-test.cpp
new file mode 100644
index 0000000000..f811a4f58d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/java-test.cpp
@@ -0,0 +1,138 @@
+/*
+ * 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 Java evaluator.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "driver.hpp"
+
+namespace tuscany {
+namespace java {
+
+bool testEvalExpr() {
+ gc_scoped_pool pool;
+ JavaRuntime javaRuntime;
+ {
+ const failable<JavaClass> obj = readClass(javaRuntime, ".", "test.CalcImpl");
+ assert(hasContent(obj));
+ const value exp = mklist<value>("mult", 2, 3);
+ const failable<value> r = evalClass(javaRuntime, exp, content(obj));
+ assert(hasContent(r));
+ assert(content(r) == value(6));
+ }
+ {
+ const failable<JavaClass> obj = readClass(javaRuntime, ".", "test.CalcImpl");
+ assert(hasContent(obj));
+ const value exp = mklist<value>("even", 2);
+ const failable<value> r = evalClass(javaRuntime, exp, content(obj));
+ assert(hasContent(r));
+ assert(content(r) == value(true));
+ }
+ {
+ const failable<JavaClass> obj = readClass(javaRuntime, ".", "test.AdderImpl");
+ assert(hasContent(obj));
+ const value exp = mklist<value>("add", 2, 3);
+ const failable<value> r = evalClass(javaRuntime, exp, content(obj));
+ assert(hasContent(r));
+ assert(content(r) == value(5));
+ }
+ {
+ const failable<JavaClass> obj = readClass(javaRuntime, ".", "test.CalcImpl");
+ assert(hasContent(obj));
+ const value exp = mklist<value>("square", mklist<value>(1, 2, 3));
+ const failable<value> r = evalClass(javaRuntime, exp, content(obj));
+ assert(hasContent(r));
+ assert(content(r) == mklist<value>(1, 4, 9));
+ }
+ return true;
+}
+
+const value add(const list<value>& args) {
+ assert(car(args) == "add");
+ const double x = cadr(args);
+ const double y = caddr(args);
+ return x + y;
+}
+
+bool testEvalLambda() {
+ gc_scoped_pool pool;
+ JavaRuntime javaRuntime;
+ {
+ const failable<JavaClass> obj = readClass(javaRuntime, ".", "test.CalcImpl");
+ assert(hasContent(obj));
+ const value tcel = mklist<value>("add", 3, 4, lambda<value(const list<value>&)>(add));
+ const failable<value> r = evalClass(javaRuntime, tcel, content(obj));
+ assert(hasContent(r));
+ assert(content(r) == value(7));
+ }
+ {
+ const failable<JavaClass> obj = readClass(javaRuntime, ".", "test.CalcImpl");
+ assert(hasContent(obj));
+ const value tcel = mklist<value>("addEval", 3, 4, lambda<value(const list<value>&)>(add));
+ const failable<value> r = evalClass(javaRuntime, tcel, content(obj));
+ assert(hasContent(r));
+ assert(content(r) == value(7));
+ }
+ return true;
+}
+
+bool testClassLoader() {
+ gc_scoped_pool pool;
+ JavaRuntime javaRuntime;
+ const failable<JavaClass> obj = readClass(javaRuntime, ".", "org.apache.tuscany.ClassLoader$Test");
+ assert(hasContent(obj));
+ const value exp = mklist<value>("testClassLoader");
+ const failable<value> r = evalClass(javaRuntime, exp, content(obj));
+ assert(hasContent(r));
+ assert(content(r) == value(true));
+ return true;
+}
+
+bool testIterableUtil() {
+ gc_scoped_pool pool;
+ JavaRuntime javaRuntime;
+ const failable<JavaClass> obj = readClass(javaRuntime, ".", "org.apache.tuscany.IterableUtil$Test");
+ assert(hasContent(obj));
+ const value exp = mklist<value>("testList");
+ const failable<value> r = evalClass(javaRuntime, exp, content(obj));
+ assert(hasContent(r));
+ assert(content(r) == value(true));
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::java::testEvalExpr();
+ tuscany::java::testEvalLambda();
+ tuscany::java::testClassLoader();
+ tuscany::java::testIterableUtil();
+
+ tuscany::cout << "OK" << tuscany::endl;
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/jni-test.cpp b/sca-cpp/branches/gcc-4.4/modules/java/jni-test.cpp
new file mode 100644
index 0000000000..727af13dc6
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/jni-test.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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$ */
+
+/**
+ * Basic JNI test.
+ */
+
+#include <assert.h>
+#include <jni.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "fstream.hpp"
+#include "eval.hpp"
+
+namespace tuscany {
+namespace java {
+
+#ifdef JAVA_HARMONY_VM
+#define JNI_VERSION JNI_VERSION_1_4
+#else
+#define JNI_VERSION JNI_VERSION_1_6
+#endif
+
+bool testJNI() {
+ gc_scoped_pool pool;
+ JavaVM* jvm;
+ JNIEnv* env;
+
+ JavaVMInitArgs args;
+ args.version = JNI_VERSION;
+ args.ignoreUnrecognized = JNI_FALSE;
+ JavaVMOption options[3];
+ args.options = options;
+ args.nOptions = 0;
+ const char* envcp = getenv("CLASSPATH");
+ const string cp = string("-Djava.class.path=") + (envcp == NULL? "." : envcp);
+ options[args.nOptions].optionString = const_cast<char*>(c_str(cp));
+ options[args.nOptions++].extraInfo = NULL;
+#ifdef JAVA_HARMONY_VM
+ JNI_CreateJavaVM(&jvm, &env, &args);
+#else
+ JNI_CreateJavaVM(&jvm, (void**)&env, &args);
+#endif
+
+ jclass classClass = env->FindClass("java/lang/Class");
+ assert(classClass != NULL);
+ jclass loaderClass = env->FindClass("org/apache/tuscany/ClassLoader");
+ assert(loaderClass != NULL);
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::java::testJNI();
+
+ tuscany::cout << "OK" << tuscany::endl;
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/mod-java.cpp b/sca-cpp/branches/gcc-4.4/modules/java/mod-java.cpp
new file mode 100644
index 0000000000..510f9574b0
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/mod-java.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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$ */
+
+/**
+ * HTTPD module used to eval Java component implementations.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "../server/mod-cpp.hpp"
+#include "../server/mod-eval.hpp"
+#include "mod-java.hpp"
+
+namespace tuscany {
+namespace server {
+namespace modeval {
+
+/**
+ * Apply a lifecycle start or restart event.
+ */
+struct javaLifecycle {
+ javaLifecycle(java::JavaRuntime& jr) : jr(jr) {
+ }
+ const value operator()(const list<value>& params) const {
+ const value func = car(params);
+ if (func == "javaRuntime")
+ return (gc_ptr<value>)(value*)(void*)&jr;
+ return lambda<value(const list<value>&)>();
+ }
+ java::JavaRuntime& jr;
+};
+
+const value applyLifecycle(unused const list<value>& params) {
+
+ // Create a Java runtime
+ java::JavaRuntime& jr = *(new (gc_new<java::JavaRuntime>()) java::JavaRuntime());
+
+ // Return the function to invoke on subsequent events
+ return failable<value>(lambda<value(const list<value>&)>(javaLifecycle(jr)));
+}
+
+/**
+ * Evaluate a Java component implementation and convert it to an applicable
+ * lambda function.
+ */
+const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, const lambda<value(const list<value>&)>& lifecycle) {
+ const string itype(elementName(impl));
+ if (contains(itype, ".java")) {
+ const void* p = (gc_ptr<value>)lifecycle(mklist<value>("javaRuntime"));
+ return modjava::evalImplementation(path, impl, px, *(java::JavaRuntime*)p);
+ }
+ if (contains(itype, ".cpp"))
+ return modcpp::evalImplementation(path, impl, px);
+ return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype);
+}
+
+}
+}
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/mod-java.hpp b/sca-cpp/branches/gcc-4.4/modules/java/mod-java.hpp
new file mode 100644
index 0000000000..e7da06e930
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/mod-java.hpp
@@ -0,0 +1,77 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_modjava_hpp
+#define tuscany_modjava_hpp
+
+/**
+ * Evaluation functions used by mod-eval to evaluate Java
+ * component implementations.
+ */
+
+#include "string.hpp"
+#include "stream.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "eval.hpp"
+
+namespace tuscany {
+namespace server {
+namespace modjava {
+
+/**
+ * Apply a Java component implementation function.
+ */
+struct applyImplementation {
+ java::JavaClass impl;
+ const list<value> px;
+ java::JavaRuntime& jr;
+ applyImplementation(const java::JavaClass& impl, const list<value>& px, java::JavaRuntime& jr) : impl(impl), px(px), jr(jr) {
+ }
+ const value operator()(const list<value>& params) const {
+ const value expr = append<value>(params, px);
+ debug(expr, "modeval::java::applyImplementation::input");
+ const failable<value> res = java::evalClass(jr, expr, impl);
+ const value val = !hasContent(res)? mklist<value>(value(), reason(res)) : mklist<value>(content(res));
+ debug(val, "modeval::java::applyImplementation::result");
+ return val;
+ }
+};
+
+/**
+ * Evaluate a Java component implementation and convert it to an applicable
+ * lambda function.
+ */
+const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, java::JavaRuntime& jr) {
+ const string cn(attributeValue("class", impl));
+ const failable<java::JavaClass> jc = java::readClass(jr, path, cn);
+ if (!hasContent(jc))
+ return mkfailure<lambda<value(const list<value>&)> >(reason(jc));
+ return lambda<value(const list<value>&)>(applyImplementation(content(jc), px, jr));
+}
+
+}
+}
+}
+
+#endif /* tuscany_modjava_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/ClassLoader.java b/sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/ClassLoader.java
new file mode 100644
index 0000000000..ef7b2316fb
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/ClassLoader.java
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+package org.apache.tuscany;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+/**
+ * Class loader used to load SCA component implementation classes.
+ */
+class ClassLoader extends URLClassLoader {
+
+ ClassLoader(final URL... urls) {
+ super(urls);
+ }
+
+ /**
+ * Create a class loader for an SCA contribution path.
+ */
+ static java.lang.ClassLoader valueOf(final String path) throws MalformedURLException {
+ return new ClassLoader(new File(path).toURI().toURL());
+ }
+
+ /**
+ * Load a class.
+ */
+ static Class<?> forName(final String name, final boolean resolve, final java.lang.ClassLoader loader) throws ClassNotFoundException {
+ return Class.forName(name, resolve, loader);
+ }
+
+ /**
+ * Test the class loader.
+ */
+ static class Test {
+ Boolean testClassLoader() {
+ try {
+ final Class<?> clazz = ClassLoader.forName("test.CalcImpl", true, ClassLoader.valueOf("."));
+ assert clazz != null;
+ } catch(final MalformedURLException e) {
+ throw new RuntimeException(e);
+ } catch(final ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ return true;
+ }
+ }
+
+ public static void main(final String[] args) {
+ System.out.println("Testing...");
+
+ Test.class.getClassLoader().setDefaultAssertionStatus(true);
+ new Test().testClassLoader();
+
+ System.out.println("OK");
+ }
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/InvocationHandler.java b/sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/InvocationHandler.java
new file mode 100644
index 0000000000..06466fe9fc
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/InvocationHandler.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+package org.apache.tuscany;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * Proxy Invocation handler used to represent SCA component references.
+ */
+class InvocationHandler implements java.lang.reflect.InvocationHandler {
+ final long lambda;
+
+ InvocationHandler(final long lambda) {
+ this.lambda = lambda;
+ }
+
+ /**
+ * Create a proxy for an interface and the lambda function representing
+ * an SCA component reference.
+ */
+ static Object valueOf(final Class<?> iface, final long lambda) {
+ return Proxy.newProxyInstance(iface.getClassLoader(), new Class[]{iface}, new InvocationHandler(lambda));
+ }
+
+ /**
+ * Proxy invocation of a C++ function.
+ */
+ public native Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable;
+
+ /**
+ * Return the stack trace of an exception.
+ */
+ static String stackTrace(final Throwable e) {
+ final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw);
+ e.printStackTrace(pw);
+ return sw.toString();
+ }
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/IterableUtil.java b/sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/IterableUtil.java
new file mode 100644
index 0000000000..6d559f370a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/IterableUtil.java
@@ -0,0 +1,368 @@
+/*
+ * 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.
+ */
+
+package org.apache.tuscany;
+
+import static java.util.Arrays.*;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Utility functions to help work efficiently with iterable lists, inspired from Lisp.
+ */
+public class IterableUtil {
+
+ /**
+ * Convert an array or a variable list of arguments to an iterable list.
+ */
+ public static <T> Iterable<T> list(final Object... a) {
+ return new ArrayIterable<T>(a, 0);
+ }
+
+ /**
+ * Convert an iterable list to a java.util.Collection.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Collection<T> collection(final Object l) {
+ final Collection<T> c = new ArrayList<T>();
+ for(final Object x : (Iterable<?>)l)
+ c.add((T)x);
+ return c;
+ }
+
+ /**
+ * Construct a new list from an element and a list.
+ */
+ public static <T> Iterable<T> cons(final Object car, final Iterable<?> cdr) {
+ return new PairIterable<T>(car, cdr);
+ }
+
+ /**
+ * Return true if a list is nil (empty).
+ */
+ public static boolean isNil(final Object l) {
+ if(l instanceof BasicIterable<?>)
+ return ((BasicIterable<?>)l).isNil();
+ if(l instanceof Collection<?>)
+ return ((Collection<?>)l).isEmpty();
+ return !((Iterable<?>)l).iterator().hasNext();
+ }
+
+ /**
+ * Return the car (first element) of a list.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T car(final Object l) {
+ if(l instanceof BasicIterable<?>)
+ return ((BasicIterable<T>)l).car();
+ if(l instanceof List<?>)
+ return (T)((List<?>)l).get(0);
+ return (T)((Iterable<?>)l).iterator().next();
+ }
+
+ /**
+ * Return the cdr (rest after the first element) of a list.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Iterable<T> cdr(final Object l) {
+ if(l instanceof BasicIterable<?>)
+ return ((BasicIterable<T>)l).cdr();
+ if(l instanceof List<?>)
+ return new ListIterable<T>((List<?>)l, 1);
+ if(l instanceof Collection<?>)
+ return new ArrayIterable<T>(((Collection<?>)l).toArray(), 1);
+ return new Iterable<T>() {
+ public Iterator<T> iterator() {
+ final Iterator<T> i = ((Iterable<T>)l).iterator();
+ i.next();
+ return i;
+ }
+ };
+ }
+
+ /**
+ * Return the car of the cdr of a list.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T cadr(final Object l) {
+ return (T)car(cdr(l));
+ }
+
+ /**
+ * Return the cdr of the cdr of a list.
+ */
+ public static <T> Iterable<T> cddr(final Object l) {
+ return cdr(cdr(l));
+ }
+
+ /**
+ * Return the car of the cdr of the cdr of a list.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T caddr(final Object l) {
+ return (T)car(cddr(l));
+ }
+
+ /**
+ * Return the first pair matching a key from a list of key value pairs.
+ */
+ public static <T> Iterable<T> assoc(final Object k, final Object l) {
+ if(isNil(l))
+ return list();
+ if(k.equals(car(car(l))))
+ return car(l);
+ return assoc(k, cdr(l));
+ }
+
+ /**
+ * Internal base implementation class for iterable and immutable lists.
+ */
+ static abstract class BasicIterable<T> extends AbstractList<T> {
+ abstract T car();
+
+ abstract Iterable<T> cdr();
+
+ abstract Boolean isNil();
+
+ @Override
+ public int size() {
+ return this.isNil()? 0 : 1 + ((List<T>)this.cdr()).size();
+ }
+
+ @Override
+ public T get(final int index) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Internal implementation of a list backed by an array.
+ */
+ static class ArrayIterable<T> extends BasicIterable<T> {
+ final Object[] a;
+ final int start;
+
+ ArrayIterable(final Object[] a, final int start) {
+ this.a = a;
+ this.start = start;
+ }
+
+ @Override
+ Boolean isNil() {
+ return this.a.length - this.start == 0;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ T car() {
+ return (T)this.a[this.start];
+ }
+
+ @Override
+ BasicIterable<T> cdr() {
+ return new ArrayIterable<T>(this.a, this.start + 1);
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ return new Iterator<T>() {
+ int i = ArrayIterable.this.start;
+
+ public boolean hasNext() {
+ return this.i < ArrayIterable.this.a.length;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T next() {
+ return (T)ArrayIterable.this.a[this.i++];
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ }
+
+ /**
+ * Internal implementation of a list backed by a java.util.List.
+ */
+ static class ListIterable<T> extends BasicIterable<T> {
+ final List<?> l;
+ final int start;
+
+ ListIterable(final List<?> l, final int start) {
+ this.l = l;
+ this.start = start;
+ }
+
+ @Override
+ Boolean isNil() {
+ return this.l.size() - this.start == 0;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ T car() {
+ return (T)this.l.get(this.start);
+ }
+
+ @Override
+ BasicIterable<T> cdr() {
+ return new ListIterable<T>(this.l, this.start + 1);
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ return new Iterator<T>() {
+ int i = ListIterable.this.start;
+
+ public boolean hasNext() {
+ return this.i < ListIterable.this.l.size();
+ }
+
+ @SuppressWarnings("unchecked")
+ public T next() {
+ return (T)ListIterable.this.l.get(this.i++);
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ }
+
+ /**
+ * Internal implementation of a list backed by an element / iterable pair.
+ */
+ static class PairIterable<T> extends BasicIterable<T> {
+ final Object car;
+ final Iterable<?> cdr;
+
+ PairIterable(final Object car, final Iterable<?> cdr) {
+ this.car = car;
+ this.cdr = cdr;
+ }
+
+ @Override
+ Boolean isNil() {
+ return false;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ T car() {
+ return (T)this.car;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ Iterable<T> cdr() {
+ return (Iterable<T>)this.cdr;
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ return new Iterator<T>() {
+ boolean carIterator = true;
+ Iterator<?> cdrIterator = PairIterable.this.cdr.iterator();
+
+ public boolean hasNext() {
+ if(this.carIterator)
+ return true;
+ return this.cdrIterator.hasNext();
+ }
+
+ @SuppressWarnings("unchecked")
+ public T next() {
+ if(this.carIterator) {
+ this.carIterator = false;
+ return (T)PairIterable.this.car;
+ }
+ return (T)this.cdrIterator.next();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ }
+
+ /**
+ * Test the list functions.
+ */
+ static class Test {
+ Boolean testList() {
+ final Iterable<Object> l = list(2, 3, 4);
+ assert car(l) == Integer.valueOf(2);
+ assert cadr(l) == Integer.valueOf(3);
+ assert caddr(l) == Integer.valueOf(4);
+
+ final Iterable<Object> c = cons(0, cons(1, l));
+ assert car(c) == Integer.valueOf(0);
+ assert cadr(c) == Integer.valueOf(1);
+ assert caddr(c) == Integer.valueOf(2);
+ assert c.toString().equals("[0, 1, 2, 3, 4]");
+
+ final Iterable<Object> cl = cons(0, cons(1, new ArrayList<Object>(asList(2, 3, 4))));
+ assert car(cl) == Integer.valueOf(0);
+ assert cadr(cl) == Integer.valueOf(1);
+ assert caddr(cl) == Integer.valueOf(2);
+ assert cl.toString().equals("[0, 1, 2, 3, 4]");
+
+ final List<Object> jl = new ArrayList<Object>(collection(cl));
+ assert jl.size() == 5;
+ assert jl.get(0) == Integer.valueOf(0);
+ assert jl.get(1) == Integer.valueOf(1);
+ assert jl.get(2) == Integer.valueOf(2);
+
+ final Iterable<Object> n = list();
+ assert isNil(n);
+ assert n.toString().equals("[]");
+
+ final Iterable<Object> cn = cons(0, n);
+ assert !isNil(cn);
+ assert isNil(cdr(cn));
+ assert cn.toString().equals("[0]");
+
+ final Iterable<Object> al = new ArrayList<Object>(Arrays.asList(1, 2, 3));
+ assert car(al) == Integer.valueOf(1);
+ assert cadr(al) == Integer.valueOf(2);
+ assert caddr(al) == Integer.valueOf(3);
+ return true;
+ }
+ }
+
+ public static void main(final String[] args) {
+ System.out.println("Testing...");
+
+ Test.class.getClassLoader().setDefaultAssertionStatus(true);
+ new Test().testList();
+
+ System.out.println("OK");
+ }
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/Service.java b/sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/Service.java
new file mode 100644
index 0000000000..a00d5b1b53
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/Service.java
@@ -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.
+ */
+
+package org.apache.tuscany;
+
+/**
+ * Interface used to represent SCA component references providing both REST
+ * access to a resource and function application.
+ */
+public interface Service {
+
+ /**
+ * Post a new item to a collection of items.
+ */
+ Iterable<String> post(Iterable<String> collection, Iterable<?> item);
+
+ /**
+ * Return an item.
+ */
+ Iterable<?> get(Iterable<String> id);
+
+ /**
+ * Update an item.
+ */
+ boolean put(Iterable<String> id, Iterable<?> item);
+
+ /**
+ * Delete an item.
+ */
+ boolean delete(Iterable<String> id);
+
+ /**
+ * Evaluate an expression.
+ */
+ <T> T eval(Object... params);
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/UUIDUtil.java b/sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/UUIDUtil.java
new file mode 100644
index 0000000000..60076c62ca
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/org/apache/tuscany/UUIDUtil.java
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+package org.apache.tuscany;
+
+/**
+ * A fast and portable UUID generator function.
+ */
+public class UUIDUtil {
+
+ /**
+ * Return a UUID.
+ */
+ public static native String uuid();
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/server-test b/sca-cpp/branches/gcc-4.4/modules/java/server-test
new file mode 100755
index 0000000000..dba63a9525
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/server-test
@@ -0,0 +1,41 @@
+#!/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
+../http/httpd-conf tmp localhost 8090 ../server/htdocs
+../server/server-conf tmp
+./java-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+SCAContribution `pwd`/
+SCAComposite domain-test.composite
+EOF
+
+export CLASSPATH="`pwd`/libmod-tuscany-java-1.0.jar:`pwd`"
+
+../http/httpd-start tmp
+sleep 2
+
+# Test
+./client-test 2>/dev/null
+rc=$?
+
+# Cleanup
+../http/httpd-stop tmp
+sleep 2
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/test/Adder.java b/sca-cpp/branches/gcc-4.4/modules/java/test/Adder.java
new file mode 100644
index 0000000000..7236548c41
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/test/Adder.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package test;
+
+public interface Adder {
+
+ Double add(Double x, Double y);
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/test/AdderImpl.java b/sca-cpp/branches/gcc-4.4/modules/java/test/AdderImpl.java
new file mode 100644
index 0000000000..e607012b78
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/test/AdderImpl.java
@@ -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.
+ */
+
+package test;
+
+public class AdderImpl {
+
+ public Double add(Double x, Double y) {
+ return x + y;
+ }
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/test/CalcImpl.java b/sca-cpp/branches/gcc-4.4/modules/java/test/CalcImpl.java
new file mode 100644
index 0000000000..5bea01a43f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/test/CalcImpl.java
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+package test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.Service;
+
+public class CalcImpl {
+
+ public Double add(final Double x, final Double y, final Adder adder) {
+ return adder.add(x, y);
+ }
+
+ public Double addEval(final Double x, final Double y, final Service adder) {
+ return adder.eval("add", x, y);
+ }
+
+ public Double mult(final Double x, final Double y) {
+ return x * y;
+ }
+
+ public Boolean even(final Double x) {
+ return (double)((int)(double)x / 2 * 2) == (double)x;
+ }
+
+ public Iterable<Double> square(final Iterable<Double> l) {
+ final List<Double> r = new ArrayList<Double>();
+ for(final Double x : l)
+ r.add(x * x);
+ return r;
+ }
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/test/Client.java b/sca-cpp/branches/gcc-4.4/modules/java/test/Client.java
new file mode 100644
index 0000000000..c3bd875fcc
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/test/Client.java
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+package test;
+
+public interface Client {
+
+ String echo(String x);
+
+ Iterable<?> get(Iterable<String> id);
+
+ Iterable<String> post(Iterable<String> collection, Iterable<?> item);
+
+ Boolean put(Iterable<String> id, Iterable<?> item);
+
+ Boolean delete(Iterable<String> id);
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/test/ClientImpl.java b/sca-cpp/branches/gcc-4.4/modules/java/test/ClientImpl.java
new file mode 100644
index 0000000000..ade2ba302e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/test/ClientImpl.java
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+package test;
+
+public class ClientImpl {
+
+ public String echo(String x, Server server) {
+ return server.echo(x);
+ }
+
+ public Iterable<?> get(Iterable<String> id, Server server) {
+ return server.get(id);
+ }
+
+ public Iterable<String> post(Iterable<String> collection, Iterable<?> item, Server server) {
+ return server.post(collection, item);
+ }
+
+ public Boolean put(Iterable<String> id, Iterable<?> item, Server server) {
+ return server.put(id, item);
+ }
+
+ public Boolean delete(Iterable<String> id, Server server) {
+ return server.delete(id);
+ }
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/test/Server.java b/sca-cpp/branches/gcc-4.4/modules/java/test/Server.java
new file mode 100644
index 0000000000..3dfe3c84ef
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/test/Server.java
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+package test;
+
+public interface Server {
+
+ String echo(String x);
+
+ Iterable<?> get(Iterable<String> id);
+
+ Iterable<String> post(Iterable<String> collection, Iterable<?> item);
+
+ Boolean put(Iterable<String> id, Iterable<?> item);
+
+ Boolean delete(Iterable<String> id);
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/test/ServerImpl.java b/sca-cpp/branches/gcc-4.4/modules/java/test/ServerImpl.java
new file mode 100644
index 0000000000..05012c22cf
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/test/ServerImpl.java
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+package test;
+
+import static org.apache.tuscany.IterableUtil.*;
+
+public class ServerImpl {
+
+ public String echo(final String x) {
+ return x;
+ }
+
+ public Iterable<?> get(final Iterable<String> id) {
+ if (isNil(id))
+ return list("Sample Feed", "123456789",
+ list("Item", "111", list(list("'javaClass", "services.Item"), list("'name", "Apple"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 2.99))),
+ list("Item", "222", list(list("'javaClass", "services.Item"), list("'name", "Orange"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 3.55))),
+ list("Item", "333", list(list("'javaClass", "services.Item"), list("'name", "Pear"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 1.55))));
+ final Iterable<?> entry = list(list("'javaClass", "services.Item"), list("'name", "Apple"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 2.99));
+ return list("Item", car(id), entry);
+ }
+
+ public Iterable<String> post(final Iterable<String> collection, final Iterable<?> item) {
+ return list("123456789");
+ }
+
+ public Boolean put(final Iterable<String> id, final Iterable<?> item) {
+ return true;
+ }
+
+ public Boolean delete(final Iterable<String> id) {
+ return true;
+ }
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/java/wiring-test b/sca-cpp/branches/gcc-4.4/modules/java/wiring-test
new file mode 100755
index 0000000000..dcbaa3e1cc
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/java/wiring-test
@@ -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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../http/curl.prefix`
+
+# Setup
+../http/httpd-conf tmp localhost 8090 ../server/htdocs
+../server/server-conf tmp
+./java-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+SCAContribution `pwd`/
+SCAComposite domain-test.composite
+EOF
+
+export CLASSPATH="`pwd`/libmod-tuscany-java-1.0.jar:`pwd`"
+
+../http/httpd-start tmp
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/index.html 2>/dev/null >tmp/index.html
+diff tmp/index.html ../server/htdocs/index.html
+rc=$?
+
+# Test ATOMPub
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/ >tmp/feed.xml 2>/dev/null
+ diff tmp/feed.xml ../server/htdocs/feed.xml
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/111 >tmp/entry.xml 2>/dev/null
+ diff tmp/entry.xml ../server/htdocs/entry.xml
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/ -X POST -H "Content-type: application/atom+xml" --data @../server/htdocs/entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/111 -X PUT -H "Content-type: application/atom+xml" --data @../server/htdocs/entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/111 -X DELETE 2>/dev/null
+ rc=$?
+fi
+
+# Test JSON-RPC
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/ -X POST -H "Content-type: application/json-rpc" --data @../server/htdocs/json-request.txt >tmp/json-result.txt 2>/dev/null
+ diff tmp/json-result.txt ../server/htdocs/json-result.txt
+ rc=$?
+fi
+
+# Cleanup
+../http/httpd-stop tmp
+sleep 2
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/modules/json/Makefile.am b/sca-cpp/branches/gcc-4.4/modules/json/Makefile.am
new file mode 100644
index 0000000000..fd00ebb4af
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/json/Makefile.am
@@ -0,0 +1,22 @@
+# 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.
+
+json_test_SOURCES = json-test.cpp
+json_test_LDFLAGS = -lmozjs
+
+noinst_PROGRAMS = json-test
+TESTS = json-test
diff --git a/sca-cpp/branches/gcc-4.4/modules/json/json-test.cpp b/sca-cpp/branches/gcc-4.4/modules/json/json-test.cpp
new file mode 100644
index 0000000000..b74f068710
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/json/json-test.cpp
@@ -0,0 +1,176 @@
+/*
+ * 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 JSON data conversion functions.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "json.hpp"
+
+namespace tuscany {
+namespace json {
+
+bool testJSEval() {
+ JSONContext cx;
+ const string script("(function testJSON(n){ return JSON.parse(JSON.stringify(n)) })(5)");
+ jsval rval;
+ assert(JS_EvaluateScript(cx, cx.getGlobal(), c_str(script), length(script), "testJSON.js", 1, &rval));
+ const string r(JS_GetStringBytes(JS_ValueToString(cx, rval)));
+ assert(r == "5");
+ return true;
+}
+
+ostream* jsonWriter(const string& s, ostream* os) {
+ (*os) << s;
+ return os;
+}
+
+bool testJSON() {
+ const JSONContext cx;
+
+ {
+ const list<value> ad = mklist<value>(mklist<value>(attribute, "city", string("san francisco")), mklist<value>(attribute, "state", string("ca")));
+ const list<value> ac = mklist<value>(mklist<value>(element, "id", string("1234")), mklist<value>(attribute, "balance", 1000));
+ const list<value> cr = mklist<value>(mklist<value> (attribute, "name", string("jdoe")), cons<value>(element, cons<value>("address", ad)), cons<value>(element, cons<value>("account", ac)));
+ const list<value> c = mklist<value>(cons<value>(element, cons<value>("customer", cr)));
+
+ ostringstream os;
+ writeJSON<ostream*>(jsonWriter, &os, c, cx);
+ assert(str(os) == "{\"customer\":{\"@name\":\"jdoe\",\"address\":{\"@city\":\"san francisco\",\"@state\":\"ca\"},\"account\":{\"id\":\"1234\",\"@balance\":1000}}}");
+ }
+ {
+ const list<value> phones = mklist<value> (string("408-1234"), string("650-1234"));
+ const list<value> l = mklist<value> (mklist<value> (element, "phones", phones), mklist<value> (element, "lastName", string("test\ttab")), mklist<value> (attribute, "firstName", string("test1")));
+
+ ostringstream os;
+ writeJSON<ostream*>(jsonWriter, &os, l, cx);
+ assert(str(os) == "{\"phones\":[\"408-1234\",\"650-1234\"],\"lastName\":\"test\\u0009tab\",\"@firstName\":\"test1\"}");
+
+ istringstream is(str(os));
+ const list<string> il = streamList(is);
+ const list<value> r = content(readJSON(il, cx));
+ assert(r == l);
+
+ ostringstream wos;
+ write(content(writeJSON(r, cx)), wos);
+ assert(str(wos) == str(os));
+ }
+ {
+ const list<value> l = mklist<value>(list<value>() + "ns1:echoString" + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + (list<value>() + "text" + string("Hello World!")));
+ ostringstream wos;
+ write(content(writeJSON(valuesToElements(l), cx)), wos);
+ assert(str(wos) == "{\"ns1:echoString\":{\"@xmlns:ns1\":\"http://ws.apache.org/axis2/services/echo\",\"text\":\"Hello World!\"}}");
+
+ istringstream is(str(wos));
+ const list<string> il = streamList(is);
+ const list<value> r = elementsToValues(content(readJSON(il, cx)));
+ assert(r == l);
+ }
+ return true;
+}
+
+bool testJSONRPC() {
+ JSONContext cx;
+ {
+ const string lm("{\"id\": 1, \"method\": \"system.listMethods\", \"params\": []}");
+ const list<value> e = content(readJSON(mklist(lm), cx));
+ const list<value> v = elementsToValues(e);
+ assert(assoc<value>("id", v) == mklist<value>("id", 1));
+ assert(assoc<value>("method", v) == mklist<value>("method", string("system.listMethods")));
+ assert(assoc<value>("params", v) == mklist<value>("params", list<value>()));
+ }
+ {
+ const string i("{\"id\":3,\"result\":[{\"price\":\"$2.99\",\"name\":\"Apple\"},{\"price\":\"$3.55\",\"name\":\"Orange\"},{\"price\":\"$1.55\",\"name\":\"Pear\"}]}");
+ const list<value> e = content(readJSON(mklist(i), cx));
+ const string i2("{\"id\":3,\"result\":{\"0\":{\"price\":\"$2.99\",\"name\":\"Apple\"},\"1\":{\"price\":\"$3.55\",\"name\":\"Orange\"},\"2\":{\"price\":\"$1.55\",\"name\":\"Pear\"}}}");
+ const list<value> e2 = content(readJSON(mklist(i), cx));
+ assert(e == e2);
+ }
+ {
+ const string i("{\"id\":3,\"result\":[{\"price\":\"$2.99\",\"name\":\"Apple\"},{\"price\":\"$3.55\",\"name\":\"Orange\"},{\"price\":\"$1.55\",\"name\":\"Pear\"}]}");
+ const list<value> e = content(readJSON(mklist(i), cx));
+ ostringstream os;
+ write(content(writeJSON(e, cx)), os);
+ assert(str(os) == i);
+ const list<value> v = elementsToValues(e);
+ const list<value> r = valuesToElements(v);
+ assert(r == e);
+ }
+ {
+ const list<value> r = mklist<value>(mklist<value>("id", 1), mklist<value>("result", mklist<value>(string("Service.get"), string("Service.getTotal"))));
+ const list<value> e = valuesToElements(r);
+ ostringstream os;
+ write(content(writeJSON(e, cx)), os);
+ assert(str(os) == "{\"id\":1,\"result\":[\"Service.get\",\"Service.getTotal\"]}");
+ }
+ {
+ const string f("{\"id\":1,\"result\":[\"Sample Feed\",\"123456789\",[\"Item\",\"111\",{\"javaClass\":\"services.Item\",\"name\":\"Apple\",\"currencyCode\":\"USD\",\"currencySymbol\":\"$\",\"price\":2.99}],[\"Item\",\"222\",{\"javaClass\":\"services.Item\",\"name\":\"Orange\",\"currencyCode\":\"USD\",\"currencySymbol\":\"$\",\"price\":3.55}],[\"Item\",\"333\",{\"javaClass\":\"services.Item\",\"name\":\"Pear\",\"currencyCode\":\"USD\",\"currencySymbol\":\"$\",\"price\":1.55}]]}");
+ const list<value> r = content(readJSON(mklist(f), cx));
+ const list<value> v = elementsToValues(r);
+ const list<value> e = valuesToElements(v);
+ ostringstream os;
+ write(content(writeJSON(e, cx)), os);
+ assert(str(os) == f);
+ }
+ {
+ const list<value> arg = mklist<value>(list<value>() + "ns1:echoString" + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + (list<value>() + "text" + string("Hello World!")));
+ const failable<list<string> > r = jsonRequest(1, "echo", mklist<value>(arg), cx);
+ ostringstream os;
+ write(content(r), os);
+ assert(str(os) == "{\"id\":1,\"method\":\"echo\",\"params\":[{\"ns1:echoString\":{\"@xmlns:ns1\":\"http://ws.apache.org/axis2/services/echo\",\"text\":\"Hello World!\"}}]}");
+
+ istringstream is(str(os));
+ const list<string> il = streamList(is);
+ const list<value> ir = elementsToValues(content(readJSON(il, cx)));
+ assert(car<value>(cadr<value>(caddr<value>(ir))) == arg);
+ }
+ {
+ const list<value> res = mklist<value>(list<value>() + "ns1:echoString" + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/c/samples")) + (list<value>() + "text" + string("Hello World!")));
+ const failable<list<string> > r = jsonResult(1, res, cx);
+ ostringstream os;
+ write(content(r), os);
+ assert(str(os) == "{\"id\":1,\"result\":{\"ns1:echoString\":{\"@xmlns:ns1\":\"http://ws.apache.org/axis2/c/samples\",\"text\":\"Hello World!\"}}}");
+
+ istringstream is(str(os));
+ const list<string> il = streamList(is);
+ const list<value> ir = elementsToValues(content(readJSON(il, cx)));
+ assert(cdr<value>(cadr<value>(ir)) == res);
+ }
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::json::testJSEval();
+ tuscany::json::testJSON();
+ tuscany::json::testJSONRPC();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/json/json.hpp b/sca-cpp/branches/gcc-4.4/modules/json/json.hpp
new file mode 100644
index 0000000000..1d966d3f67
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/json/json.hpp
@@ -0,0 +1,403 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_json_hpp
+#define tuscany_json_hpp
+
+/**
+ * JSON data conversion functions.
+ */
+
+#define XP_UNIX
+#include <jsapi.h>
+#include "string.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "element.hpp"
+#include "monad.hpp"
+
+namespace tuscany {
+namespace json {
+
+/**
+ * Report JSON errors.
+ */
+void reportError(unused JSContext *cx, const char *message, JSErrorReport *report) {
+ cerr << (const char*)(report->filename? report->filename : "<no filename>") << ":"
+ << (int)report->lineno << ":" << message << endl;
+}
+
+/**
+ * Encapsulates a JavaScript runtime. Shared by multiple threads in
+ * a process.
+ */
+class JSONRuntime {
+public:
+ JSONRuntime() {
+ // Create JS runtime
+ rt = JS_NewRuntime(8L * 1024L * 1024L);
+ if(rt == NULL)
+ cleanup();
+ }
+
+ operator JSRuntime*() const {
+ return rt;
+ }
+private:
+ bool cleanup() {
+ if(rt != NULL) {
+ JS_DestroyRuntime(rt);
+ rt = NULL;
+ }
+ JS_ShutDown();
+ return true;
+ }
+
+ JSRuntime* rt;
+} jsRuntime;
+
+JSClass jsGlobalClass = { "global", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+ JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, JSCLASS_NO_OPTIONAL_MEMBERS};
+
+/**
+ * Represents a JavaScript context. Create one per thread.
+ */
+class JSONContext {
+public:
+ JSONContext() {
+ // Create JS context
+ cx = JS_NewContext(jsRuntime, 8192);
+ if(cx == NULL)
+ return;
+ JS_SetOptions(cx, JSOPTION_VAROBJFIX);
+ JS_SetVersion(cx, JSVERSION_DEFAULT);
+ JS_SetErrorReporter(cx, reportError);
+
+ // Create global JS object
+ global = JS_NewObject(cx, &jsGlobalClass, NULL, NULL);
+ if(global == NULL) {
+ cleanup();
+ return;
+ }
+
+ // Populate global object with the standard globals, like Object and Array
+ if(!JS_InitStandardClasses(cx, global)) {
+ cleanup();
+ return;
+ }
+ }
+
+ ~JSONContext() {
+ cleanup();
+ }
+
+ operator JSContext*() const {
+ return cx;
+ }
+
+ JSObject* getGlobal() const {
+ return global;
+ }
+
+private:
+ bool cleanup() {
+ if(cx != NULL) {
+ JS_DestroyContext(cx);
+ cx = NULL;
+ }
+ return true;
+ }
+
+ JSContext* cx;
+ JSObject* global;
+};
+
+/**
+ * Returns true if a list represents a JS array.
+ */
+const bool isJSArray(const list<value>& l) {
+ if(isNil(l))
+ return true;
+ const value v = car(l);
+ if (isSymbol(v))
+ return false;
+ if(isList(v)) {
+ if(!isNil((list<value>)v) && isSymbol(car<value>(v)))
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Converts JS properties to values.
+ */
+const list<value> jsPropertiesToValues(const list<value>& propertiesSoFar, JSObject* o, JSObject* i, const JSONContext& cx) {
+
+ const value jsValToValue(const jsval& jsv, const JSONContext& cx);
+
+ jsid id;
+ if(!JS_NextProperty(cx, i, &id) || id == JSVAL_VOID)
+ return propertiesSoFar;
+ jsval jsv;
+ if(!JS_GetPropertyById(cx, o, id, &jsv))
+ return propertiesSoFar;
+ const value val = jsValToValue(jsv, cx);
+
+ jsval idv;
+ JS_IdToValue(cx, id, &idv);
+ if(JSVAL_IS_STRING(idv)) {
+ const string name = JS_GetStringBytes(JSVAL_TO_STRING(idv));
+ if (substr(name, 0, 1) == atsign)
+ return jsPropertiesToValues(cons<value>(mklist<value>(attribute, c_str(substr(name, 1)), val), propertiesSoFar), o, i, cx);
+ if (isList(val) && !isJSArray(val))
+ return jsPropertiesToValues(cons<value>(cons<value>(element, cons<value>(c_str(name), list<value>(val))), propertiesSoFar), o, i, cx);
+ return jsPropertiesToValues(cons<value> (mklist<value> (element, c_str(name), val), propertiesSoFar), o, i, cx);
+ }
+ return jsPropertiesToValues(cons(val, propertiesSoFar), o, i, cx);
+}
+
+/**
+ * Converts a JS val to a value.
+ */
+const value jsValToValue(const jsval& jsv, const JSONContext& cx) {
+ switch(JS_TypeOfValue(cx, jsv)) {
+ case JSTYPE_STRING: {
+ return value(string(JS_GetStringBytes(JSVAL_TO_STRING(jsv))));
+ }
+ case JSTYPE_BOOLEAN: {
+ return value((bool)JSVAL_TO_BOOLEAN(jsv));
+ }
+ case JSTYPE_NUMBER: {
+ jsdouble jsd;
+ JS_ValueToNumber(cx, jsv, &jsd);
+ return value((double)jsd);
+ }
+ case JSTYPE_OBJECT: {
+ JSObject* o = JSVAL_TO_OBJECT(jsv);
+ JSObject* i = JS_NewPropertyIterator(cx, o);
+ if(i == NULL)
+ return value(list<value> ());
+ const value pv = jsPropertiesToValues(list<value> (), o, i, cx);
+ return pv;
+ }
+ default: {
+ return value();
+ }
+ }
+}
+
+/**
+ * Consumes JSON strings and populates a JS object.
+ */
+failable<bool> consume(JSONParser* parser, const list<string>& ilist, const JSONContext& cx) {
+ if (isNil(ilist))
+ return true;
+ JSString* jstr = JS_NewStringCopyZ(cx, c_str(car(ilist)));
+ if(!JS_ConsumeJSONText(cx, parser, JS_GetStringChars(jstr), JS_GetStringLength(jstr)))
+ return mkfailure<bool>("JS_ConsumeJSONText failed");
+ return consume(parser, cdr(ilist), cx);
+}
+
+/**
+ * Convert a list of strings representing a JSON document to a list of values.
+ */
+const failable<list<value> > readJSON(const list<string>& ilist, const JSONContext& cx) {
+ jsval val;
+ JSONParser* parser = JS_BeginJSONParse(cx, &val);
+ if(parser == NULL)
+ return mkfailure<list<value> >("JS_BeginJSONParse failed");
+
+ const failable<bool> consumed = consume(parser, ilist, cx);
+
+ if(!JS_FinishJSONParse(cx, parser, JSVAL_NULL))
+ return mkfailure<list<value> >("JS_FinishJSONParse failed");
+ if(!hasContent(consumed))
+ return mkfailure<list<value> >(reason(consumed));
+
+ return list<value>(jsValToValue(val, cx));
+}
+
+/**
+ * Converts a list of values to JS array elements.
+ */
+JSObject* valuesToJSElements(JSObject* a, const list<value>& l, int i, const JSONContext& cx) {
+ const jsval valueToJSVal(const value& val, const JSONContext& cx);
+ if (isNil(l))
+ return a;
+ jsval pv = valueToJSVal(car(l), cx);
+ JS_SetElement(cx, a, i, &pv);
+ return valuesToJSElements(a, cdr(l), ++i, cx);
+}
+
+/**
+ * Converts a value to a JS val.
+ */
+const jsval valueToJSVal(const value& val, const JSONContext& cx) {
+ JSObject* valuesToJSProperties(JSObject* o, const list<value>& l, const JSONContext& cx);
+
+ switch(type(val)) {
+ case value::String:
+ case value::Symbol: {
+ return STRING_TO_JSVAL(JS_NewStringCopyZ(cx, c_str((string)val)));
+ }
+ case value::Bool: {
+ return BOOLEAN_TO_JSVAL((bool)val);
+ }
+ case value::Number: {
+ return DOUBLE_TO_JSVAL(JS_NewDouble(cx, (double)val));
+ }
+ case value::List: {
+ if (isJSArray(val))
+ return OBJECT_TO_JSVAL(valuesToJSElements(JS_NewArrayObject(cx, 0, NULL), val, 0, cx));
+ return OBJECT_TO_JSVAL(valuesToJSProperties(JS_NewObject(cx, NULL, NULL, NULL), val, cx));
+ }
+ default: {
+ return JSVAL_VOID;
+ }
+ }
+}
+
+/**
+ * Converts a list of values to JS properties.
+ */
+JSObject* valuesToJSProperties(JSObject* o, const list<value>& l, const JSONContext& cx) {
+ if (isNil(l))
+ return o;
+
+ // Write an attribute
+ const value token(car(l));
+
+ if (isTaggedList(token, attribute)) {
+ jsval pv = valueToJSVal(attributeValue(token), cx);
+ JS_SetProperty(cx, o, c_str(atsign + string(attributeName(token))), &pv);
+
+ } else if (isTaggedList(token, element)) {
+
+ // Write the value of an element
+ if (elementHasValue(token)) {
+ jsval pv = valueToJSVal(elementValue(token), cx);
+ JS_SetProperty(cx, o, c_str(string(elementName(token))), &pv);
+
+ } else {
+
+ // Write a parent element
+ JSObject* child = JS_NewObject(cx, NULL, NULL, NULL);
+ jsval pv = OBJECT_TO_JSVAL(child);
+ JS_SetProperty(cx, o, c_str(string(elementName(token))), &pv);
+
+ // Write its children
+ valuesToJSProperties(child, elementChildren(token), cx);
+ }
+ }
+
+ // Go on
+ return valuesToJSProperties(o, cdr(l), cx);
+}
+
+/**
+ * Context passed to the JSON write callback function.
+ */
+template<typename R> class WriteContext {
+public:
+ WriteContext(const lambda<R(const string&, const R)>& reduce, const R& accum, const JSONContext& cx) : cx(cx), reduce(reduce), accum(accum) {
+ }
+ const JSONContext& cx;
+ const lambda<R(const string&, const R)> reduce;
+ R accum;
+};
+
+/**
+ * Called by JS_Stringify to write JSON out.
+ */
+template<typename R> JSBool writeCallback(const jschar *buf, uint32 len, void *data) {
+ WriteContext<R>& wcx = *(static_cast<WriteContext<R>*> (data));
+ JSString* jstr = JS_NewUCStringCopyN(wcx.cx, buf, len);
+ wcx.accum = wcx.reduce(string(JS_GetStringBytes(jstr), JS_GetStringLength(jstr)), wcx.accum);
+ return JS_TRUE;
+}
+
+/**
+ * Convert a list of values to a JSON document.
+ */
+template<typename R> const failable<R> writeJSON(const lambda<R(const string&, const R)>& reduce, const R& initial, const list<value>& l, const JSONContext& cx) {
+ jsval val = OBJECT_TO_JSVAL(valuesToJSProperties(JS_NewObject(cx, NULL, NULL, NULL), l, cx));
+
+ WriteContext<R> wcx(reduce, initial, cx);
+ if (!JS_Stringify(cx, &val, NULL, JSVAL_NULL, writeCallback<R>, &wcx))
+ return mkfailure<R>("JS_Stringify failed");
+ return wcx.accum;
+}
+
+/**
+ * Convert a list of values to a list of strings representing a JSON document.
+ */
+const failable<list<string> > writeJSON(const list<value>& l, const JSONContext& cx) {
+ const failable<list<string> > ls = writeJSON<list<string>>(rcons<string>, list<string>(), l, cx);
+ if (!hasContent(ls))
+ return ls;
+ return reverse(list<string>(content(ls)));
+}
+
+/**
+ * Convert a list of function + params to a JSON-RPC request.
+ */
+const failable<list<string> > jsonRequest(const value& id, const value& func, const value& params, json::JSONContext& cx) {
+ const list<value> r = mklist<value>(mklist<value>("id", id), mklist<value>("method", string(func)), mklist<value>("params", params));
+ return writeJSON(valuesToElements(r), cx);
+}
+
+/**
+ * Convert a value to a JSON-RPC result.
+ */
+const failable<list<string> > jsonResult(const value& id, const value& val, JSONContext& cx) {
+ return writeJSON(valuesToElements(mklist<value>(mklist<value>("id", id), mklist<value>("result", val))), cx);
+}
+
+/**
+ * Convert a JSON-RPC result to a value.
+ */
+const failable<value> jsonResultValue(const list<string>& s, JSONContext& cx) {
+ const failable<list<value> > jsres = json::readJSON(s, cx);
+ if (!hasContent(jsres))
+ return mkfailure<value>(reason(jsres));
+ const list<value> rval(cadr<value>(elementsToValues(content(jsres))));
+ const value val = cadr(rval);
+ if (isList(val) && !isJSArray(val))
+ return value(mklist<value>(val));
+ return val;
+}
+
+/**
+ * Return a portable function name from a JSON-RPC function name.
+ * Strip the "system." and "Service." prefixes added by some JSON-RPC clients.
+ */
+const string funcName(const string& f) {
+ if (length(f) > 7 && find(f, "system.", 0) == 0)
+ return c_str(f) + 7;
+ if (length(f) > 8 && find(f, "Service.", 0) == 0)
+ return c_str(f) + 8;
+ return f;
+}
+
+}
+}
+
+#endif /* tuscany_json_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/python/Makefile.am b/sca-cpp/branches/gcc-4.4/modules/python/Makefile.am
new file mode 100644
index 0000000000..c4e7b038e1
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/python/Makefile.am
@@ -0,0 +1,54 @@
+# 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.
+
+libdir = $(prefix)/modules/python
+
+if WANT_PYTHON
+
+INCLUDES = -I${PYTHON_INCLUDE}
+
+mod_SCRIPTS = python-conf
+moddir = $(prefix)/modules/python
+
+nobase_xsd_DATA = *.xsd
+xsddir = $(prefix)/xsd
+
+prefix_DATA = python.prefix
+prefixdir = $(prefix)/modules/python
+python.prefix: $(top_builddir)/config.status
+ echo ${PYTHON_PREFIX} >python.prefix
+
+lib_LTLIBRARIES = libmod_tuscany_python.la
+libmod_tuscany_python_la_SOURCES = mod-python.cpp
+libmod_tuscany_python_la_LDFLAGS = -lxml2 -lcurl -lmozjs -L${PYTHON_LIB} -R${PYTHON_LIB} -lpython2.6
+noinst_DATA = libmod_tuscany_python.so
+libmod_tuscany_python.so:
+ ln -s .libs/libmod_tuscany_python.so libmod_tuscany_python.so
+
+python_test_SOURCES = python-test.cpp
+python_test_LDFLAGS = -L${PYTHON_LIB} -R${PYTHON_LIB} -lpython2.6
+
+python_shell_SOURCES = python-shell.cpp
+python_shell_LDFLAGS = -L${PYTHON_LIB} -R${PYTHON_LIB} -lpython2.6
+
+client_test_SOURCES = client-test.cpp
+client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+
+noinst_PROGRAMS = python-test python-shell client-test
+TESTS = python-test server-test
+
+endif
diff --git a/sca-cpp/branches/gcc-4.4/modules/python/client-test.cpp b/sca-cpp/branches/gcc-4.4/modules/python/client-test.cpp
new file mode 100644
index 0000000000..21fda53e05
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/python/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 "../server/client-test.hpp"
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+ tuscany::server::testURI = "http://localhost:8090/python";
+
+ tuscany::server::testServer();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/python/client-test.py b/sca-cpp/branches/gcc-4.4/modules/python/client-test.py
new file mode 100644
index 0000000000..47e6cf4bda
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/python/client-test.py
@@ -0,0 +1,35 @@
+# 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.
+
+# JSON-RPC test case
+
+def echo(x, ref):
+ return ref("echo", x)
+
+# ATOMPub test case
+
+def get(id, ref):
+ return ref("get", id)
+
+def post(collection, item, ref):
+ return ref("post", collection, item)
+
+def put(id, item, ref):
+ return ref("put", id, item)
+
+def delete(id, ref):
+ return ref("delete", id)
diff --git a/sca-cpp/branches/gcc-4.4/modules/python/domain-test.composite b/sca-cpp/branches/gcc-4.4/modules/python/domain-test.composite
new file mode 100644
index 0000000000..c8e92b286e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/python/domain-test.composite
@@ -0,0 +1,42 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://domain/test"
+ name="domain-test">
+
+ <component name="python-test">
+ <t:implementation.python script="server-test.py"/>
+ <service name="test">
+ <t:binding.http uri="python"/>
+ </service>
+ </component>
+
+ <component name="client-test">
+ <t:implementation.python script="client-test.py"/>
+ <service name="client">
+ <t:binding.http uri="client"/>
+ </service>
+ <reference name="ref" target="python-test">
+ <t:binding.http/>
+ </reference>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/modules/python/driver.hpp b/sca-cpp/branches/gcc-4.4/modules/python/driver.hpp
new file mode 100644
index 0000000000..2820201057
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/python/driver.hpp
@@ -0,0 +1,63 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_python_driver_hpp
+#define tuscany_python_driver_hpp
+
+/**
+ * Python evaluator main driver loop.
+ */
+
+#include "string.hpp"
+#include "stream.hpp"
+#include "monad.hpp"
+#include "../scheme/driver.hpp"
+#include "eval.hpp"
+
+namespace tuscany {
+namespace python {
+
+const value evalDriverLoop(PyObject* script, istream& in, ostream& out) {
+ scheme::promptForInput(scheme::evalInputPrompt, out);
+ value input = scheme::readValue(in);
+ if (isNil(input))
+ return input;
+ const failable<value> output = evalScript(input, script);
+ scheme::announceOutput(scheme::evalOutputPrompt, out);
+ scheme::userPrint(content(output), out);
+ return evalDriverLoop(script, in, out);
+}
+
+const bool evalDriverRun(const char* path, istream& in, ostream& out) {
+ PythonRuntime py;
+ scheme::setupDisplay(out);
+ ifstream is(path);
+ failable<PyObject*> script = readScript(path, is);
+ if (!hasContent(script))
+ return true;
+ evalDriverLoop(content(script), in, out);
+ Py_DECREF(content(script));
+ return true;
+}
+
+}
+}
+#endif /* tuscany_python_driver_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/python/eval.hpp b/sca-cpp/branches/gcc-4.4/modules/python/eval.hpp
new file mode 100644
index 0000000000..855804a5ae
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/python/eval.hpp
@@ -0,0 +1,300 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_python_eval_hpp
+#define tuscany_python_eval_hpp
+
+/**
+ * Python script evaluation logic.
+ */
+#include <python2.6/Python.h>
+
+#include "list.hpp"
+#include "value.hpp"
+
+namespace tuscany {
+namespace python {
+
+/**
+ * Represent a Python runtime.
+ */
+class PythonRuntime {
+public:
+ PythonRuntime() {
+ if (Py_IsInitialized())
+ return;
+ Py_InitializeEx(0);
+ }
+};
+
+/**
+ * Return the last python error.
+ */
+const string lastError() {
+ if(PyErr_Occurred()) {
+ PyObject* type;
+ PyObject* val;
+ PyObject* trace;
+ PyErr_Fetch(&type, &val, &trace);
+ if (type != NULL && val != NULL) {
+ PyObject* stype = PyObject_Str(type);
+ PyObject* sval = PyObject_Str(val);
+ string msg = string() + PyString_AsString(stype) + " : " + PyString_AsString(sval);
+ Py_DECREF(stype);
+ Py_DECREF(sval);
+ Py_DECREF(type);
+ Py_DECREF(val);
+ Py_XDECREF(trace);
+ PyErr_Print();
+ return msg;
+ }
+ PyErr_Print();
+ Py_XDECREF(type);
+ Py_XDECREF(val);
+ Py_XDECREF(trace);
+ PyErr_Print();
+ return "Unknown Python error";
+ }
+ return "";
+}
+
+/**
+ * Declare conversion functions.
+ */
+PyObject* valueToPyObject(const value& v);
+const value pyObjectToValue(PyObject *o);
+PyObject* valuesToPyTuple(const list<value>& v);
+const list<value> pyTupleToValues(PyObject* o);
+
+/**
+ * Callable python type used to represent a lambda expression.
+ */
+typedef struct {
+ PyObject_HEAD
+ lambda<value(const list<value>&)> func;
+} pyLambda;
+
+void pyLambda_dealloc(PyObject* self) {
+ PyMem_DEL(self);
+}
+
+PyObject* pyLambda_call(PyObject* self, PyObject* args, unused PyObject* kwds) {
+ const pyLambda* pyl = (pyLambda*)self;
+ const value result = pyl->func(pyTupleToValues(args));
+ Py_DECREF(args);
+ PyObject *pyr = valueToPyObject(result);
+ return pyr;
+}
+
+PyTypeObject pyLambda_type = {
+ PyObject_HEAD_INIT(0)
+ 0,
+ "lambda",
+ sizeof(pyLambda),
+ 0,
+ (destructor)pyLambda_dealloc,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ (ternaryfunc)pyLambda_call,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0
+};
+
+/**
+ * Create a new python object representing a lambda expression.
+ */
+PyObject *mkPyLambda(const lambda<value(const list<value>&)>& l) {
+ pyLambda* pyl = NULL;
+ pyl = PyObject_NEW(pyLambda, &pyLambda_type);
+ if (pyl != NULL)
+ pyl->func = l;
+ return (PyObject *)pyl;
+}
+
+/**
+ * Convert a list of values to a python list.
+ */
+
+PyObject* valuesToPyListHelper(PyObject* l, const list<value>& v) {
+ if (isNil(v))
+ return l;
+ PyList_Append(l, valueToPyObject(car(v)));
+ return valuesToPyListHelper(l, cdr(v));
+}
+
+PyObject* valuesToPyTuple(const list<value>& v) {
+ return PyList_AsTuple(valuesToPyListHelper(PyList_New(0), v));
+}
+
+/**
+ * Convert a value to a python object.
+ */
+PyObject* valueToPyObject(const value& v) {
+ switch (type(v)) {
+ case value::List:
+ return valuesToPyTuple(v);
+ case value::Lambda:
+ return mkPyLambda(v);
+ case value::Symbol:
+ return PyString_FromString(c_str(string("'") + v));
+ case value::String:
+ return PyString_FromString(c_str(v));
+ case value::Number:
+ return PyFloat_FromDouble((double)v);
+ case value::Bool:
+ return (bool)v? Py_True : Py_False;
+ default:
+ return Py_None;
+ }
+}
+
+/**
+ * Convert a python tuple to a list of values.
+ */
+
+const list<value> pyTupleToValuesHelper(PyObject* o, const int i, const int size) {
+ if (i == size)
+ return list<value>();
+ return cons(pyObjectToValue(PyTuple_GetItem(o, i)), pyTupleToValuesHelper(o, i + 1, size));
+}
+
+const list<value> pyTupleToValues(PyObject* o) {
+ return pyTupleToValuesHelper(o, 0, PyTuple_Size(o));
+}
+
+/**
+ * Lambda function used to represent a python callable object.
+ */
+struct pyCallable {
+ PyObject* func;
+
+ pyCallable(PyObject* func) : func(func) {
+ Py_INCREF(func);
+ }
+
+ ~pyCallable() {
+ Py_DECREF(func);
+ }
+
+ const value operator()(const list<value>& args) const {
+ PyObject* pyargs = valuesToPyTuple(args);
+ PyObject* result = PyObject_CallObject(func, pyargs);
+ Py_DECREF(pyargs);
+ const value v = pyObjectToValue(result);
+ Py_DECREF(result);
+ return v;
+ }
+};
+
+/**
+ * Convert a python object to a value.
+ */
+const value pyObjectToValue(PyObject *o) {
+ if (PyString_Check(o)) {
+ const char* s = PyString_AsString(o);
+ if (*s == '\'')
+ return value(s + 1);
+ return value(string(s));
+ }
+ if (PyBool_Check(o))
+ return value(o == Py_True);
+ if (PyInt_Check(o))
+ return value((double)PyInt_AsLong(o));
+ if (PyLong_Check(o))
+ return value((double)PyLong_AsLong(o));
+ if (PyFloat_Check(o))
+ return value((double)PyFloat_AsDouble(o));
+ if (PyTuple_Check(o))
+ return pyTupleToValues(o);
+ if (PyCallable_Check(o))
+ return lambda<value(const list<value>&)>(pyCallable(o));
+ return value();
+}
+
+/**
+ * Evaluate an expression against a script provided as a python object.
+ */
+const failable<value> evalScript(const value& expr, PyObject* script) {
+
+ // Get the requested function
+ PyObject* func = PyObject_GetAttrString(script, c_str(car<value>(expr)));
+ if (func == NULL) {
+
+ // The start, stop, and restart functions are optional
+ const value fn = car<value>(expr);
+ if (fn == "start" || fn == "stop") {
+ PyErr_Clear();
+ return value(lambda<value(const list<value>&)>());
+ }
+
+ return mkfailure<value>(string("Couldn't find function: ") + car<value>(expr) + " : " + lastError());
+ }
+ if (!PyCallable_Check(func)) {
+ Py_DECREF(func);
+ return mkfailure<value>(string("Couldn't find callable function: ") + car<value>(expr));
+ }
+
+ // Convert args to python objects
+ PyObject* args = valuesToPyTuple(cdr<value>(expr));
+
+ // Call the function
+ PyObject* result = PyObject_CallObject(func, args);
+ Py_DECREF(args);
+ Py_DECREF(func);
+ if (result == NULL)
+ return mkfailure<value>(string("Function call failed: ") + car<value>(expr) + " : " + lastError());
+
+ // Convert python result to a value
+ const value v = pyObjectToValue(result);
+ Py_DECREF(result);
+ return v;
+}
+
+/**
+ * Read a python script from an input stream.
+ */
+const failable<PyObject*> readScript(const string& path, istream& is) {
+ const list<string> ls = streamList(is);
+ ostringstream os;
+ write(ls, os);
+ PyObject* code = Py_CompileStringFlags(c_str(str(os)), c_str(path), Py_file_input, NULL);
+ if (code == NULL)
+ return mkfailure<PyObject*>(string("Couldn't compile script: ") + path + " : " + lastError());
+ PyObject* mod = PyImport_ExecCodeModule(const_cast<char*>(c_str(path)), code);
+ if (mod == NULL)
+ return mkfailure<PyObject*>(string("Couldn't import module: ") + path + " : " + lastError());
+ return mod;
+}
+
+/**
+ * Evaluate an expression against a script provided as an input stream.
+ */
+const failable<value> evalScript(const value& expr, istream& is) {
+ failable<PyObject*> script = readScript("script", is);
+ if (!hasContent(script))
+ return mkfailure<value>(reason(script));
+ return evalScript(expr, content(script));
+}
+
+}
+}
+#endif /* tuscany_python_eval_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/python/mod-python.cpp b/sca-cpp/branches/gcc-4.4/modules/python/mod-python.cpp
new file mode 100644
index 0000000000..8561a1fbf4
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/python/mod-python.cpp
@@ -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.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * HTTPD module used to eval Python component implementations.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "../server/mod-cpp.hpp"
+#include "../server/mod-eval.hpp"
+#include "mod-python.hpp"
+
+namespace tuscany {
+namespace server {
+namespace modeval {
+
+/**
+ * Apply a lifecycle start or restart event.
+ */
+const value applyLifecycle(unused const list<value>& params) {
+
+ // Create a Python runtime
+ new (gc_new<python::PythonRuntime>()) python::PythonRuntime();
+
+ // Return a nil function as we don't need to handle the stop event
+ return failable<value>(lambda<value(const list<value>&)>());
+}
+
+/**
+ * Evaluate a Python component implementation and convert it to an applicable
+ * lambda function.
+ */
+const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, unused const lambda<value(const list<value>&)>& lifecycle) {
+ const string itype(elementName(impl));
+ if (contains(itype, ".python"))
+ return modpython::evalImplementation(path, impl, px);
+ if (contains(itype, ".cpp"))
+ return modcpp::evalImplementation(path, impl, px);
+ return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype);
+}
+
+}
+}
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/python/mod-python.hpp b/sca-cpp/branches/gcc-4.4/modules/python/mod-python.hpp
new file mode 100644
index 0000000000..d13f2227ab
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/python/mod-python.hpp
@@ -0,0 +1,79 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_modpython_hpp
+#define tuscany_modpython_hpp
+
+/**
+ * Evaluation functions used by mod-eval to evaluate Python
+ * component implementations.
+ */
+
+#include "string.hpp"
+#include "stream.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "eval.hpp"
+
+namespace tuscany {
+namespace server {
+namespace modpython {
+
+/**
+ * Apply a Python component implementation function.
+ */
+struct applyImplementation {
+ PyObject* impl;
+ const list<value> px;
+ applyImplementation(PyObject* impl, const list<value>& px) : impl(impl), px(px) {
+ }
+ const value operator()(const list<value>& params) const {
+ const value expr = append<value>(params, px);
+ debug(expr, "modeval::python::applyImplementation::input");
+ const failable<value> res = python::evalScript(expr, impl);
+ const value val = !hasContent(res)? mklist<value>(value(), reason(res)) : mklist<value>(content(res));
+ debug(val, "modeval::python::applyImplementation::result");
+ return val;
+ }
+};
+
+/**
+ * Evaluate a Python component implementation and convert it to an applicable
+ * lambda function.
+ */
+const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) {
+ const string fpath(path + attributeValue("script", impl));
+ ifstream is(fpath);
+ if (fail(is))
+ return mkfailure<lambda<value(const list<value>&)> >(string("Could not read implementation: ") + fpath);
+ const failable<PyObject*> script = python::readScript(fpath, is);
+ if (!hasContent(script))
+ return mkfailure<lambda<value(const list<value>&)> >(reason(script));
+ return lambda<value(const list<value>&)>(applyImplementation(content(script), px));
+}
+
+}
+}
+}
+
+#endif /* tuscany_modpython_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/python/python-conf b/sca-cpp/branches/gcc-4.4/modules/python/python-conf
new file mode 100755
index 0000000000..983679db4d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/python/python-conf
@@ -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.
+
+# Generate a Python server conf
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+
+cat >>$root/conf/httpd.conf <<EOF
+# Support for Python SCA components
+LoadModule mod_tuscany_eval $here/libmod_tuscany_python.so
+
+EOF
diff --git a/sca-cpp/branches/gcc-4.4/modules/python/python-shell.cpp b/sca-cpp/branches/gcc-4.4/modules/python/python-shell.cpp
new file mode 100644
index 0000000000..89b47b8d44
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/python/python-shell.cpp
@@ -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.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Python script evaluator shell, used for interactive testing of scripts.
+ */
+
+#include <assert.h>
+#include "gc.hpp"
+#include "stream.hpp"
+#include "string.hpp"
+#include "driver.hpp"
+
+int main(const int argc, char** argv) {
+ tuscany::gc_scoped_pool pool;
+ if (argc != 2) {
+ tuscany::cerr << "Usage: python-shell <script.py>" << tuscany::endl;
+ return 1;
+ }
+ tuscany::python::evalDriverRun(argv[1], tuscany::cin, tuscany::cout);
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/python/python-test.cpp b/sca-cpp/branches/gcc-4.4/modules/python/python-test.cpp
new file mode 100644
index 0000000000..c4ffcee57e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/python/python-test.cpp
@@ -0,0 +1,109 @@
+/*
+ * 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 Python script evaluator.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "driver.hpp"
+
+namespace tuscany {
+namespace python {
+
+const string testPythonAdd =
+ "def add(x, y):\n"
+ " return x + y\n";
+
+bool testEvalExpr() {
+ gc_scoped_pool pool;
+ PythonRuntime py;
+
+ istringstream is(testPythonAdd);
+ failable<PyObject*> script = readScript("script", is);
+ assert(hasContent(script));
+
+ const value exp = mklist<value>("add", 2, 3);
+ const failable<value> r = evalScript(exp, content(script));
+ assert(hasContent(r));
+ assert(content(r) == value(5));
+
+ return true;
+}
+
+const value mult(const list<value>& args) {
+ const double x = car(args);
+ const double y = cadr(args);
+ return x * y;
+}
+
+const string testReturnLambda(
+ "def mul(x, y):\n"
+ " return x * y\n"
+ "\n"
+ "def testReturnLambda():\n"
+ " return mul\n");
+
+const string testCallLambda(
+ "def testCallLambda(l, x, y):\n"
+ " return l(x, y)\n");
+
+bool testEvalLambda() {
+ gc_scoped_pool pool;
+ PythonRuntime py;
+
+ const value trl = mklist<value>("testReturnLambda");
+ istringstream trlis(testReturnLambda);
+ const failable<value> trlv = evalScript(trl, trlis);
+
+ assert(hasContent(trlv));
+ assert(isLambda(content(trlv)));
+ const lambda<value(const list<value>&)> trll(content(trlv));
+ assert(trll(mklist<value>(2, 3)) == value(6));
+
+ istringstream tclis(testCallLambda);
+ const value tcl = mklist<value>("testCallLambda", content(trlv), 2, 3);
+ const failable<value> tclv = evalScript(tcl, tclis);
+ assert(hasContent(tclv));
+ assert(content(tclv) == value(6));
+
+ istringstream tcelis(testCallLambda);
+ const value tcel = mklist<value>("testCallLambda", lambda<value(const list<value>&)>(mult), 3, 4);
+ const failable<value> tcelv = evalScript(tcel, tcelis);
+ assert(hasContent(tcelv));
+ assert(content(tcelv) == value(12));
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::python::testEvalExpr();
+ tuscany::python::testEvalLambda();
+
+ tuscany::cout << "OK" << tuscany::endl;
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/python/server-test b/sca-cpp/branches/gcc-4.4/modules/python/server-test
new file mode 100755
index 0000000000..b01f5f501d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/python/server-test
@@ -0,0 +1,39 @@
+#!/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
+../http/httpd-conf tmp localhost 8090 ../server/htdocs
+../server/server-conf tmp
+./python-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+SCAContribution `pwd`/
+SCAComposite domain-test.composite
+EOF
+
+../http/httpd-start tmp
+sleep 2
+
+# Test
+./client-test 2>/dev/null
+rc=$?
+
+# Cleanup
+../http/httpd-stop tmp
+sleep 2
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/modules/python/server-test.py b/sca-cpp/branches/gcc-4.4/modules/python/server-test.py
new file mode 100644
index 0000000000..dcda763043
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/python/server-test.py
@@ -0,0 +1,42 @@
+# 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.
+
+# JSON-RPC test case
+
+def echo(x):
+ return x
+
+# ATOMPub test case
+
+def get(id):
+ if id == ():
+ return ("Sample Feed", "123456789",
+ ("Item", "111", (("'javaClass", "services.Item"), ("'name", "Apple"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 2.99))),
+ ("Item", "222", (("'javaClass", "services.Item"), ("'name", "Orange"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 3.55))),
+ ("Item", "333", (("'javaClass", "services.Item"), ("name", "Pear"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 1.55))))
+
+ entry = (("'javaClass", "services.Item"), ("'name", "Apple"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 2.99))
+ return ("Item", id[0], entry)
+
+def post(collection, item):
+ return ("123456789",)
+
+def put(id, item):
+ return True
+
+def delete(id):
+ return True
diff --git a/sca-cpp/branches/gcc-4.4/modules/python/tuscany-sca-1.1-implementation-python.xsd b/sca-cpp/branches/gcc-4.4/modules/python/tuscany-sca-1.1-implementation-python.xsd
new file mode 100644
index 0000000000..c811ba6729
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/python/tuscany-sca-1.1-implementation-python.xsd
@@ -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.
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/1.1"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ elementFormDefault="qualified">
+
+ <import namespace="http://docs.oasis-open.org/ns/opencsa/sca/200912" schemaLocation="sca-1.1-cd04.xsd"/>
+
+ <element name="implementation.python" type="t:PythonImplementation" substitutionGroup="sca:implementation"/>
+
+ <complexType name="PythonImplementation">
+ <complexContent>
+ <extension base="sca:Implementation">
+ <sequence>
+ <any namespace="##targetNamespace" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="script" type="anyURI" use="required"/>
+ <anyAttribute namespace="##any" processContents="lax"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/modules/python/wiring-test b/sca-cpp/branches/gcc-4.4/modules/python/wiring-test
new file mode 100755
index 0000000000..42df9d4ff3
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/python/wiring-test
@@ -0,0 +1,78 @@
+#!/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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../http/curl.prefix`
+
+# Setup
+../http/httpd-conf tmp localhost 8090 ../server/htdocs
+../server/server-conf tmp
+./python-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+SCAContribution `pwd`/
+SCAComposite domain-test.composite
+EOF
+
+../http/httpd-start tmp
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/index.html 2>/dev/null >tmp/index.html
+diff tmp/index.html ../server/htdocs/index.html
+rc=$?
+
+# Test ATOMPub
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/ >tmp/feed.xml 2>/dev/null
+ diff tmp/feed.xml ../server/htdocs/feed.xml
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/111 >tmp/entry.xml 2>/dev/null
+ diff tmp/entry.xml ../server/htdocs/entry.xml
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/ -X POST -H "Content-type: application/atom+xml" --data @../server/htdocs/entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/111 -X PUT -H "Content-type: application/atom+xml" --data @../server/htdocs/entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/111 -X DELETE 2>/dev/null
+ rc=$?
+fi
+
+# Test JSON-RPC
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/ -X POST -H "Content-type: application/json-rpc" --data @../server/htdocs/json-request.txt >tmp/json-result.txt 2>/dev/null
+ diff tmp/json-result.txt ../server/htdocs/json-result.txt
+ rc=$?
+fi
+
+# Cleanup
+../http/httpd-stop tmp
+sleep 2
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/modules/scdl/Makefile.am b/sca-cpp/branches/gcc-4.4/modules/scdl/Makefile.am
new file mode 100644
index 0000000000..542ce4be20
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/scdl/Makefile.am
@@ -0,0 +1,22 @@
+# 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.
+
+scdl_test_SOURCES = scdl-test.cpp
+scdl_test_LDFLAGS = -lxml2
+
+noinst_PROGRAMS = scdl-test
+TESTS = scdl-test
diff --git a/sca-cpp/branches/gcc-4.4/modules/scdl/scdl-test.cpp b/sca-cpp/branches/gcc-4.4/modules/scdl/scdl-test.cpp
new file mode 100644
index 0000000000..e8ee77eb4e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/scdl/scdl-test.cpp
@@ -0,0 +1,124 @@
+/*
+ * 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 SCDL read functions.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "list.hpp"
+#include "tree.hpp"
+#include "scdl.hpp"
+
+namespace tuscany {
+namespace scdl {
+
+bool testComposite() {
+ ifstream is("test.composite");
+ const list<value> c = readXML(streamList(is));
+ return true;
+}
+
+bool testComponents() {
+ ifstream is("test.composite");
+ const list<value> c = components(readXML(streamList(is)));
+ assert(length(c) == 4);
+
+ const value store = car(c);
+ assert(name(store) == string("Store"));
+ const value impl = implementation(store);
+ assert(uri(impl) == string("store.html"));
+ assert(implementationType(impl) == "t:implementation.scheme");
+
+ const value catalog = named(string("Catalog"), c);
+ assert(name(catalog) == string("Catalog"));
+
+ const list<value> t = mkbtree(sort(nameToElementAssoc(c)));
+ assert(assoctree<value>("Catalog", t) == mklist<value>("Catalog" , cadr(c)));
+ return true;
+}
+
+bool testServices() {
+ ifstream is("test.composite");
+ const list<value> c = components(readXML(streamList(is)));
+ const value store = car(c);
+
+ assert(length(services(store)) == 1);
+ const value widget = car(services(store));
+ assert(name(widget) == string("Widget"));
+
+ assert(length(bindings(widget)) == 1);
+ const value binding = car(bindings(widget));
+ assert(uri(binding) == string("/store"));
+ assert(bindingType(binding) == "t:binding.http");
+ return true;
+}
+
+bool testReferences() {
+ ifstream is("test.composite");
+ const list<value> c = components(readXML(streamList(is)));
+ const value store = car(c);
+
+ assert(length(references(store)) == 3);
+ const value catalog = car(references(store));
+ assert(name(catalog) == string("catalog"));
+ assert(target(catalog) == string("Catalog"));
+
+ assert(length(bindings(catalog)) == 1);
+ const value binding = car(bindings(catalog));
+ assert(uri(binding) == value());
+ assert(bindingType(binding) == "t:binding.jsonrpc");
+
+ const list<value> t = mkbtree(sort(referenceToTargetAssoc(references(store))));
+ assert(assoctree<value>("shoppingCart", t) == mklist<value>(string("shoppingCart"), string("ShoppingCart/Cart")));
+ return true;
+}
+
+bool testProperties() {
+ ifstream is("test.composite");
+ const list<value> c = components(readXML(streamList(is)));
+ const value catalog = named(string("Catalog"), c);
+
+ assert(length(properties(catalog)) == 1);
+ const value currencyCode = car(properties(catalog));
+ assert(name(currencyCode) == string("currencyCode"));
+ assert(propertyValue(currencyCode) == string("USD"));
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::scdl::testComposite();
+ tuscany::scdl::testComponents();
+ tuscany::scdl::testServices();
+ tuscany::scdl::testReferences();
+ tuscany::scdl::testProperties();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/scdl/scdl.hpp b/sca-cpp/branches/gcc-4.4/modules/scdl/scdl.hpp
new file mode 100644
index 0000000000..531144e219
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/scdl/scdl.hpp
@@ -0,0 +1,178 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_scdl_hpp
+#define tuscany_scdl_hpp
+
+/**
+ * SCDL read functions.
+ */
+
+#include "string.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "xml.hpp"
+
+namespace tuscany {
+namespace scdl {
+
+/**
+ * Returns a list of components in a composite.
+ */
+const list<value> components(const value& l) {
+ const list<value> cs = elementChildren("composite", l);
+ if (isNil(cs))
+ return cs;
+ return elementChildren("component", car(cs));
+}
+
+/**
+ * Returns the name of a component, service or reference.
+ */
+const value name(const value& l) {
+ return attributeValue("name", l);
+}
+
+/**
+ * Convert a list of elements to a name -> element assoc list.
+ */
+const list<value> nameToElementAssoc(const list<value>& l) {
+ if (isNil(l))
+ return l;
+ const value e(car(l));
+ return cons<value>(mklist<value>(name(e), e), nameToElementAssoc(cdr(l)));
+}
+
+/**
+ * Returns the scdl declaration with the given name.
+ */
+struct filterName {
+ const value n;
+ filterName(const value& n) : n(n) {
+ }
+ const bool operator()(const value& v) const {
+ return name(v) == n;
+ }
+};
+
+const value named(const value& name, const value& l) {
+ const list<value> c = filter<value>(filterName(name), l);
+ if (isNil(c))
+ return value();
+ return car(c);
+}
+
+/**
+ * Returns the implementation of a component.
+ */
+const bool filterImplementation(const value& v) {
+ return isElement(v) && contains(string(cadr<value>(v)), "implementation.");
+}
+
+const value implementation(const value& l) {
+ const list<value> n = filter<value>(filterImplementation, l);
+ if (isNil(n))
+ return value();
+ return car(n);
+}
+
+/**
+ * Returns the URI of a service, reference or implementation.
+ */
+const value uri(const value& l) {
+ return attributeValue("uri", l);
+}
+
+/**
+ * Returns a list of services in a component.
+ */
+const list<value> services(const value& l) {
+ return elementChildren("service", l);
+}
+
+/**
+ * Returns a list of references in a component.
+ */
+const list<value> references(const value& l) {
+ return elementChildren("reference", l);
+}
+
+/**
+ * Returns the target of a reference.
+ */
+const value target(const value& l) {
+ return attributeValue("target", l);
+}
+
+/**
+ * Convert a list of references to a reference name -> target assoc list.
+ */
+const list<value> referenceToTargetAssoc(const list<value>& r) {
+ if (isNil(r))
+ return r;
+ const value ref(car(r));
+ return cons<value>(mklist<value>(scdl::name(ref), scdl::target(ref)), referenceToTargetAssoc(cdr(r)));
+}
+
+/**
+ * Returns a list of bindings in a service or reference.
+ */
+const bool filterBinding(const value& v) {
+ return isElement(v) && contains(string(cadr<value>(v)), "binding.");
+}
+
+const list<value> bindings(const value& l) {
+ return filter<value>(filterBinding, l);
+}
+
+/**
+ * Returns a list of properties in a component.
+ */
+const list<value> properties(const value& l) {
+ return elementChildren("property", l);
+}
+
+/**
+ * Returns the type of an implementation.
+ */
+const value implementationType(const value& l) {
+ return elementName(l);
+}
+
+/**
+ * Returns the type of a binding.
+ */
+const value bindingType(const value& l) {
+ return elementName(l);
+}
+
+/**
+ * Returns the value of a property.
+ */
+const value propertyValue(const value& l) {
+ return elementValue(l);
+}
+
+}
+}
+
+#endif /* tuscany_scdl_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/scdl/test.composite b/sca-cpp/branches/gcc-4.4/modules/scdl/test.composite
new file mode 100644
index 0000000000..f6fdba7f5f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/scdl/test.composite
@@ -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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.scheme script="store.scm"/>
+ <service name="Widget">
+ <t:binding.http uri="/store"/>
+ </service>
+ <reference name="catalog" target="Catalog">
+ <t:binding.jsonrpc/>
+ </reference>
+ <reference name="shoppingCart" target="ShoppingCart/Cart">
+ <t:binding.atom/>
+ </reference>
+ <reference name="shoppingTotal" target="ShoppingCart/Total">
+ <t:binding.jsonrpc/>
+ </reference>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.scheme script="fruits-catalog.scm"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.scheme script="shopping-cart.scm"/>
+ <service name="Cart">
+ <t:binding.atom uri="/ShoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc/>
+ </service>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.scheme script="currency-converter.scm"/>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/modules/scheme/Makefile.am b/sca-cpp/branches/gcc-4.4/modules/scheme/Makefile.am
new file mode 100644
index 0000000000..03556d0c45
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/scheme/Makefile.am
@@ -0,0 +1,26 @@
+# 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.
+
+xsddir=$(prefix)/xsd
+nobase_xsd_DATA = *.xsd
+
+eval_test_SOURCES = eval-test.cpp
+
+eval_shell_SOURCES = eval-shell.cpp
+
+noinst_PROGRAMS = eval-test eval-shell
+TESTS = eval-test
diff --git a/sca-cpp/branches/gcc-4.4/modules/scheme/driver.hpp b/sca-cpp/branches/gcc-4.4/modules/scheme/driver.hpp
new file mode 100644
index 0000000000..112c226ed1
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/scheme/driver.hpp
@@ -0,0 +1,76 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_scheme_driver_hpp
+#define tuscany_scheme_driver_hpp
+
+/**
+ * Script evaluator main driver loop.
+ */
+
+#include "string.hpp"
+#include "stream.hpp"
+#include "eval.hpp"
+
+namespace tuscany {
+namespace scheme {
+
+const string evalOutputPrompt("; ");
+const string evalInputPrompt("=> ");
+
+const bool promptForInput(const string& str, ostream& out) {
+ out << endl << endl << str;
+ return true;
+}
+
+const bool announceOutput(const string str, ostream& out) {
+ out << endl << str;
+ return true;
+}
+
+const bool userPrint(const value val, ostream& out) {
+ if(isCompoundProcedure(val))
+ writeValue(mklist<value>(compoundProcedureSymbol, procedureParameters(val), procedureBody(val), "<procedure-env>"), out);
+ writeValue(val, out);
+ return true;
+}
+
+const value evalDriverLoop(istream& in, ostream& out, Env& env) {
+ promptForInput(evalInputPrompt, out);
+ value input = readValue(in);
+ if (isNil(input))
+ return input;
+ const value output = evalExpr(input, env);
+ announceOutput(evalOutputPrompt, out);
+ userPrint(output, out);
+ return evalDriverLoop(in, out, env);
+}
+
+const bool evalDriverRun(istream& in, ostream& out) {
+ setupDisplay(out);
+ Env env = setupEnvironment();
+ evalDriverLoop(in, out, env);
+ return true;
+}
+
+}
+}
+#endif /* tuscany_scheme_driver_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/scheme/environment.hpp b/sca-cpp/branches/gcc-4.4/modules/scheme/environment.hpp
new file mode 100644
index 0000000000..bfb415a978
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/scheme/environment.hpp
@@ -0,0 +1,179 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_scheme_environment_hpp
+#define tuscany_scheme_environment_hpp
+
+/**
+ * Script evaluator environment implementation.
+ */
+
+#include "string.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "primitive.hpp"
+#include <string>
+
+namespace tuscany {
+namespace scheme {
+
+typedef value Frame;
+typedef list<value> Env;
+
+const value trueSymbol("true");
+const value falseSymbol("false");
+const value defineSymbol("define");
+const value setSymbol("set!");
+const value dotSymbol(".");
+
+const Env theEmptyEnvironment() {
+ return list<value>();
+}
+
+const bool isDefinition(const value& exp) {
+ return isTaggedList(exp, defineSymbol);
+}
+
+const bool isAssignment(const value& exp) {
+ return isTaggedList(exp, setSymbol);
+}
+
+const bool isVariable(const value& exp) {
+ return isSymbol(exp);
+}
+
+const Env enclosingEnvironment(const Env& env) {
+ return cdr(env);
+}
+
+const gc_ptr<Frame> firstFrame(const Env& env) {
+ return car(env);
+}
+
+list<value> frameVariables(const Frame& frame) {
+ return car((list<value> )frame);
+}
+
+list<value> frameValues(const Frame& frame) {
+ return cdr((list<value> )frame);
+}
+
+const bool isDotVariable(const value& var) {
+ return var == dotSymbol;
+}
+
+const Frame makeBinding(const Frame& frameSoFar, const list<value>& variables, const list<value> values) {
+ if (isNil(variables)) {
+ if (!isNil(values))
+ logStream() << "Too many arguments supplied " << values << endl;
+ return frameSoFar;
+ }
+ if (isDotVariable(car(variables)))
+ return makeBinding(frameSoFar, cdr(variables), mklist<value>(values));
+
+ if (isNil(values)) {
+ if (!isNil(variables))
+ logStream() << "Too few arguments supplied " << variables << endl;
+ return frameSoFar;
+ }
+
+ const list<value> vars = cons(car(variables), frameVariables(frameSoFar));
+ const list<value> vals = cons(car(values), frameValues(frameSoFar));
+ const Frame newFrame = cons(value(vars), vals);
+
+ return makeBinding(newFrame, cdr(variables), cdr(values));
+}
+
+const gc_ptr<Frame> makeFrame(const list<value>& variables, const list<value> values) {
+ gc_ptr<Frame> frame = new (gc_new<Frame>()) Frame();
+ *frame = value(makeBinding(cons(value(list<value>()), list<value>()), variables, values));
+ return frame;
+}
+
+const value definitionVariable(const value& exp) {
+ const list<value> exps(exp);
+ if(isSymbol(car(cdr(exps))))
+ return car(cdr(exps));
+ const list<value> lexps(car(cdr(exps)));
+ return car(lexps);
+}
+
+const value definitionValue(const value& exp) {
+ const list<value> exps(exp);
+ if(isSymbol(car(cdr(exps))))
+ return car(cdr(cdr(exps)));
+ const list<value> lexps(car(cdr(exps)));
+ return makeLambda(cdr(lexps), cdr(cdr(exps)));
+}
+
+const value assignmentVariable(const value& exp) {
+ return car(cdr((list<value> )exp));
+}
+
+const value assignmentValue(const value& exp) {
+ return car(cdr(cdr((list<value> )exp)));
+}
+
+const Frame addBindingToFrame(const value& var, const value& val, const Frame& frame) {
+ return cons(value(cons(var, frameVariables(frame))), cons(val, frameValues(frame)));
+}
+
+const bool defineVariable(const value& var, const value& val, Env& env) {
+ *firstFrame(env) = addBindingToFrame(var, val, *firstFrame(env));
+ return true;
+}
+
+const Env extendEnvironment(const list<value>& vars, const list<value>& vals, const Env& baseEnv) {
+ return cons<value>(makeFrame(vars, vals), baseEnv);
+}
+
+const Env setupEnvironment() {
+ Env env = extendEnvironment(primitiveProcedureNames(), primitiveProcedureObjects(), theEmptyEnvironment());
+ defineVariable(trueSymbol, true, env);
+ defineVariable(falseSymbol, false, env);
+ return env;
+}
+
+const value lookupEnvLoop(const value& var, const Env& env);
+
+const value lookupEnvScan(const value& var, const list<value>& vars, const list<value>& vals, const Env& env) {
+ if(isNil(vars))
+ return lookupEnvLoop(var, enclosingEnvironment(env));
+ if(var == car(vars))
+ return car(vals);
+ return lookupEnvScan(var, cdr(vars), cdr(vals), env);
+}
+
+const value lookupEnvLoop(const value& var, const Env& env) {
+ if(env == theEmptyEnvironment()) {
+ logStream() << "Unbound variable " << var << endl;
+ return value();
+ }
+ return lookupEnvScan(var, frameVariables(*firstFrame(env)), frameValues(*firstFrame(env)), env);
+}
+
+const value lookupVariableValue(const value& var, const Env& env) {
+ return lookupEnvLoop(var, env);
+}
+
+}
+}
+#endif /* tuscany_scheme_environment_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/scheme/eval-shell.cpp b/sca-cpp/branches/gcc-4.4/modules/scheme/eval-shell.cpp
new file mode 100644
index 0000000000..4aa67c2375
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/scheme/eval-shell.cpp
@@ -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.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Script evaluator shell, used for interactive testing of scripts.
+ */
+
+#include <assert.h>
+#include "gc.hpp"
+#include "stream.hpp"
+#include "string.hpp"
+#include "driver.hpp"
+
+int main() {
+ tuscany::gc_scoped_pool pool;
+ tuscany::scheme::evalDriverRun(tuscany::cin, tuscany::cout);
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/scheme/eval-test.cpp b/sca-cpp/branches/gcc-4.4/modules/scheme/eval-test.cpp
new file mode 100644
index 0000000000..7c4c0c69c4
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/scheme/eval-test.cpp
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Test script evaluator.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "driver.hpp"
+
+namespace tuscany {
+namespace scheme {
+
+bool testEnv() {
+ gc_scoped_pool pool;
+ Env globalEnv = list<value>();
+ Env env = extendEnvironment(mklist<value>("a"), mklist<value>(1), globalEnv);
+ defineVariable("x", env, env);
+ assert(lookupVariableValue(value("x"), env) == env);
+ assert(lookupVariableValue("a", env) == value(1));
+ return true;
+}
+
+bool testEnvGC() {
+ resetLambdaCounters();
+ resetListCounters();
+ resetValueCounters();
+ testEnv();
+ assert(checkValueCounters());
+ assert(checkLambdaCounters());
+ assert(checkListCounters());
+ return true;
+}
+
+bool testRead() {
+ istringstream is("abcd");
+ assert(readValue(is) == "abcd");
+
+ istringstream is2("123");
+ assert(readValue(is2) == value(123));
+
+ istringstream is3("(abcd)");
+ assert(readValue(is3) == mklist(value("abcd")));
+
+ istringstream is4("(abcd xyz)");
+ assert(readValue(is4) == mklist<value>("abcd", "xyz"));
+
+ istringstream is5("(abcd (xyz tuv))");
+ assert(readValue(is5) == mklist<value>("abcd", mklist<value>("xyz", "tuv")));
+
+ return true;
+}
+
+bool testWrite() {
+ const list<value> i = list<value>()
+ + (list<value>() + "item" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"
+ + (list<value>() + "item"
+ + (list<value>() + "name" + "Apple")
+ + (list<value>() + "price" + "$2.99")))
+ + (list<value>() + "item" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c"
+ + (list<value>() + "item"
+ + (list<value>() + "name" + "Orange")
+ + (list<value>() + "price" + "$3.55")));
+ const list<value> a = cons<value>("Feed", cons<value>("feed-1234", i));
+ ostringstream os;
+ writeValue(a, os);
+ istringstream is(str(os));
+ assert(readValue(is) == a);
+ return true;
+}
+
+const string testSchemeNumber(
+ "(define (testNumber) (if (= 1 1) (display \"testNumber ok\") (error \"testNumber\"))) "
+ "(testNumber)");
+
+const string testSchemeString(
+ "(define (testString) (if (= \"abc\" \"abc\") (display \"testString ok\") (error \"testString\"))) "
+ "(testString)");
+
+const string testSchemeDefinition(
+ "(define a \"abc\") (define (testDefinition) (if (= a \"abc\") (display \"testDefinition ok\") (error \"testDefinition\"))) "
+ "(testDefinition)");
+
+const string testSchemeIf(
+ "(define (testIf) (if (= \"abc\" \"abc\") (if (= \"xyz\" \"xyz\") (display \"testIf ok\") (error \"testNestedIf\")) (error \"testIf\"))) "
+ "(testIf)");
+
+const string testSchemeCond(
+ "(define (testCond) (cond ((= \"abc\" \"abc\") (display \"testCond ok\")) (else (error \"testIf\"))))"
+ "(testCond)");
+
+const string testSchemeBegin(
+ "(define (testBegin) "
+ "(begin "
+ "(define a \"abc\") "
+ "(if (= a \"abc\") (display \"testBegin1 ok\") (error \"testBegin\")) "
+ "(define x \"xyz\") "
+ "(if (= x \"xyz\") (display \"testBegin2 ok\") (error \"testBegin\")) "
+ ") "
+ ") "
+ "(testBegin)");
+
+const string testSchemeLambda(
+ "(define sqrt (lambda (x) (* x x))) "
+ "(define (testLambda) (if (= 4 (sqrt 2)) (display \"testLambda ok\") (error \"testLambda\"))) "
+ "(testLambda)");
+
+const string testSchemeForward(
+ "(define (testLambda) (if (= 4 (sqrt 2)) (display \"testForward ok\") (error \"testForward\"))) "
+ "(define sqrt (lambda (x) (* x x))) "
+ "(testLambda)");
+
+const string evalOutput(const string& scm) {
+ istringstream is(scm);
+ ostringstream os;
+ evalDriverRun(is, os);
+ return str(os);
+}
+
+bool testEval() {
+ gc_scoped_pool pool;
+ assert(contains(evalOutput(testSchemeNumber), "testNumber ok"));
+ assert(contains(evalOutput(testSchemeString), "testString ok"));
+ assert(contains(evalOutput(testSchemeDefinition), "testDefinition ok"));
+ assert(contains(evalOutput(testSchemeIf), "testIf ok"));
+ assert(contains(evalOutput(testSchemeCond), "testCond ok"));
+ assert(contains(evalOutput(testSchemeBegin), "testBegin1 ok"));
+ assert(contains(evalOutput(testSchemeBegin), "testBegin2 ok"));
+ assert(contains(evalOutput(testSchemeLambda), "testLambda ok"));
+ assert(contains(evalOutput(testSchemeForward), "testForward ok"));
+ return true;
+}
+
+bool testEvalExpr() {
+ gc_scoped_pool pool;
+ const value exp = mklist<value>("+", 2, 3);
+ Env env = setupEnvironment();
+ const value r = evalExpr(exp, env);
+ assert(r == value(5));
+ return true;
+}
+
+bool testEvalRun() {
+ gc_scoped_pool pool;
+ evalDriverRun(cin, cout);
+ return true;
+}
+
+const value mult(const list<value>& args) {
+ const double x = car(args);
+ const double y = cadr(args);
+ return x * y;
+}
+
+const string testReturnLambda(
+ "(define (testReturnLambda) * )");
+
+const string testCallLambda(
+ "(define (testCallLambda l x y) (l x y))");
+
+bool testEvalLambda() {
+ gc_scoped_pool pool;
+ Env env = setupEnvironment();
+
+ const value trl = mklist<value>("testReturnLambda");
+ istringstream trlis(testReturnLambda);
+ const value trlv = evalScript(trl, trlis, env);
+
+ istringstream tclis(testCallLambda);
+ const value tcl = cons<value>("testCallLambda", quotedParameters(mklist<value>(trlv, 2, 3)));
+ const value tclv = evalScript(tcl, tclis, env);
+ assert(tclv == value(6));
+
+ istringstream tcelis(testCallLambda);
+ const value tcel = cons<value>("testCallLambda", quotedParameters(mklist<value>(primitiveProcedure(mult), 3, 4)));
+ const value tcelv = evalScript(tcel, tcelis, env);
+ assert(tcelv == value(12));
+ return true;
+}
+
+bool testEvalGC() {
+ resetLambdaCounters();
+ resetListCounters();
+ resetValueCounters();
+ testEval();
+ testEvalExpr();
+ testEvalLambda();
+ assert(checkValueCounters());
+ assert(checkLambdaCounters());
+ assert(checkListCounters());
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::scheme::testEnv();
+ tuscany::scheme::testEnvGC();
+ tuscany::scheme::testRead();
+ tuscany::scheme::testWrite();
+ tuscany::scheme::testEval();
+ tuscany::scheme::testEvalExpr();
+ tuscany::scheme::testEvalLambda();
+ tuscany::scheme::testEvalGC();
+
+ tuscany::cout << "OK" << tuscany::endl;
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/scheme/eval.hpp b/sca-cpp/branches/gcc-4.4/modules/scheme/eval.hpp
new file mode 100644
index 0000000000..34d1a7bc17
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/scheme/eval.hpp
@@ -0,0 +1,290 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_scheme_eval_hpp
+#define tuscany_scheme_eval_hpp
+
+/**
+ * Core script evaluation logic.
+ */
+
+#include <string.h>
+#include "list.hpp"
+#include "value.hpp"
+#include "primitive.hpp"
+#include "io.hpp"
+#include "environment.hpp"
+
+namespace tuscany {
+namespace scheme {
+
+const value evalExpr(const value& exp, Env& env);
+
+const value compoundProcedureSymbol("compound-procedure");
+const value procedureSymbol("procedure");
+const value applySymbol("apply");
+const value beginSymbol("begin");
+const value condSymbol("cond");
+const value elseSymbol("else");
+const value ifSymbol("if");
+
+const bool isBegin(const value& exp) {
+ return isTaggedList(exp, beginSymbol);
+}
+
+const list<value> beginActions(const value& exp) {
+ return cdr((list<value> )exp);
+}
+
+const bool isLambdaExpr(const value& exp) {
+ return isTaggedList(exp, lambdaSymbol);
+}
+
+const list<value> lambdaParameters(const value& exp) {
+ return car(cdr((list<value> )exp));
+}
+
+static list<value> lambdaBody(const value& exp) {
+ return cdr(cdr((list<value> )exp));
+}
+
+const value makeProcedure(const list<value>& parameters, const value& body, const Env& env) {
+ return mklist<value>(procedureSymbol, parameters, body, env);
+}
+
+const bool isApply(const value& exp) {
+ return isTaggedList(exp, applySymbol);
+}
+
+const bool isApplication(const value& exp) {
+ return isList(exp);
+}
+
+const value operat(const value& exp) {
+ return car((list<value> )exp);
+}
+
+const list<value> operands(const value& exp) {
+ return cdr((list<value> )exp);
+}
+
+const list<value> listOfValues(const list<value> exps, Env& env) {
+ if(isNil(exps))
+ return list<value> ();
+ return cons(evalExpr(car(exps), env), listOfValues(cdr(exps), env));
+}
+
+const value applyOperat(const value& exp) {
+ return cadr((list<value> )exp);
+}
+
+const value applyOperand(const value& exp) {
+ return caddr((list<value> )exp);
+}
+
+const bool isCompoundProcedure(const value& procedure) {
+ return isTaggedList(procedure, procedureSymbol);
+}
+
+const list<value> procedureParameters(const value& exp) {
+ return car(cdr((list<value> )exp));
+}
+
+const value procedureBody(const value& exp) {
+ return car(cdr(cdr((list<value> )exp)));
+}
+
+const Env procedureEnvironment(const value& exp) {
+ return (Env)car(cdr(cdr(cdr((list<value> )exp))));
+}
+
+const bool isLastExp(const list<value>& seq) {
+ return isNil(cdr(seq));
+}
+
+const value firstExp(const list<value>& seq) {
+ return car(seq);
+}
+
+const list<value> restExp(const list<value>& seq) {
+ return cdr(seq);
+}
+
+const value makeBegin(const list<value> seq) {
+ return cons(beginSymbol, seq);
+}
+
+const value evalSequence(const list<value>& exps, Env& env) {
+ if(isLastExp(exps))
+ return evalExpr(firstExp(exps), env);
+ evalExpr(firstExp(exps), env);
+ return evalSequence(restExp(exps), env);
+}
+
+const value applyProcedure(const value& procedure, list<value>& arguments) {
+ if(isPrimitiveProcedure(procedure))
+ return applyPrimitiveProcedure(procedure, arguments);
+ if(isCompoundProcedure(procedure)) {
+ Env env = extendEnvironment(procedureParameters(procedure), arguments, procedureEnvironment(procedure));
+ return evalSequence(procedureBody(procedure), env);
+ }
+ logStream() << "Unknown procedure type " << procedure << endl;
+ return value();
+}
+
+const value sequenceToExp(const list<value> exps) {
+ if(isNil(exps))
+ return exps;
+ if(isLastExp(exps))
+ return firstExp(exps);
+ return makeBegin(exps);
+}
+
+const list<value> condClauses(const value& exp) {
+ return cdr((list<value> )exp);
+}
+
+const value condPredicate(const value& clause) {
+ return car((list<value> )clause);
+}
+
+const list<value> condActions(const value& clause) {
+ return cdr((list<value> )clause);
+}
+
+const value ifPredicate(const value& exp) {
+ return car(cdr((list<value> )exp));
+}
+
+const value ifConsequent(const value& exp) {
+ return car(cdr(cdr((list<value> )exp)));
+}
+
+const value ifAlternative(const value& exp) {
+ if(!isNil(cdr(cdr(cdr((list<value> )exp)))))
+ return car(cdr(cdr(cdr((list<value> )exp))));
+ return false;
+}
+
+const bool isCond(const value& exp) {
+ return isTaggedList(exp, condSymbol);
+}
+
+const bool isCondElseClause(const value& clause) {
+ return condPredicate(clause) == elseSymbol;
+}
+
+const bool isIf(const value& exp) {
+ return isTaggedList(exp, ifSymbol);
+}
+
+const value makeIf(value predicate, value consequent, value alternative) {
+ return mklist(ifSymbol, predicate, consequent, alternative);
+}
+
+const value expandClauses(const list<value>& clauses) {
+ if(isNil(clauses))
+ return false;
+ const value first = car(clauses);
+ const list<value> rest = cdr(clauses);
+ if(isCondElseClause(first)) {
+ if(isNil(rest))
+ return sequenceToExp(condActions(first));
+ logStream() << "else clause isn't last " << clauses << endl;
+ return value();
+ }
+ return makeIf(condPredicate(first), sequenceToExp(condActions(first)), expandClauses(rest));
+}
+
+value condToIf(const value& exp) {
+ return expandClauses(condClauses(exp));
+}
+
+value evalIf(const value& exp, Env& env) {
+ if(isTrue(evalExpr(ifPredicate(exp), env)))
+ return evalExpr(ifConsequent(exp), env);
+ return evalExpr(ifAlternative(exp), env);
+}
+
+const value evalDefinition(const value& exp, Env& env) {
+ defineVariable(definitionVariable(exp), evalExpr(definitionValue(exp), env), env);
+ return definitionVariable(exp);
+}
+
+const value evalExpr(const value& exp, Env& env) {
+ if(isSelfEvaluating(exp))
+ return exp;
+ if(isQuoted(exp))
+ return textOfQuotation(exp);
+ if(isDefinition(exp))
+ return evalDefinition(exp, env);
+ if(isIf(exp))
+ return evalIf(exp, env);
+ if(isBegin(exp))
+ return evalSequence(beginActions(exp), env);
+ if(isCond(exp))
+ return evalExpr(condToIf(exp), env);
+ if(isLambdaExpr(exp))
+ return makeProcedure(lambdaParameters(exp), lambdaBody(exp), env);
+ if(isVariable(exp))
+ return lookupVariableValue(exp, env);
+ if(isApply(exp)) {
+ list<value> applyOperandValues = evalExpr(applyOperand(exp), env);
+ return applyProcedure(evalExpr(applyOperat(exp), env), applyOperandValues);
+ }
+ if(isApplication(exp)) {
+ list<value> operandValues = listOfValues(operands(exp), env);
+ return applyProcedure(evalExpr(operat(exp), env), operandValues);
+ }
+ logStream() << "Unknown expression type " << exp << endl;
+ return value();
+}
+
+const list<value> quotedParameters(const list<value>& p) {
+ if (isNil(p))
+ return p;
+ return cons<value>(mklist<value>(quoteSymbol, car(p)), quotedParameters(cdr(p)));
+}
+
+/**
+ * Evaluate an expression against a script provided as a list of values.
+ */
+const value evalScriptLoop(const value& expr, const list<value>& script, scheme::Env& env) {
+ if (isNil(script))
+ return scheme::evalExpr(expr, env);
+ scheme::evalExpr(car(script), env);
+ return evalScriptLoop(expr, cdr(script), env);
+}
+
+const value evalScript(const value& expr, const value& script, Env& env) {
+ return evalScriptLoop(expr, script, env);
+}
+
+/**
+ * Evaluate an expression against a script provided as an input stream.
+ */
+const value evalScript(const value& expr, istream& is, Env& env) {
+ return evalScript(expr, readScript(is), env);
+}
+
+}
+}
+#endif /* tuscany_scheme_eval_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/scheme/io.hpp b/sca-cpp/branches/gcc-4.4/modules/scheme/io.hpp
new file mode 100644
index 0000000000..5e5397cfeb
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/scheme/io.hpp
@@ -0,0 +1,217 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_scheme_io_hpp
+#define tuscany_scheme_io_hpp
+
+/**
+ * Script evaluator IO functions.
+ */
+
+#include <ctype.h>
+#include "stream.hpp"
+#include "string.hpp"
+
+#include "list.hpp"
+#include "value.hpp"
+#include "primitive.hpp"
+
+namespace tuscany {
+namespace scheme {
+
+const value rightParenthesis(mklist<value>(")"));
+const value leftParenthesis(mklist<value>("("));
+const value comment(mklist<value>(";"));
+
+const double stringToNumber(const string& str) {
+ return atof(c_str(str));
+}
+
+const bool isWhitespace(const char ch) {
+ return ch != -1 && isspace(ch);
+}
+
+const bool isIdentifierStart(const char ch) {
+ return ch != -1 && !isspace(ch) && !isdigit(ch);
+}
+
+const bool isIdentifierPart(const char ch) {
+ return ch != -1 && !isspace(ch) && ch != '(' && ch != ')';
+}
+
+const bool isDigit(const char ch) {
+ return isdigit(ch) || ch == '.';
+}
+
+const bool isLeftParenthesis(const value& token) {
+ return leftParenthesis == token;
+}
+
+const bool isRightParenthesis(const value& token) {
+ return rightParenthesis == token;
+}
+
+const char readChar(istream& in) {
+ if(in.eof()) {
+ return -1;
+ }
+ char c = (char)get(in);
+ return c;
+}
+
+const char peekChar(istream& in) {
+ if(eof(in))
+ return -1;
+ char c = (char)peek(in);
+ return c;
+}
+
+const bool isQuote(const value& token) {
+ return token == quoteSymbol;
+}
+
+const value skipComment(istream& in);
+const value readQuoted(istream& in);
+const value readIdentifier(const char chr, istream& in);
+const value readString(istream& in);
+const value readNumber(const char chr, istream& in);
+const value readValue(istream& in);
+
+const value readToken(istream& in) {
+ const char firstChar = readChar(in);
+ if(isWhitespace(firstChar))
+ return readToken(in);
+ if(firstChar == ';')
+ return skipComment(in);
+ if(firstChar == '\'')
+ return readQuoted(in);
+ if(firstChar == '(')
+ return leftParenthesis;
+ if(firstChar == ')')
+ return rightParenthesis;
+ if(firstChar == '"')
+ return readString(in);
+ if(isIdentifierStart(firstChar))
+ return readIdentifier(firstChar, in);
+ if(isDigit(firstChar))
+ return readNumber(firstChar, in);
+ if(firstChar == -1)
+ return value();
+ logStream() << "Illegal lexical syntax '" << firstChar << "'" << endl;
+ return readToken(in);
+}
+
+const value skipComment(istream& in) {
+ const char nextChar = readChar(in);
+ if (nextChar == '\n')
+ return readToken(in);
+ return skipComment(in);
+}
+
+const value readQuoted(istream& in) {
+ return mklist(quoteSymbol, readValue(in));
+}
+
+const list<value> readList(const list<value>& listSoFar, istream& in) {
+ const value token = readToken(in);
+ if(isNil(token) || isRightParenthesis(token))
+ return reverse(listSoFar);
+ if(isLeftParenthesis(token))
+ return readList(cons(value(readList(list<value> (), in)), listSoFar), in);
+ return readList(cons(token, listSoFar), in);
+}
+
+const string listToString(const list<char>& l) {
+ if(isNil(l))
+ return "";
+ const char buf[1] = { car(l) };
+ return string(buf, 1) + listToString(cdr(l));
+}
+
+const list<char> readIdentifierHelper(const list<char>& listSoFar, istream& in) {
+ const char nextChar = peekChar(in);
+ if(isIdentifierPart(nextChar))
+ return readIdentifierHelper(cons(readChar(in), listSoFar), in);
+ return reverse(listSoFar);
+}
+
+const value readIdentifier(const char chr, istream& in) {
+ return c_str(listToString(readIdentifierHelper(mklist(chr), in)));
+}
+
+const list<char> readStringHelper(const list<char>& listSoFar, istream& in) {
+ const char nextChar = readChar(in);
+ if(nextChar != -1 && nextChar != '"')
+ return readStringHelper(cons(nextChar, listSoFar), in);
+ return reverse(listSoFar);
+}
+
+const value readString(istream& in) {
+ return listToString(readStringHelper(list<char>(), in));
+}
+
+const list<char> readNumberHelper(const list<char>& listSoFar, istream& in) {
+ const char nextChar = peekChar(in);
+ if(isDigit(nextChar))
+ return readNumberHelper(cons(readChar(in), listSoFar), in);
+ return reverse(listSoFar);
+}
+
+const value readNumber(const char chr, istream& in) {
+ return stringToNumber(listToString(readNumberHelper(mklist(chr), in)));
+}
+
+const value readValue(istream& in) {
+ const value nextToken = readToken(in);
+ if(isLeftParenthesis(nextToken))
+ return readList(list<value> (), in);
+ return nextToken;
+}
+
+const value readValue(const string s) {
+ istringstream in(s);
+ const value nextToken = readToken(in);
+ if(isLeftParenthesis(nextToken))
+ return readList(list<value> (), in);
+ return nextToken;
+}
+
+const bool writeValue(const value& val, ostream& out) {
+ out << val;
+ return true;
+}
+
+const string writeValue(const value& val) {
+ ostringstream out;
+ out << val;
+ return str(out);
+}
+
+const value readScript(istream& in) {
+ const value val = readValue(in);
+ if (isNil(val))
+ return list<value>();
+ return cons(val, (list<value>)readScript(in));
+}
+
+}
+}
+#endif /* tuscany_scheme_io_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/scheme/primitive.hpp b/sca-cpp/branches/gcc-4.4/modules/scheme/primitive.hpp
new file mode 100644
index 0000000000..fd5f3e9755
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/scheme/primitive.hpp
@@ -0,0 +1,285 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_scheme_primitive_hpp
+#define tuscany_scheme_primitive_hpp
+
+/**
+ * Script evaluator primitive functions.
+ */
+
+#include <apr_general.h>
+#include <apr_uuid.h>
+#include "stream.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+
+namespace tuscany {
+namespace scheme {
+
+const value primitiveSymbol("primitive");
+const value quoteSymbol("'");
+const value lambdaSymbol("lambda");
+
+#ifdef WANT_THREADS
+__thread
+#endif
+ostream* displayOutStream = NULL;
+
+#ifdef WANT_THREADS
+__thread
+#endif
+ostream* logOutStream = NULL;
+
+const bool setupDisplay(ostream& out) {
+ displayOutStream = &out;
+ return true;
+}
+
+ostream& displayStream() {
+ if (displayOutStream == NULL)
+ return cout;
+ return *displayOutStream;
+}
+
+const bool setupLog(ostream& out) {
+ logOutStream = &out;
+ return true;
+}
+
+ostream& logStream() {
+ if (logOutStream == NULL)
+ return cerr;
+ return *logOutStream;
+}
+
+const value carProc(const list<value>& args) {
+ return car((list<value> )car(args));
+}
+
+const value cdrProc(const list<value>& args) {
+ return cdr((list<value> )car(args));
+}
+
+const value consProc(const list<value>& args) {
+ return cons(car(args), (list<value> )cadr(args));
+}
+
+const value listProc(const list<value>& args) {
+ return args;
+}
+
+const value assocProc(const list<value>& args) {
+ return assoc(car(args), (list<list<value> >)cadr(args));
+}
+
+const value nulProc(const list<value>& args) {
+ const value v(car(args));
+ if (isNil(v))
+ return true;
+ if (isList(v))
+ return isNil(list<value>(v));
+ return false;
+}
+
+const value equalProc(const list<value>& args) {
+ return (bool)(car(args) == cadr(args));
+}
+
+const value addProc(const list<value>& args) {
+ if (isNil(cdr(args)))
+ return (double)car(args);
+ return (double)car(args) + (double)cadr(args);
+}
+
+const value subProc(const list<value>& args) {
+ if (isNil(cdr(args)))
+ return (double)0 - (double)car(args);
+ return (double)car(args) - (double)cadr(args);
+}
+
+const value mulProc(const list<value>& args) {
+ return (double)car(args) * (double)cadr(args);
+}
+
+const value divProc(const list<value>& args) {
+ return (double)car(args) / (double)cadr(args);
+}
+
+const value displayProc(const list<value>& args) {
+ if (isNil(args)) {
+ displayStream() << endl;
+ return true;
+ }
+ displayStream() << car(args);
+ return displayProc(cdr(args));
+}
+
+const value logProc(const list<value>& args) {
+ if (isNil(args)) {
+ logStream() << endl;
+ return true;
+ }
+ logStream() << car(args);
+ return logProc(cdr(args));
+}
+
+const value uuidProc(unused const list<value>& args) {
+ apr_uuid_t uuid;
+ apr_uuid_get(&uuid);
+ char buf[APR_UUID_FORMATTED_LENGTH];
+ apr_uuid_format(buf, &uuid);
+ return string(buf, APR_UUID_FORMATTED_LENGTH);
+}
+
+const value cadrProc(unused const list<value>& args) {
+ return cadr((list<value> )car(args));
+}
+
+const value caddrProc(unused const list<value>& args) {
+ return caddr((list<value> )car(args));
+}
+
+const value cadddrProc(unused const list<value>& args) {
+ return cadddr((list<value> )car(args));
+}
+
+const value cddrProc(unused const list<value>& args) {
+ return cddr((list<value> )car(args));
+}
+
+const value cdddrProc(unused const list<value>& args) {
+ return cdddr((list<value> )car(args));
+}
+
+const value startProc(unused const list<value>& args) {
+ return lambda<value(const list<value>&)>();
+}
+
+const value stopProc(unused const list<value>& args) {
+ return lambda<value(const list<value>&)>();
+}
+
+const value applyPrimitiveProcedure(const value& proc, list<value>& args) {
+ const lambda<value(const list<value>&)> func(cadr((list<value>)proc));
+ return func(args);
+}
+
+const bool isPrimitiveProcedure(const value& proc) {
+ return isTaggedList(proc, primitiveSymbol);
+}
+
+const bool isSelfEvaluating(const value& exp) {
+ if(isNil(exp))
+ return true;
+ if(isNumber(exp))
+ return true;
+ if(isString(exp))
+ return true;
+ if(isBool(exp))
+ return true;
+ if(isLambda(exp))
+ return true;
+ return false;
+}
+
+const value primitiveImplementation(const list<value>& proc) {
+ return car(cdr(proc));
+}
+
+template<typename F> const value primitiveProcedure(const F& f) {
+ return mklist<value>(primitiveSymbol, (lambda<value(const list<value>&)>)f);
+}
+
+const list<value> primitiveProcedureNames() {
+ return mklist<value>("car")
+ + "cdr"
+ + "cons"
+ + "list"
+ + "nul"
+ + "="
+ + "equal?"
+ + "+"
+ + "-"
+ + "*"
+ + "/"
+ + "assoc"
+ + "cadr"
+ + "caddr"
+ + "cadddr"
+ + "cddr"
+ + "cdddr"
+ + "display"
+ + "log"
+ + "uuid"
+ + "start"
+ + "stop";
+}
+
+const list<value> primitiveProcedureObjects() {
+ return mklist(primitiveProcedure(carProc))
+ + primitiveProcedure(cdrProc)
+ + primitiveProcedure(consProc)
+ + primitiveProcedure(listProc)
+ + primitiveProcedure(nulProc)
+ + primitiveProcedure(equalProc)
+ + primitiveProcedure(equalProc)
+ + primitiveProcedure(addProc)
+ + primitiveProcedure(subProc)
+ + primitiveProcedure(mulProc)
+ + primitiveProcedure(divProc)
+ + primitiveProcedure(assocProc)
+ + primitiveProcedure(cadrProc)
+ + primitiveProcedure(caddrProc)
+ + primitiveProcedure(cadddrProc)
+ + primitiveProcedure(cddrProc)
+ + primitiveProcedure(cdddrProc)
+ + primitiveProcedure(displayProc)
+ + primitiveProcedure(logProc)
+ + primitiveProcedure(uuidProc)
+ + primitiveProcedure(startProc)
+ + primitiveProcedure(stopProc);
+}
+
+const bool isFalse(const value& exp) {
+ return (bool)exp == false;
+}
+
+const bool isTrue(const value& exp) {
+ return (bool)exp == true;
+}
+
+const bool isQuoted(const value& exp) {
+ return isTaggedList(exp, quoteSymbol);
+}
+
+const value textOfQuotation(const value& exp) {
+ return car(cdr((list<value> )exp));
+}
+
+const value makeLambda(const list<value>& parameters, const list<value>& body) {
+ return cons(lambdaSymbol, cons<value>(parameters, body));
+}
+
+}
+}
+#endif /* tuscany_scheme_primitive_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/scheme/tuscany-sca-1.1-implementation-scheme.xsd b/sca-cpp/branches/gcc-4.4/modules/scheme/tuscany-sca-1.1-implementation-scheme.xsd
new file mode 100644
index 0000000000..5b32834832
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/scheme/tuscany-sca-1.1-implementation-scheme.xsd
@@ -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.
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/1.1"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ elementFormDefault="qualified">
+
+ <import namespace="http://docs.oasis-open.org/ns/opencsa/sca/200912" schemaLocation="sca-1.1-cd04.xsd"/>
+
+ <element name="implementation.scheme" type="t:SchemeImplementation" substitutionGroup="sca:implementation"/>
+
+ <complexType name="SchemeImplementation">
+ <complexContent>
+ <extension base="sca:Implementation">
+ <sequence>
+ <any namespace="##targetNamespace" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="script" type="anyURI" use="required"/>
+ <anyAttribute namespace="##any" processContents="lax"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/Makefile.am b/sca-cpp/branches/gcc-4.4/modules/server/Makefile.am
new file mode 100644
index 0000000000..06323aad05
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/Makefile.am
@@ -0,0 +1,46 @@
+# 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.
+
+INCLUDES = -I${HTTPD_INCLUDE}
+
+mod_SCRIPTS = cpp-conf scheme-conf server-conf
+moddir = $(prefix)/modules/server
+
+lib_LTLIBRARIES = libmod_tuscany_eval.la libmod_tuscany_wiring.la
+libdir = $(prefix)/modules/server
+noinst_DATA = libmod_tuscany_eval.so libmod_tuscany_wiring.so
+
+libmod_tuscany_eval_la_SOURCES = mod-eval.cpp
+libmod_tuscany_eval_la_LDFLAGS = -lxml2 -lcurl -lmozjs
+libmod_tuscany_eval.so:
+ ln -s .libs/libmod_tuscany_eval.so libmod_tuscany_eval.so
+
+libmod_tuscany_wiring_la_SOURCES = mod-wiring.cpp
+libmod_tuscany_wiring_la_LDFLAGS = -lxml2 -lcurl -lmozjs
+libmod_tuscany_wiring.so:
+ ln -s .libs/libmod_tuscany_wiring.so libmod_tuscany_wiring.so
+
+noinst_testdir = $(prefix)/test
+noinst_test_LTLIBRARIES = libimpl-test.la
+libimpl_test_la_SOURCES = impl-test.cpp
+
+client_test_SOURCES = client-test.cpp
+client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+
+noinst_PROGRAMS = client-test
+TESTS = httpd-test server-test wiring-test
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/client-test.cpp b/sca-cpp/branches/gcc-4.4/modules/server/client-test.cpp
new file mode 100644
index 0000000000..5de7ab6e7b
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/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() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+ tuscany::server::testURI = "http://localhost:8090/test";
+
+ tuscany::server::testServer();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/client-test.hpp b/sca-cpp/branches/gcc-4.4/modules/server/client-test.hpp
new file mode 100644
index 0000000000..9b37a73803
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/client-test.hpp
@@ -0,0 +1,350 @@
+/*
+ * 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 "../http/curl.hpp"
+
+namespace tuscany {
+namespace server {
+
+string testURI = "http://localhost:8090/test";
+bool testBlobs = true;
+
+ostream* curlWriter(const string& s, ostream* os) {
+ (*os) << s;
+ return os;
+}
+
+const bool testGet() {
+ gc_scoped_pool pool;
+ http::CURLSession ch;
+ {
+ ostringstream os;
+ const failable<list<ostream*> > r = http::get<ostream*>(curlWriter, &os, "http://localhost:8090/index.html", ch);
+ assert(hasContent(r));
+ assert(contains(str(os), "HTTP/1.1 200") || contains(str(os), "HTTP/1.0 200"));
+ assert(contains(str(os), "It works"));
+ }
+ {
+ const failable<value> r = http::getcontent("http://localhost:8090/index.html", ch);
+ assert(hasContent(r));
+ assert(contains(car(reverse(list<value>(content(r)))), "It works"));
+ }
+ return true;
+}
+
+struct getLoop {
+ http::CURLSession ch;
+ getLoop(http::CURLSession& ch) : ch(ch) {
+ }
+ const bool operator()() const {
+ const failable<value> r = http::getcontent("http://localhost:8090/index.html", ch);
+ assert(hasContent(r));
+ assert(contains(car(reverse(list<value>(content(r)))), "It works"));
+ return true;
+ }
+};
+
+const bool testGetPerf() {
+ gc_scoped_pool pool;
+ http::CURLSession ch;
+ const lambda<bool()> gl = getLoop(ch);
+ cout << "Static GET test " << time(gl, 5, 200) << " ms" << endl;
+ return true;
+}
+
+const bool testEval() {
+ gc_scoped_pool pool;
+ http::CURLSession ch;
+ const value val = content(http::evalExpr(mklist<value>(string("echo"), string("Hello")), testURI, ch));
+ assert(val == 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 value val = content(http::evalExpr(mklist<value>(string("echo"), string("Hello")), uri, ch));
+ assert(val == 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 value val = content(http::evalExpr(mklist<value>(string("echo"), blobs), uri, ch));
+ assert(val == blobs);
+ return true;
+ }
+};
+
+const bool testEvalPerf() {
+ gc_scoped_pool pool;
+ http::CURLSession ch;
+ 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>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99"));
+ const list<value> a = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
+ http::CURLSession ch;
+ 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;
+ {
+ const list<value> i = list<value>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99"));
+ const list<value> val = mklist<value>(string("item"), 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>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "blob1" + blob)
+ + (list<value>() + "blob2" + blob)
+ + (list<value>() + "price" + string("$2.99"));
+ const list<value> val = mklist<value>(string("item"), 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;
+ 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;
+ const int threads;
+ const gc_ptr<worker> w;
+ postThreadLoop(const lambda<bool()>& l, const int threads) : l(l), threads(threads), w(new (gc_new<worker>()) worker(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;
+
+ const list<value> i = list<value>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99"));
+ const value val = mklist<value>(string("item"), 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, 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;
+ 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>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99"));
+ const value val = mklist<value>(string("item"), 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>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99"));
+ const list<value> a = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
+ http::CURLSession ch;
+ 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;
+ value rc = content(http::del(testURI + "/111", ch));
+ assert(rc == value(true));
+ return true;
+}
+
+const bool testServer() {
+ tuscany::server::testGet();
+ tuscany::server::testPost();
+ tuscany::server::testPut();
+ tuscany::server::testDel();
+ tuscany::server::testEval();
+ tuscany::server::testGetPerf();
+ tuscany::server::testPostPerf();
+#ifdef WANT_THREADS
+ tuscany::server::testPostThreadPerf();
+#else
+ tuscany::server::testPostForkPerf();
+#endif
+ tuscany::server::testEvalPerf();
+ return true;
+}
+
+}
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/client-test.scm b/sca-cpp/branches/gcc-4.4/modules/server/client-test.scm
new file mode 100644
index 0000000000..47b799d390
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/client-test.scm
@@ -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.
+
+; JSON-RPC test case
+
+(define (echo x ref) (ref "echo" x))
+
+; ATOMPub test case
+
+(define (get id ref)
+ (ref "get" id)
+)
+
+(define (post coll entry ref)
+ (ref "post" coll entry)
+)
+
+(define (put id entry ref)
+ (ref "put" id entry)
+)
+
+(define (delete id ref)
+ (ref "delete" id)
+)
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/cpp-conf b/sca-cpp/branches/gcc-4.4/modules/server/cpp-conf
new file mode 100755
index 0000000000..bc014ac979
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/cpp-conf
@@ -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.
+
+# Generate a C++ server conf
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+
+cat >>$root/conf/httpd.conf <<EOF
+# Support for C++ SCA components
+LoadModule mod_tuscany_eval $here/libmod_tuscany_eval.so
+
+EOF
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/domain-test.composite b/sca-cpp/branches/gcc-4.4/modules/server/domain-test.composite
new file mode 100644
index 0000000000..ef85bb919b
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/domain-test.composite
@@ -0,0 +1,49 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://domain/test"
+ name="domain-test">
+
+ <component name="scheme-test">
+ <t:implementation.scheme script="server-test.scm"/>
+ <service name="test">
+ <t:binding.http uri="test"/>
+ </service>
+ </component>
+
+ <component name="cpp-test">
+ <implementation.cpp path=".libs" library="libimpl-test"/>
+ <service name="cpp">
+ <t:binding.http uri="cpp"/>
+ </service>
+ </component>
+
+ <component name="client-test">
+ <t:implementation.scheme script="client-test.scm"/>
+ <service name="client">
+ <t:binding.http uri="client"/>
+ </service>
+ <reference name="ref" target="scheme-test">
+ <t:binding.http/>
+ </reference>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/htdocs/entry.xml b/sca-cpp/branches/gcc-4.4/modules/server/htdocs/entry.xml
new file mode 100644
index 0000000000..86b8a10547
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/htdocs/entry.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>111</id><content type="application/xml"><item><javaClass>services.Item</javaClass><name>Apple</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>2.99</price></item></content><link href="111"/></entry>
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/htdocs/feed.xml b/sca-cpp/branches/gcc-4.4/modules/server/htdocs/feed.xml
new file mode 100644
index 0000000000..5e37de6580
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/htdocs/feed.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Sample Feed</title><id>123456789</id><entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>111</id><content type="application/xml"><item><javaClass>services.Item</javaClass><name>Apple</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>2.99</price></item></content><link href="111"/></entry><entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>222</id><content type="application/xml"><item><javaClass>services.Item</javaClass><name>Orange</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>3.55</price></item></content><link href="222"/></entry><entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>333</id><content type="application/xml"><item><javaClass>services.Item</javaClass><name>Pear</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>1.55</price></item></content><link href="333"/></entry></feed>
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/htdocs/index.html b/sca-cpp/branches/gcc-4.4/modules/server/htdocs/index.html
new file mode 100644
index 0000000000..1bfb3e30c2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/htdocs/index.html
@@ -0,0 +1,21 @@
+<!--
+ 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><body><h1>It works!</h1></body></html>
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/htdocs/json-request.txt b/sca-cpp/branches/gcc-4.4/modules/server/htdocs/json-request.txt
new file mode 100644
index 0000000000..b4bd07fc46
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/htdocs/json-request.txt
@@ -0,0 +1 @@
+{"id":1,"method":"echo","params":["Hello"]}
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/htdocs/json-result.txt b/sca-cpp/branches/gcc-4.4/modules/server/htdocs/json-result.txt
new file mode 100644
index 0000000000..121bf74902
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/htdocs/json-result.txt
@@ -0,0 +1 @@
+{"id":1,"result":"Hello"} \ No newline at end of file
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/httpd-test b/sca-cpp/branches/gcc-4.4/modules/server/httpd-test
new file mode 100755
index 0000000000..13347ea83f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/httpd-test
@@ -0,0 +1,78 @@
+#!/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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../http/curl.prefix`
+
+# Setup
+../http/httpd-conf tmp localhost 8090 htdocs
+./server-conf tmp
+./scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+SCAContribution `pwd`/
+SCAComposite domain-test.composite
+EOF
+
+../http/httpd-start tmp
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/index.html 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/index.html
+rc=$?
+
+# Test ATOMPub
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/test/ >tmp/feed.xml 2>/dev/null
+ diff tmp/feed.xml htdocs/feed.xml
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/test/111 >tmp/entry.xml 2>/dev/null
+ diff tmp/entry.xml htdocs/entry.xml
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/test/ -X POST -H "Content-type: application/atom+xml" --data @htdocs/entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/test/111 -X PUT -H "Content-type: application/atom+xml" --data @htdocs/entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/test/111 -X DELETE 2>/dev/null
+ rc=$?
+fi
+
+# Test JSON-RPC
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/test/ -X POST -H "Content-type: application/json-rpc" --data @htdocs/json-request.txt >tmp/json-result.txt 2>/dev/null
+ diff tmp/json-result.txt htdocs/json-result.txt
+ rc=$?
+fi
+
+# Cleanup
+../http/httpd-stop tmp
+sleep 2
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/impl-test.cpp b/sca-cpp/branches/gcc-4.4/modules/server/impl-test.cpp
new file mode 100644
index 0000000000..1bd0843745
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/impl-test.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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 component implementation.
+ */
+
+#include "string.hpp"
+
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+
+namespace tuscany {
+namespace server {
+
+const failable<value> get(unused const list<value>& params) {
+ return value(mklist<value>("text/html", mklist<value>("Hey")));
+}
+
+const failable<value> post(unused const list<value>& params) {
+ return value(mklist<value>(string("123456789")));
+}
+
+const failable<value> put(unused const list<value>& params) {
+ return value(true);
+}
+
+const failable<value> del(unused const list<value>& params) {
+ return value(true);
+}
+
+const failable<value> echo(const list<value>& params) {
+ return value(car(params));
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+ const tuscany::value func(car(params));
+ if (func == "get")
+ return tuscany::server::get(cdr(params));
+ if (func == "post")
+ return tuscany::server::post(cdr(params));
+ if (func == "put")
+ return tuscany::server::put(cdr(params));
+ if (func == "delete")
+ return tuscany::server::del(cdr(params));
+ if (func == "echo")
+ return tuscany::server::echo(cdr(params));
+ return tuscany::mkfailure<tuscany::value>();
+}
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/mod-cpp.hpp b/sca-cpp/branches/gcc-4.4/modules/server/mod-cpp.hpp
new file mode 100644
index 0000000000..b3828dd7d2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/mod-cpp.hpp
@@ -0,0 +1,102 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_modcpp_hpp
+#define tuscany_modcpp_hpp
+
+/**
+ * Evaluation functions used by mod-eval to evaluate C++
+ * component implementations.
+ */
+
+#include "string.hpp"
+#include "stream.hpp"
+
+#include "function.hpp"
+#include "list.hpp"
+#include "element.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "dynlib.hpp"
+#include "../scheme/driver.hpp"
+
+namespace tuscany {
+namespace server {
+namespace modcpp {
+
+/**
+ * Apply a C++ component implementation function.
+ */
+const list<value> failableResult(const value& func, const list<value>& v) {
+ if (isNil(cdr(v)))
+ return v;
+
+ // Report a failure with an empty reason as 'function not supported'
+ // Except for the start, and stop functions, which are optional
+ const value reason = cadr(v);
+ if (length(reason) == 0) {
+ if (func == "start" || func == "stop")
+ return mklist<value>(lambda<value(const list<value>&)>());
+ return mklist<value>(value(), string("Function not supported: ") + func);
+ }
+ return v;
+}
+
+struct applyImplementation {
+ const lib ilib;
+ const lambda<value(const list<value>&)> impl;
+ const list<value> px;
+ applyImplementation(const lib& ilib, const lambda<value(const list<value>&)>& impl, const list<value>& px) : ilib(ilib), impl(impl), px(px) {
+ }
+ const value operator()(const list<value>& params) const {
+ debug(params, "modeval::cpp::applyImplementation::input");
+
+ // Apply the component implementation function
+ const value val = failableResult(car(params), impl(append(params, px)));
+
+ debug(val, "modeval::cpp::applyImplementation::result");
+ return val;
+ }
+};
+
+/**
+ * Evaluate a C++ component implementation and convert it to
+ * an applicable lambda function.
+ */
+const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) {
+
+ // Configure the implementation's lambda function
+ const value ipath(attributeValue("path", impl));
+ const value iname(attributeValue("library", impl));
+ const string fpath(isNil(ipath)? path + iname : path + ipath + "/" + iname);
+ const lib ilib(*(new (gc_new<lib>()) lib(fpath + dynlibExt)));
+ const failable<lambda<value(const list<value>&)> > evalf(dynlambda<value(const list<value>&)>("apply", ilib));
+ if (!hasContent(evalf))
+ return evalf;
+ const lambda<value(const list<value>&)> l(applyImplementation(ilib, content(evalf), px));
+ return l;
+}
+
+}
+}
+}
+
+#endif /* tuscany_modcpp_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/mod-eval.cpp b/sca-cpp/branches/gcc-4.4/modules/server/mod-eval.cpp
new file mode 100644
index 0000000000..a94ccf5bbe
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/mod-eval.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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$ */
+
+/**
+ * HTTPD module used to eval C++ and Scheme component implementations.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "mod-eval.hpp"
+#include "mod-scheme.hpp"
+#include "mod-cpp.hpp"
+
+namespace tuscany {
+namespace server {
+namespace modeval {
+
+/**
+ * Apply a lifecycle start or restart event.
+ */
+const value applyLifecycle(unused const list<value>& params) {
+ // Return a nil function as we don't need to handle any subsequent events
+ return failable<value>(lambda<value(const list<value>&)>());
+}
+
+/**
+ * Evaluate a Scheme or C++ component implementation and convert it to an
+ * applicable lambda function.
+ */
+const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, unused const lambda<value(const list<value>&)>& lifecycle) {
+ const string itype(elementName(impl));
+ if (contains(itype, ".scheme"))
+ return modscheme::evalImplementation(path, impl, px);
+ if (contains(itype, ".cpp"))
+ return modcpp::evalImplementation(path, impl, px);
+ return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype);
+}
+
+}
+}
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/mod-eval.hpp b/sca-cpp/branches/gcc-4.4/modules/server/mod-eval.hpp
new file mode 100644
index 0000000000..5ce787d2fb
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/mod-eval.hpp
@@ -0,0 +1,615 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_modeval_hpp
+#define tuscany_modeval_hpp
+
+/**
+ * HTTPD module used to eval component implementations.
+ */
+
+#include "string.hpp"
+#include "stream.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "tree.hpp"
+#include "value.hpp"
+#include "element.hpp"
+#include "monad.hpp"
+#include "../atom/atom.hpp"
+#include "../json/json.hpp"
+#include "../scdl/scdl.hpp"
+#include "../http/curl.hpp"
+#include "../http/httpd.hpp"
+
+extern "C" {
+extern module AP_MODULE_DECLARE_DATA mod_tuscany_eval;
+}
+
+namespace tuscany {
+namespace server {
+namespace modeval {
+
+/**
+ * Server configuration.
+ */
+class ServerConf {
+public:
+ ServerConf(server_rec* s) : s(s), wiringServerName(""), contributionPath(""), compositeName(""), ca(""), cert(""), key("") {
+ }
+
+ const server_rec* s;
+ lambda<value(const list<value>&)> lifecycle;
+ string wiringServerName;
+ string contributionPath;
+ string compositeName;
+ string ca;
+ string cert;
+ string key;
+ list<value> implementations;
+ list<value> implTree;
+};
+
+/**
+ * Convert a result represented as a content + failure pair to a
+ * failable monad.
+ */
+const failable<value> failableResult(const list<value>& v) {
+ if (isNil(cdr(v)))
+ return car(v);
+ return mkfailure<value>(string(cadr(v)));
+}
+
+/**
+ * Handle an HTTP GET.
+ */
+const failable<int> get(request_rec* r, const lambda<value(const list<value>&)>& impl) {
+ debug(r->uri, "modeval::get::uri");
+
+ // Inspect the query string
+ const list<list<value> > args = httpd::queryArgs(r);
+ const list<value> ia = assoc(value("id"), args);
+ const list<value> ma = assoc(value("method"), args);
+
+ // Evaluate a JSON-RPC request and return a JSON result
+ if (!isNil(ia) && !isNil(ma)) {
+
+ // Extract the request id, method and params
+ const value id = cadr(ia);
+ const value func = c_str(json::funcName(string(cadr(ma))));
+
+ // Apply the requested function
+ const failable<value> val = failableResult(impl(cons(func, httpd::queryParams(args))));
+ if (!hasContent(val))
+ return mkfailure<int>(reason(val));
+
+ // Return JSON result
+ json::JSONContext cx;
+ return httpd::writeResult(json::jsonResult(id, content(val), cx), "application/json-rpc", r);
+ }
+
+ // Evaluate the GET expression
+ const list<value> path(pathValues(r->uri));
+ const failable<value> val = failableResult(impl(cons<value>("get", mklist<value>(cddr(path)))));
+ if (!hasContent(val))
+ return mkfailure<int>(reason(val));
+ const value c = content(val);
+
+ // Write returned content-type / content-list pair
+ if (isList(cadr<value>(c)))
+ return httpd::writeResult(convertValues<string>(cadr<value>(c)), car<value>(c), r);
+
+ // Write returned ATOM feed or entry
+ if (isNil(cddr(path)))
+ return httpd::writeResult(atom::writeATOMFeed(atom::feedValuesToElements(c)), "application/atom+xml;type=feed", r);
+ else
+ return httpd::writeResult(atom::writeATOMEntry(atom::entryValuesToElements(c)), "application/atom+xml;type=entry", r);
+}
+
+/**
+ * Handle an HTTP POST.
+ */
+const failable<int> post(request_rec* r, const lambda<value(const list<value>&)>& impl) {
+ debug(r->uri, "modeval::post::url");
+
+ // Evaluate a JSON-RPC request and return a JSON result
+ const string ct = httpd::contentType(r);
+ if (contains(ct, "application/json-rpc") || contains(ct, "text/plain")) {
+
+ // Read the JSON request
+ const int rc = httpd::setupReadPolicy(r);
+ if(rc != OK)
+ return rc;
+ const list<string> ls = httpd::read(r);
+ debug(ls, "modeval::post::input");
+ json::JSONContext cx;
+ const list<value> json = elementsToValues(content(json::readJSON(ls, cx)));
+ const list<list<value> > args = httpd::postArgs(json);
+
+ // Extract the request id, method and params
+ const value id = cadr(assoc(value("id"), args));
+ const value func = c_str(json::funcName(cadr(assoc(value("method"), args))));
+ const list<value> params = (list<value>)cadr(assoc(value("params"), args));
+
+ // Evaluate the request expression
+ const failable<value> val = failableResult(impl(cons<value>(func, params)));
+ if (!hasContent(val))
+ return mkfailure<int>(reason(val));
+
+ // Return JSON result
+ return httpd::writeResult(json::jsonResult(id, content(val), cx), "application/json-rpc", r);
+ }
+
+ // Evaluate an ATOM POST request and return the location of the corresponding created resource
+ if (contains(ct, "application/atom+xml")) {
+
+ // Read the ATOM entry
+ const list<value> path(pathValues(r->uri));
+ const int rc = httpd::setupReadPolicy(r);
+ if(rc != OK)
+ return rc;
+ const list<string> ls = httpd::read(r);
+ debug(ls, "modeval::post::input");
+ const value entry = atom::entryValue(content(atom::readATOMEntry(ls)));
+
+ // Evaluate the POST expression
+ const failable<value> val = failableResult(impl(cons<value>("post", mklist<value>(cddr(path), entry))));
+ if (!hasContent(val))
+ return mkfailure<int>(reason(val));
+
+ // Return the created resource location
+ debug(content(val), "modeval::post::location");
+ apr_table_setn(r->headers_out, "Location", apr_pstrdup(r->pool, httpd::url(content(val), r)));
+ r->status = HTTP_CREATED;
+ return OK;
+ }
+
+ // Unknown content type, wrap the HTTP request struct in a value and pass it to
+ // the component implementation function
+ const failable<value> val = failableResult(impl(cons<value>("handle", mklist<value>(httpd::requestValue(r)))));
+ if (!hasContent(val))
+ return mkfailure<int>(reason(val));
+ return (int)content(val);
+}
+
+/**
+ * Handle an HTTP PUT.
+ */
+const failable<int> put(request_rec* r, const lambda<value(const list<value>&)>& impl) {
+ debug(r->uri, "modeval::put::url");
+
+ // Read the ATOM entry
+ const list<value> path(pathValues(r->uri));
+ const int rc = httpd::setupReadPolicy(r);
+ if(rc != OK)
+ return rc;
+ const list<string> ls = httpd::read(r);
+ debug(ls, "modeval::put::input");
+ const value entry = atom::entryValue(content(atom::readATOMEntry(ls)));
+
+ // Evaluate the PUT expression and update the corresponding resource
+ const failable<value> val = failableResult(impl(cons<value>("put", mklist<value>(cddr(path), entry))));
+ if (!hasContent(val))
+ return mkfailure<int>(reason(val));
+ if (val == value(false))
+ return HTTP_NOT_FOUND;
+ return OK;
+}
+
+/**
+ * Handle an HTTP DELETE.
+ */
+const failable<int> del(request_rec* r, const lambda<value(const list<value>&)>& impl) {
+ debug(r->uri, "modeval::delete::url");
+
+ // Evaluate an ATOM delete request
+ const list<value> path(pathValues(r->uri));
+ const failable<value> val = failableResult(impl(cons<value>("delete", mklist<value>(cddr(path)))));
+ if (!hasContent(val))
+ return mkfailure<int>(reason(val));
+ if (val == value(false))
+ return HTTP_NOT_FOUND;
+ return OK;
+}
+
+/**
+ * Translate a component request.
+ */
+int translate(request_rec *r) {
+ gc_scoped_pool pool(r->pool);
+ if (strncmp(r->uri, "/components/", 12) != 0)
+ return DECLINED;
+ r->handler = "mod_tuscany_eval";
+ return OK;
+}
+
+/**
+ * HTTP request handler.
+ */
+int handler(request_rec *r) {
+ gc_scoped_pool pool(r->pool);
+ if(strcmp(r->handler, "mod_tuscany_eval"))
+ return DECLINED;
+ httpdDebugRequest(r, "modeval::handler::input");
+
+ // Get the component implementation lambda
+ const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_eval);
+ const list<value> path(pathValues(r->uri));
+ const list<value> impl(assoctree<value>(cadr(path), sc.implTree));
+ if (isNil(impl))
+ return httpd::reportStatus(mkfailure<int>(string("Couldn't find component implementation")));
+
+ // Handle HTTP method
+ const lambda<value(const list<value>&)> l(cadr<value>(impl));
+ if (r->header_only)
+ return OK;
+ if(r->method_number == M_GET)
+ return httpd::reportStatus(get(r, l));
+ if(r->method_number == M_POST)
+ return httpd::reportStatus(post(r, l));
+ if(r->method_number == M_PUT)
+ return httpd::reportStatus(put(r, l));
+ if(r->method_number == M_DELETE)
+ return httpd::reportStatus(del(r, l));
+ return HTTP_NOT_IMPLEMENTED;
+}
+
+/**
+ * Convert a list of component references to a list of HTTP proxy lambdas.
+ */
+const value mkrefProxy(const value& ref, const string& base, const string& ca, const string& cert, const string& key) {
+ return lambda<value(const list<value>&)>(http::proxy(base + string(scdl::name(ref)), ca, cert, key));
+}
+
+const list<value> refProxies(const list<value>& refs, const string& base, const string& ca, const string& cert, const string& key) {
+ if (isNil(refs))
+ return refs;
+ return cons(mkrefProxy(car(refs), base, ca, cert, key), refProxies(cdr(refs), base, ca, cert, key));
+}
+
+/**
+ * Convert a list of component properties to a list of lambda functions that just return
+ * the property value.
+ */
+struct propProxy {
+ const value v;
+ propProxy(const value& v) : v(v) {
+ }
+ const value operator()(unused const list<value>& params) const {
+ return v;
+ }
+};
+
+const value mkpropProxy(const value& prop) {
+ return lambda<value(const list<value>&)>(propProxy(elementValue(prop)));
+}
+
+const list<value> propProxies(const list<value>& props) {
+ if (isNil(props))
+ return props;
+ return cons(mkpropProxy(car(props)), propProxies(cdr(props)));
+}
+
+/**
+ * Evaluate a component and convert it to an applicable lambda function.
+ */
+const value evalComponent(ServerConf& sc, server_rec& server, const value& comp) {
+ extern const failable<lambda<value(const list<value>&)> > evalImplementation(const string& cpath, const value& impl, const list<value>& px, const lambda<value(const list<value>&)>& lifecycle);
+
+ const value impl = scdl::implementation(comp);
+
+ // Convert component references to configured proxy lambdas
+ ostringstream base;
+ if (sc.wiringServerName == "")
+ base << (server.server_scheme == NULL? "http" : server.server_scheme)
+ << "://" << (server.server_hostname == NULL? "localhost" : server.server_hostname)
+ << ":" << (server.port == 0? 80 : server.port)
+ << "/references/" << string(scdl::name(comp)) << "/";
+ else
+ base << sc.wiringServerName << "/references/" << string(scdl::name(comp)) << "/";
+ const list<value> rpx(refProxies(scdl::references(comp), str(base), sc.ca, sc.cert, sc.key));
+
+ // Convert component proxies to configured proxy lambdas
+ const list<value> ppx(propProxies(scdl::properties(comp)));
+
+ // Evaluate the component implementation and convert it to an applicable lambda function
+ const failable<lambda<value(const list<value>&)> > cimpl(evalImplementation(sc.contributionPath, impl, append(rpx, ppx), sc.lifecycle));
+ if (!hasContent(cimpl))
+ return reason(cimpl);
+ return content(cimpl);
+}
+
+/**
+ * Return a list of component-name + configured-implementation pairs.
+ */
+const list<value> componentToImplementationAssoc(ServerConf& sc, server_rec& server, const list<value>& c) {
+ if (isNil(c))
+ return c;
+ return cons<value>(mklist<value>(scdl::name(car(c)), evalComponent(sc, server, car(c))), componentToImplementationAssoc(sc, server, cdr(c)));
+}
+
+/**
+ * Read the components declared in a composite.
+ */
+const failable<list<value> > readComponents(const string& path) {
+ ifstream is(path);
+ if (fail(is))
+ return mkfailure<list<value> >(string("Could not read composite: ") + path);
+ return scdl::components(readXML(streamList(is)));
+}
+
+/**
+ * Apply a list of component implementations to a start or restart lifecycle expression.
+ * Return the functions returned by the component implementations.
+ */
+const failable<list<value> > applyLifecycleExpr(const list<value>& impls, const list<value>& expr) {
+ if (isNil(impls))
+ return list<value>();
+
+ // Evaluate lifecycle expression against a component implementation lambda
+ const lambda<value(const list<value>&)> l = cadr<value>(car(impls));
+ const failable<value> r = failableResult(l(expr));
+ if (!hasContent(r))
+ return mkfailure<list<value> >(reason(r));
+ const lambda<value(const list<value>&)> rl = content(r);
+
+ // Use the returned lambda function, if any, from now on
+ const lambda<value(const list<value>&)> al = isNil(rl)? l : rl;
+
+ // Continue with the rest of the list
+ const failable<list<value> > nr = applyLifecycleExpr(cdr(impls), expr);
+ if (!hasContent(nr))
+ return nr;
+ return cons<value>(mklist<value>(car<value>(car(impls)), value(al)), content(nr));
+}
+
+/**
+ * Configure the components declared in the deployed composite.
+ */
+const failable<bool> confComponents(ServerConf& sc, server_rec& server) {
+ if (sc.contributionPath == "" || sc.compositeName == "")
+ return false;
+
+ // Read the components and get their implementation lambda functions
+ const failable<list<value> > comps = readComponents(sc.contributionPath + sc.compositeName);
+ if (!hasContent(comps))
+ return mkfailure<bool>(reason(comps));
+ sc.implementations = componentToImplementationAssoc(sc, server, content(comps));
+ debug(sc.implementations, "modeval::confComponents::implementations");
+
+ // Store the implementation lambda functions in a tree for fast retrieval
+ sc.implTree = mkbtree(sort(sc.implementations));
+ return true;
+}
+
+/**
+ * Start the components declared in the deployed composite.
+ */
+const failable<bool> startComponents(ServerConf& sc) {
+
+ // Start the components and record the returned implementation lambda functions
+ debug(sc.implementations, "modeval::startComponents::start");
+ const failable<list<value> > impls = applyLifecycleExpr(sc.implementations, mklist<value>("start"));
+ if (!hasContent(impls))
+ return mkfailure<bool>(reason(impls));
+ sc.implementations = content(impls);
+ debug(sc.implementations, "modeval::startComponents::implementations");
+
+ // Store the implementation lambda functions in a tree for fast retrieval
+ sc.implTree = mkbtree(sort(sc.implementations));
+ return true;
+}
+
+/**
+ * Cleanup callback, called when the server is stopped or restarted.
+ */
+apr_status_t serverCleanup(void* v) {
+ gc_pool pool;
+ ServerConf& sc = *(ServerConf*)v;
+ debug("modeval::serverCleanup");
+
+ // Stop the component implementations
+ applyLifecycleExpr(sc.implementations, mklist<value>("stop"));
+
+ // Call the module lifecycle function
+ if (isNil(sc.lifecycle))
+ return APR_SUCCESS;
+ debug("modeval::serverCleanup::stop");
+ sc.lifecycle(mklist<value>("stop"));
+
+ return APR_SUCCESS;
+}
+
+/**
+ * Called after all the configuration commands have been run.
+ * Process the server configuration and configure the deployed components.
+ */
+const int postConfigMerge(const ServerConf& mainsc, server_rec* s) {
+ if (s == NULL)
+ return OK;
+ ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_eval);
+ sc.wiringServerName = mainsc.wiringServerName;
+ sc.contributionPath = mainsc.contributionPath;
+ sc.compositeName = mainsc.compositeName;
+ sc.ca = mainsc.ca;
+ sc.cert = mainsc.cert;
+ sc.key = mainsc.key;
+ sc.implementations = mainsc.implementations;
+ sc.implTree = mainsc.implTree;
+ return postConfigMerge(mainsc, s->next);
+}
+
+int postConfig(apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp, server_rec *s) {
+ extern const value applyLifecycle(const list<value>&);
+
+ gc_scoped_pool pool(p);
+ ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_eval);
+
+ // Count the calls to post config
+ const string k("tuscany::modeval::postConfig");
+ const int count = (int)httpd::userData(k, s);
+ httpd::putUserData(k, (void*)(count + 1), s);
+
+ // Count == 0, do nothing as post config is always called twice,
+ // count == 1 is the first start, count > 1 is a restart
+ if (count == 0)
+ return OK;
+ if (count == 1) {
+ debug("modeval::postConfig::start");
+ const failable<value> r = failableResult(applyLifecycle(mklist<value>("start")));
+ if (!hasContent(r))
+ return -1;
+ sc.lifecycle = content(r);
+ }
+ if (count > 1) {
+ debug("modeval::postConfig::restart");
+ const failable<value> r = failableResult(applyLifecycle(mklist<value>("restart")));
+ if (!hasContent(r))
+ return -1;
+ sc.lifecycle = content(r);
+ }
+
+ // Configure the deployed components
+ debug(sc.wiringServerName, "modeval::postConfig::wiringServerName");
+ debug(sc.contributionPath, "modeval::postConfig::contributionPath");
+ debug(sc.compositeName, "modeval::postConfig::compositeName");
+ const failable<bool> res = confComponents(sc, *s);
+ if (!hasContent(res)) {
+ cerr << "[Tuscany] Due to one or more errors mod_tuscany_eval loading failed. Causing apache to stop loading." << endl;
+ return -1;
+ }
+
+ // Register a cleanup callback, called when the server is stopped or restarted
+ apr_pool_pre_cleanup_register(p, (void*)&sc, serverCleanup);
+
+ // Merge the config into any virtual hosts
+ return postConfigMerge(sc, s->next);
+}
+
+/**
+ * Child process initialization.
+ */
+void childInit(apr_pool_t* p, server_rec* s) {
+ gc_scoped_pool pool(p);
+ ServerConf* sc = (ServerConf*)ap_get_module_config(s->module_config, &mod_tuscany_eval);
+ if(sc == NULL) {
+ cerr << "[Tuscany] Due to one or more errors mod_tuscany_eval loading failed. Causing apache to stop loading." << endl;
+ exit(APEXIT_CHILDFATAL);
+ }
+
+ // Start the components in the child process
+ const failable<bool> res = startComponents(*sc);
+ if (!hasContent(res)) {
+ cerr << "[Tuscany] Due to one or more errors mod_tuscany_eval loading failed. Causing apache to stop loading." << endl;
+ exit(APEXIT_CHILDFATAL);
+ }
+
+ // Register a cleanup callback, called when the child is stopped or restarted
+ apr_pool_pre_cleanup_register(p, (void*)sc, serverCleanup);
+}
+
+/**
+ * Configuration commands.
+ */
+const char* confWiringServerName(cmd_parms *cmd, unused void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
+ ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
+ sc.wiringServerName = arg;
+ return NULL;
+}
+const char* confContribution(cmd_parms *cmd, unused void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
+ ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
+ sc.contributionPath = arg;
+ return NULL;
+}
+const char* confComposite(cmd_parms *cmd, unused void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
+ ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
+ sc.compositeName = arg;
+ return NULL;
+}
+const char* confCAFile(cmd_parms *cmd, unused void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
+ ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
+ sc.ca = arg;
+ return NULL;
+}
+const char* confCertFile(cmd_parms *cmd, unused void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
+ ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
+ sc.cert = arg;
+ return NULL;
+}
+const char* confCertKeyFile(cmd_parms *cmd, unused void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
+ ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
+ sc.key = arg;
+ return NULL;
+}
+
+const char* confEnv(unused cmd_parms *cmd, unused void *c, const char *name, const char *value) {
+ gc_scoped_pool pool(cmd->pool);
+ setenv(name, value != NULL? value : "", 1);
+ return NULL;
+}
+
+/**
+ * HTTP server module declaration.
+ */
+const command_rec commands[] = {
+ AP_INIT_TAKE1("SCAWiringServerName", (const char*(*)())confWiringServerName, NULL, RSRC_CONF, "SCA wiring server name"),
+ AP_INIT_TAKE1("SCAContribution", (const char*(*)())confContribution, NULL, RSRC_CONF, "SCA contribution location"),
+ AP_INIT_TAKE1("SCAComposite", (const char*(*)())confComposite, NULL, RSRC_CONF, "SCA composite location"),
+ AP_INIT_TAKE12("SCASetEnv", (const char*(*)())confEnv, NULL, OR_FILEINFO, "Environment variable name and optional value"),
+ AP_INIT_TAKE1("SCASSLCACertificateFile", (const char*(*)())confCAFile, NULL, RSRC_CONF, "SSL CA certificate file"),
+ AP_INIT_TAKE1("SCASSLCertificateFile", (const char*(*)())confCertFile, NULL, RSRC_CONF, "SSL certificate file"),
+ AP_INIT_TAKE1("SCASSLCertificateKeyFile", (const char*(*)())confCertKeyFile, NULL, RSRC_CONF, "SSL certificate key file"),
+ {NULL, NULL, NULL, 0, NO_ARGS, NULL}
+};
+
+
+void registerHooks(unused apr_pool_t *p) {
+ ap_hook_post_config(postConfig, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_child_init(childInit, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_handler(handler, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_translate_name(translate, NULL, NULL, APR_HOOK_FIRST);
+}
+
+}
+}
+}
+
+extern "C" {
+
+module AP_MODULE_DECLARE_DATA mod_tuscany_eval = {
+ STANDARD20_MODULE_STUFF,
+ // dir config and merger
+ NULL, NULL,
+ // server config and merger
+ tuscany::httpd::makeServerConf<tuscany::server::modeval::ServerConf>, NULL,
+ // commands and hooks
+ tuscany::server::modeval::commands, tuscany::server::modeval::registerHooks
+};
+
+}
+
+#endif
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/mod-scheme.hpp b/sca-cpp/branches/gcc-4.4/modules/server/mod-scheme.hpp
new file mode 100644
index 0000000000..f5b9554c3f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/mod-scheme.hpp
@@ -0,0 +1,89 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_modscheme_hpp
+#define tuscany_modscheme_hpp
+
+/**
+ * Evaluation functions used by mod-eval to evaluate Scheme
+ * component implementations.
+ */
+
+#include "string.hpp"
+#include "stream.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "../scheme/eval.hpp"
+
+namespace tuscany {
+namespace server {
+namespace modscheme {
+
+/**
+ * Convert proxy lambdas to evaluator primitive procedures.
+ */
+const list<value> primitiveProcedures(const list<value>& l) {
+ if (isNil(l))
+ return l;
+ return cons<value>(mklist<value>(scheme::primitiveSymbol, car(l)), primitiveProcedures(cdr(l)));
+}
+
+/**
+ * Apply a Scheme component implementation function.
+ */
+struct applyImplementation {
+ const value impl;
+ const list<value> px;
+ applyImplementation(const value& impl, const list<value>& px) : impl(impl), px(scheme::quotedParameters(primitiveProcedures(px))) {
+ }
+ const value operator()(const list<value>& params) const {
+ const value expr = cons<value>(car(params), append(scheme::quotedParameters(cdr(params)), px));
+ debug(expr, "modeval::scheme::applyImplementation::input");
+ scheme::Env env = scheme::setupEnvironment();
+ const value res = scheme::evalScript(expr, impl, env);
+ const value val = isNil(res)? mklist<value>(value(), string("Could not evaluate expression")) : mklist<value>(res);
+ debug(val, "modeval::scheme::applyImplementation::result");
+ return val;
+ }
+};
+
+/**
+ * Evaluate a Scheme component implementation and convert it to an
+ * applicable lambda function.
+ */
+const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) {
+ const string fpath(path + attributeValue("script", impl));
+ ifstream is(fpath);
+ if (fail(is))
+ return mkfailure<lambda<value(const list<value>&)> >(string("Could not read implementation: ") + fpath);
+ const value script = scheme::readScript(is);
+ if (isNil(script))
+ return mkfailure<lambda<value(const list<value>&)> >(string("Could not read implementation: ") + fpath);
+ return lambda<value(const list<value>&)>(applyImplementation(script, px));
+}
+
+}
+}
+}
+
+#endif /* tuscany_modscheme_hpp */
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/mod-wiring.cpp b/sca-cpp/branches/gcc-4.4/modules/server/mod-wiring.cpp
new file mode 100644
index 0000000000..296181acfa
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/mod-wiring.cpp
@@ -0,0 +1,379 @@
+/*
+ * 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$ */
+
+/**
+ * HTTPD module used to wire component references and route requests to
+ * target service components.
+ */
+
+#include <sys/stat.h>
+
+#include "string.hpp"
+#include "stream.hpp"
+#include "list.hpp"
+#include "tree.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "../scdl/scdl.hpp"
+#include "../http/httpd.hpp"
+
+extern "C" {
+extern module AP_MODULE_DECLARE_DATA mod_tuscany_wiring;
+}
+
+namespace tuscany {
+namespace server {
+namespace modwiring {
+
+/**
+ * Server configuration.
+ */
+class ServerConf {
+public:
+ ServerConf(server_rec* s) : s(s), contributionPath(""), compositeName("") {
+ }
+ const server_rec* s;
+ string contributionPath;
+ string compositeName;
+ list<value> references;
+ list<value> services;
+};
+
+/**
+ * Set to true to wire using mod_proxy, false to wire using HTTP client redirects.
+ */
+const bool useModProxy = true;
+
+/**
+ * Returns true if a URI is absolute.
+ */
+const bool isAbsolute(const string& uri) {
+ return contains(uri, "://");
+}
+
+/**
+ * Route a /references/component-name/reference-name request,
+ * to the target of the component reference.
+ */
+int translateReference(request_rec *r) {
+ httpdDebugRequest(r, "modwiring::translateReference::input");
+ debug(r->uri, "modwiring::translateReference::uri");
+
+ // Find the requested component
+ const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_wiring);
+ const list<value> rpath(pathValues(r->uri));
+ const list<value> comp(assoctree(cadr(rpath), sc.references));
+ if (isNil(comp))
+ return HTTP_NOT_FOUND;
+
+ // Find the requested reference and target configuration
+ const list<value> ref(assoctree<value>(caddr(rpath), cadr(comp)));
+ if (isNil(ref))
+ return HTTP_NOT_FOUND;
+ const string target(cadr(ref));
+ debug(target, "modwiring::translateReference::target");
+
+ // Route to an absolute target URI using mod_proxy or an HTTP client redirect
+ if (isAbsolute(target)) {
+ if (useModProxy) {
+ r->filename = apr_pstrdup(r->pool, c_str(string("proxy:") + target));
+ r->proxyreq = PROXYREQ_REVERSE;
+ r->handler = "proxy-server";
+ return OK;
+ }
+
+ r->status = HTTP_MOVED_TEMPORARILY;
+ apr_table_setn(r->headers_out, "Location", apr_pstrdup(r->pool, c_str(target)));
+ r->handler = "mod_tuscany_wiring";
+ return OK;
+ }
+
+ // Route to a relative target URI using a local internal redirect
+ r->filename = apr_pstrdup(r->pool, c_str(string("/redirect:/components/") + target));
+ r->handler = "mod_tuscany_wiring";
+ return OK;
+}
+
+/**
+ * Find a leaf matching a request path in a tree of URI paths.
+ */
+const int matchPath(const list<value>& k, const list<value>& p) {
+ if (isNil(p))
+ return true;
+ if (isNil(k))
+ return false;
+ if (car(k) != car(p))
+ return false;
+ return matchPath(cdr(k), cdr(p));
+}
+
+const list<value> assocPath(const value& k, const list<value>& tree) {
+ if (isNil(tree))
+ return tree;
+ if (matchPath(k, car<value>(car(tree))))
+ return car(tree);
+ if (k < car<value>(car(tree)))
+ return assocPath(k, cadr(tree));
+ return assocPath(k, caddr(tree));
+}
+
+/**
+ * Route a service request to the component providing the requested service.
+ */
+int translateService(request_rec *r) {
+ httpdDebugRequest(r, "modwiring::translateService::input");
+ debug(r->uri, "modwiring::translateService::uri");
+
+ // Find the requested component
+ const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_wiring);
+ debug(sc.services, "modwiring::translateService::services");
+ const list<value> p(pathValues(r->uri));
+ const list<value> svc(assocPath(p, sc.services));
+ if (isNil(svc))
+ return DECLINED;
+ debug(svc, "modwiring::translateService::service");
+
+ // Build a component-name + path-info URI
+ const list<value> target(cons<value>(cadr(svc), httpd::pathInfo(p, car(svc))));
+ debug(target, "modwiring::translateService::target");
+
+ // Dispatch to the target component using a local internal redirect
+ const string tp(path(target));
+ debug(tp, "modwiring::translateService::path");
+ const string redir(string("/redirect:/components") + tp);
+ debug(redir, "modwiring::translateService::redirect");
+ r->filename = apr_pstrdup(r->pool, c_str(redir));
+ r->handler = "mod_tuscany_wiring";
+ return OK;
+}
+
+/**
+ * Translate an HTTP service or reference request and route it
+ * to the target component.
+ */
+int translate(request_rec *r) {
+ gc_scoped_pool pool(r->pool);
+ if (!strncmp(r->uri, "/components/", 12) != 0)
+ return DECLINED;
+
+ // Translate a component reference request
+ if (!strncmp(r->uri, "/references/", 12) != 0)
+ return translateReference(r);
+
+ // Translate a service request
+ return translateService(r);
+}
+
+/**
+ * HTTP request handler, redirect to a target component.
+ */
+int handler(request_rec *r) {
+ gc_scoped_pool pool(r->pool);
+ if(strcmp(r->handler, "mod_tuscany_wiring"))
+ return DECLINED;
+ httpdDebugRequest(r, "modwiring::handler::input");
+
+ // Do an internal redirect
+ if (r->filename == NULL || strncmp(r->filename, "/redirect:", 10) != 0)
+ return DECLINED;
+ debug(r->uri, "modwiring::handler::uri");
+ debug(r->filename, "modwiring::handler::filename");
+ debug(r->path_info, "modwiring::handler::path info");
+
+ if (r->args == NULL)
+ return httpd::internalRedirect(httpd::redirectURI(string(r->filename + 10), string(r->path_info)), r);
+ return httpd::internalRedirect(httpd::redirectURI(string(r->filename + 10), string(r->path_info), string(r->args)), r);
+}
+
+/**
+ * Read the components declared in a composite.
+ */
+const failable<list<value> > readComponents(const string& path) {
+ ifstream is(path);
+ if (fail(is))
+ return mkfailure<list<value> >(string("Could not read composite: ") + path);
+ return scdl::components(readXML(streamList(is)));
+}
+
+/**
+ * Return a list of component-name + references pairs. The references are
+ * arranged in trees of reference-name + reference-target pairs.
+ */
+const list<value> componentReferenceToTargetTree(const value& c) {
+ return mklist<value>(scdl::name(c), mkbtree(sort(scdl::referenceToTargetAssoc(scdl::references(c)))));
+}
+
+const list<value> componentReferenceToTargetAssoc(const list<value>& c) {
+ if (isNil(c))
+ return c;
+ return cons<value>(componentReferenceToTargetTree(car(c)), componentReferenceToTargetAssoc(cdr(c)));
+}
+
+/**
+ * Return a list of service-URI-path + component-name pairs. Service-URI-paths are
+ * represented as lists of URI path fragments.
+ */
+const list<value> defaultBindingURI(const string& cn, const string& sn) {
+ return mklist<value>(cn, sn);
+}
+
+const list<value> bindingToComponentAssoc(const string& cn, const string& sn, const list<value>& b) {
+ if (isNil(b))
+ return b;
+ const value uri(scdl::uri(car(b)));
+ if (isNil(uri))
+ return cons<value>(mklist<value>(defaultBindingURI(cn, sn), cn), bindingToComponentAssoc(cn, sn, cdr(b)));
+ return cons<value>(mklist<value>(pathValues(c_str(string(uri))), cn), bindingToComponentAssoc(cn, sn, cdr(b)));
+}
+
+const list<value> serviceToComponentAssoc(const string& cn, const list<value>& s) {
+ if (isNil(s))
+ return s;
+ const string sn(scdl::name(car(s)));
+ const list<value> btoc(bindingToComponentAssoc(cn, sn, scdl::bindings(car(s))));
+ if (isNil(btoc))
+ return cons<value>(mklist<value>(defaultBindingURI(cn, sn), cn), serviceToComponentAssoc(cn, cdr(s)));
+ return append<value>(btoc, serviceToComponentAssoc(cn, cdr(s)));
+}
+
+const list<value> uriToComponentAssoc(const list<value>& c) {
+ if (isNil(c))
+ return c;
+ return append<value>(serviceToComponentAssoc(scdl::name(car(c)), scdl::services(car(c))), uriToComponentAssoc(cdr(c)));
+}
+
+/**
+ * Configure the components declared in the server's deployment composite.
+ */
+const bool confComponents(ServerConf& sc) {
+ if (sc.contributionPath == "" || sc.compositeName == "")
+ return true;
+
+ // Read the component configuration and store the references and service URIs
+ // in trees for fast retrieval later
+ const failable<list<value> > comps = readComponents(sc.contributionPath + sc.compositeName);
+ if (!hasContent(comps))
+ return true;
+ const list<value> refs = componentReferenceToTargetAssoc(content(comps));
+ debug(refs, "modwiring::confComponents::references");
+ sc.references = mkbtree(sort(refs));
+
+ const list<value> svcs = uriToComponentAssoc(content(comps));
+ debug(svcs, "modwiring::confComponents::services");
+ sc.services = mkbtree(sort(svcs));
+ return true;
+}
+
+/**
+ * Called after all the configuration commands have been run.
+ * Process the server configuration and configure the wiring for the deployed components.
+ */
+const int postConfigMerge(const ServerConf& mainsc, server_rec* s) {
+ if (s == NULL)
+ return OK;
+ ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_wiring);
+ sc.contributionPath = mainsc.contributionPath;
+ sc.compositeName = mainsc.compositeName;
+ sc.references = mainsc.references;
+ sc.services = mainsc.services;
+ return postConfigMerge(mainsc, s->next);
+}
+
+int postConfig(unused apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp, server_rec *s) {
+ // Count the calls to post config, skip the first one as
+ // postConfig is always called twice
+ const string k("tuscany::modwiring::postConfig");
+ const int count = (int)httpd::userData(k, s);
+ httpd::putUserData(k, (void*)(count + 1), s);
+ if (count == 0)
+ return OK;
+
+ // Configure the wiring for the deployed components
+ ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_wiring);
+ debug(sc.contributionPath, "modwiring::postConfig::contributionPath");
+ debug(sc.compositeName, "modwiring::postConfig::compositeName");
+ confComponents(sc);
+
+ // Merge the config into any virtual hosts
+ return postConfigMerge(sc, s->next);
+}
+
+/**
+ * Child process initialization.
+ */
+void childInit(apr_pool_t* p, server_rec* svr_rec) {
+ gc_scoped_pool pool(p);
+ ServerConf *conf = (ServerConf*)ap_get_module_config(svr_rec->module_config, &mod_tuscany_wiring);
+ if(conf == NULL) {
+ cerr << "[Tuscany] Due to one or more errors mod_tuscany_wiring loading failed. Causing apache to stop loading." << endl;
+ exit(APEXIT_CHILDFATAL);
+ }
+}
+
+/**
+ * Configuration commands.
+ */
+const char *confContribution(cmd_parms *cmd, unused void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
+ ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_wiring);
+ sc.contributionPath = arg;
+ return NULL;
+}
+const char *confComposite(cmd_parms *cmd, unused void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
+ ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_wiring);
+ sc.compositeName = arg;
+ return NULL;
+}
+
+/**
+ * HTTP server module declaration.
+ */
+const command_rec commands[] = {
+ AP_INIT_TAKE1("SCAContribution", (const char*(*)())confContribution, NULL, RSRC_CONF, "SCA contribution location"),
+ AP_INIT_TAKE1("SCAComposite", (const char*(*)())confComposite, NULL, RSRC_CONF, "SCA composite location"),
+ {NULL, NULL, NULL, 0, NO_ARGS, NULL}
+};
+
+void registerHooks(unused apr_pool_t *p) {
+ ap_hook_post_config(postConfig, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_child_init(childInit, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_handler(handler, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_translate_name(translate, NULL, NULL, APR_HOOK_FIRST);
+}
+
+}
+}
+}
+
+extern "C" {
+
+module AP_MODULE_DECLARE_DATA mod_tuscany_wiring = {
+ STANDARD20_MODULE_STUFF,
+ // dir config and merger
+ NULL, NULL,
+ // server config and merger
+ tuscany::httpd::makeServerConf<tuscany::server::modwiring::ServerConf>, NULL,
+ // commands and hooks
+ tuscany::server::modwiring::commands, tuscany::server::modwiring::registerHooks
+};
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/scheme-conf b/sca-cpp/branches/gcc-4.4/modules/server/scheme-conf
new file mode 100755
index 0000000000..fc5f2b3ac8
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/scheme-conf
@@ -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.
+
+# Generate a Scheme server conf
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+
+cat >>$root/conf/httpd.conf <<EOF
+# Support for Scheme SCA components
+LoadModule mod_tuscany_eval $here/libmod_tuscany_eval.so
+
+EOF
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/server-conf b/sca-cpp/branches/gcc-4.4/modules/server/server-conf
new file mode 100755
index 0000000000..ed5ead4cf5
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/server-conf
@@ -0,0 +1,47 @@
+#!/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.
+
+# Generate a server conf
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+
+host=`cat $root/conf/httpd.conf | grep ServerName | awk '{ print $2 }'`
+port=`cat $root/conf/httpd.conf | grep Listen | tail -1 | awk '{ print $2 }'`
+ssl=`cat $root/conf/httpd.conf | grep "SSLEngine" | awk '{ print $2 }'`
+if [ "$ssl" = "on" ]; then
+ protocol="https"
+
+cat >>$root/conf/httpd.conf <<EOF
+# Configure SCA SSL support
+SCASSLCACertificateFile "$root/conf/ca.crt"
+SCASSLCertificateFile "$root/conf/server.crt"
+SCASSLCertificateKeyFile "$root/conf/server.key"
+
+EOF
+
+else
+ protocol="http"
+fi
+
+cat >>$root/conf/httpd.conf <<EOF
+# Support for SCA component wiring
+LoadModule mod_tuscany_wiring $here/libmod_tuscany_wiring.so
+SCAWiringServerName $protocol://$host:$port
+
+EOF
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/server-test b/sca-cpp/branches/gcc-4.4/modules/server/server-test
new file mode 100755
index 0000000000..e53c7f5ef1
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/server-test
@@ -0,0 +1,39 @@
+#!/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
+../http/httpd-conf tmp localhost 8090 htdocs
+./server-conf tmp
+./scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+SCAContribution `pwd`/
+SCAComposite domain-test.composite
+EOF
+
+../http/httpd-start tmp
+sleep 2
+
+# Test
+./client-test 2>/dev/null
+rc=$?
+
+# Cleanup
+../http/httpd-stop tmp
+sleep 2
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/server-test.scm b/sca-cpp/branches/gcc-4.4/modules/server/server-test.scm
new file mode 100644
index 0000000000..5d545ecf8b
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/server-test.scm
@@ -0,0 +1,44 @@
+; 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.
+
+; JSON-RPC test case
+
+(define (echo x) x)
+
+; ATOMPub test case
+
+(define (get id)
+ (if (nul id)
+ '("Sample Feed" "123456789"
+ ("Item" "111" ((javaClass "services.Item") (name "Apple") (currencyCode "USD") (currencySymbol "$") (price 2.99)))
+ ("Item" "222" ((javaClass "services.Item") (name "Orange") (currencyCode "USD") (currencySymbol "$") (price 3.55)))
+ ("Item" "333" ((javaClass "services.Item") (name "Pear") (currencyCode "USD") (currencySymbol "$") (price 1.55))))
+
+ (list "Item" (car id) '((javaClass "services.Item") (name "Apple") (currencyCode "USD") (currencySymbol "$") (price 2.99))))
+)
+
+(define (post collection item)
+ '("123456789")
+)
+
+(define (put id item)
+ true
+)
+
+(define (delete id)
+ true
+)
diff --git a/sca-cpp/branches/gcc-4.4/modules/server/wiring-test b/sca-cpp/branches/gcc-4.4/modules/server/wiring-test
new file mode 100755
index 0000000000..f821d15256
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/server/wiring-test
@@ -0,0 +1,78 @@
+#!/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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../http/curl.prefix`
+
+# Setup
+../http/httpd-conf tmp localhost 8090 htdocs
+./server-conf tmp
+./scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+SCAContribution `pwd`/
+SCAComposite domain-test.composite
+EOF
+
+../http/httpd-start tmp
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/index.html 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/index.html
+rc=$?
+
+# Test ATOMPub
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/ >tmp/feed.xml 2>/dev/null
+ diff tmp/feed.xml htdocs/feed.xml
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/111 >tmp/entry.xml 2>/dev/null
+ diff tmp/entry.xml htdocs/entry.xml
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/ -X POST -H "Content-type: application/atom+xml" --data @htdocs/entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/111 -X PUT -H "Content-type: application/atom+xml" --data @htdocs/entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/111 -X DELETE 2>/dev/null
+ rc=$?
+fi
+
+# Test JSON-RPC
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/client/ -X POST -H "Content-type: application/json-rpc" --data @htdocs/json-request.txt >tmp/json-result.txt 2>/dev/null
+ diff tmp/json-result.txt htdocs/json-result.txt
+ rc=$?
+fi
+
+# Cleanup
+../http/httpd-stop tmp
+sleep 2
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/Makefile.am b/sca-cpp/branches/gcc-4.4/modules/wsgi/Makefile.am
new file mode 100644
index 0000000000..7678104761
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/Makefile.am
@@ -0,0 +1,52 @@
+# 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
+
+INCLUDES = -I${PYTHON_INCLUDE}
+
+mod_SCRIPTS = composite.py scdl.py util.py elemutil.py xmlutil.py atomutil.py jsonutil.py wsgi-start wsgi-stop
+moddir = $(prefix)/modules/wsgi
+
+noinst_DATA = target.stamp
+
+target.stamp: app.yaml *.py *.composite htdocs/*
+ mkdir -p target
+ cp app.yaml *.py *.composite target
+ cp -R htdocs target/htdocs
+ touch target.stamp
+
+clean-local:
+ rm -rf target.stamp target
+
+prefix_DATA = gae.prefix
+prefixdir=$(prefix)/modules/wsgi
+gae.prefix: $(top_builddir)/config.status
+ echo ${GAE_PREFIX} >gae.prefix
+
+client_test_SOURCES = client-test.cpp
+client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+
+noinst_PROGRAMS = client-test
+
+if WANT_GAE
+TESTS = util-test wsgi-test wiring-test http-test server-test gae-test
+else
+TESTS = util-test wsgi-test wiring-test http-test server-test
+endif
+
+endif
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/app.yaml b/sca-cpp/branches/gcc-4.4/modules/wsgi/app.yaml
new file mode 100644
index 0000000000..bc70aceced
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/app.yaml
@@ -0,0 +1,50 @@
+# 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.
+
+application: sca-wsgi
+version: 1
+runtime: python
+api_version: 1
+skip_files:
+- ^(.*/)?app\.yaml
+- ^(.*/)?app\.yml
+- ^(.*/)?index\.yaml
+- ^(.*/)?index\.yml
+- ^(.*/)?#.*#
+- ^(.*/)?.*~
+- ^(.*/)?.*\.py[co]
+- ^(.*/)?.*/RCS/.*
+- ^(.*/)?\..*
+- ^(.*/)?.*-test$
+- ^(.*/)?.*\.cpp$
+- ^(.*/)?.*\.o$
+- ^(.*/)?core$
+- ^(.*/)?.*\.out$
+- ^(.*/)?.*\.log$
+- ^(.*/)?Makefile.*
+- ^(.*/)?tmp/.*
+- ^(.*/)?wsgi-start
+- ^(.*/)?wsgi-stop
+
+handlers:
+- url: /(.*\.(html|js|png))
+ static_files: htdocs/\1
+ upload: htdocs/(.*\.(html|js|png))
+
+- url: /.*
+ script: composite.py
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/atom-test.py b/sca-cpp/branches/gcc-4.4/modules/wsgi/atom-test.py
new file mode 100755
index 0000000000..61435bf438
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/atom-test.py
@@ -0,0 +1,153 @@
+#!/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 ATOM data conversion functions
+
+import unittest
+from elemutil import *
+from atomutil import *
+
+itemEntry = \
+ "<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n" \
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\">" \
+ "<title type=\"text\">item</title>" \
+ "<id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</id>" \
+ "<content type=\"application/xml\">" \
+ "<item>" \
+ "<name>Apple</name><price>$2.99</price>" \
+ "</item>" \
+ "</content>" \
+ "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\" />" \
+ "</entry>\n"
+
+incompleteEntry = \
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\">" \
+ "<title>item</title><content type=\"text/xml\">" \
+ "<Item xmlns=\"http://services/\">" \
+ "<name xmlns=\"\">Orange</name>" \
+ "<price xmlns=\"\">3.55</price>" \
+ "</Item>" \
+ "</content>" \
+ "</entry>"
+
+completedEntry = \
+ "<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n" \
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\">" \
+ "<title type=\"text\">item</title>" \
+ "<id />" \
+ "<content type=\"application/xml\">" \
+ "<Item xmlns=\"http://services/\">" \
+ "<name xmlns=\"\">Orange</name>" \
+ "<price xmlns=\"\">3.55</price>" \
+ "</Item>" \
+ "</content><link href=\"\" />" \
+ "</entry>\n"
+
+def testEntry():
+ i = (element, "'item", (element, "'name", "Apple"), (element, "'price", "$2.99"))
+ a = ("item", "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b", i)
+ s = writeATOMEntry(a);
+ assert car(s) == itemEntry
+
+ a2 = readATOMEntry((itemEntry,))
+ s2 = writeATOMEntry(a2)
+ assert car(s2) == itemEntry
+
+ a3 = readATOMEntry((incompleteEntry,))
+ s3 = writeATOMEntry(a3)
+ assert car(s3) == completedEntry
+ return True
+
+emptyFeed = \
+ "<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n" \
+ "<feed xmlns=\"http://www.w3.org/2005/Atom\">" \
+ "<title type=\"text\">Feed</title>" \
+ "<id>1234</id>" \
+ "</feed>\n"
+
+itemFeed = \
+ "<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n" \
+ "<feed xmlns=\"http://www.w3.org/2005/Atom\">" \
+ "<title type=\"text\">Feed</title>" \
+ "<id>1234</id>" \
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\">" \
+ "<title type=\"text\">item</title>" \
+ "<id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</id>" \
+ "<content type=\"application/xml\">" \
+ "<item>" \
+ "<name>Apple</name><price>$2.99</price>" \
+ "</item>" \
+ "</content>" \
+ "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\" />" \
+ "</entry>" \
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\">" \
+ "<title type=\"text\">item</title>" \
+ "<id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c</id>" \
+ "<content type=\"application/xml\">" \
+ "<item>" \
+ "<name>Orange</name><price>$3.55</price>" \
+ "</item>" \
+ "</content>" \
+ "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c\" />" \
+ "</entry>" \
+ "</feed>\n"
+
+def testFeed():
+ s = writeATOMFeed(("Feed", "1234"))
+ assert car(s) == emptyFeed
+
+ a2 = readATOMFeed((emptyFeed,))
+ s2 = writeATOMFeed(a2)
+ assert car(s2) == emptyFeed
+
+ i3 = (("item", "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b",
+ (element, "'item", (element, "'name", "Apple"), (element, "'price", "$2.99"))),
+ ("item", "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c",
+ (element, "'item", (element, "'name", "Orange"), (element, "'price", "$3.55"))))
+ a3 = cons("Feed", cons("1234", i3))
+ s3 = writeATOMFeed(a3)
+ assert car(s3) == itemFeed
+
+ i4 = (("item", "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b",
+ valueToElement(("'item", ("'name", "Apple"), ("'price", "$2.99")))),
+ ("item", "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c",
+ valueToElement(("'item", ("'name", "Orange"), ("'price", "$3.55")))))
+ a4 = cons("Feed", cons("1234", i4))
+ s4 = writeATOMFeed(a4)
+ assert car(s4) == itemFeed
+
+ a5 = readATOMFeed((itemFeed,));
+ s5 = writeATOMFeed(a5);
+ assert car(s5) == itemFeed
+
+ i6 = (("item", "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b",
+ (("'name", "Apple"), ("'price", "$2.99"))),
+ ("item", "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c",
+ (("'name", "Orange"), ("'price", "$3.55"))))
+ a6 = cons("Feed", cons("1234", i6))
+ s6 = writeATOMFeed(feedValuesToElements(a6))
+ assert car(s6) == itemFeed
+
+ return True
+
+if __name__ == "__main__":
+ print "Testing..."
+ testEntry()
+ testFeed()
+ print "OK"
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/atomutil.py b/sca-cpp/branches/gcc-4.4/modules/wsgi/atomutil.py
new file mode 100644
index 0000000000..0ec83ca9e0
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/atomutil.py
@@ -0,0 +1,103 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# ATOM data conversion functions
+
+from util import *
+from elemutil import *
+from xmlutil import *
+
+# Convert a list of elements to a list of values representing an ATOM entry
+def entryElementsToValues(e):
+ lt = filter(selector((element, "'title")), e)
+ t = "" if isNil(lt) else elementValue(car(lt))
+ li = filter(selector((element, "'id")), e)
+ i = "" if isNil(li) else elementValue(car(li))
+ lc = filter(selector((element, "'content")), e)
+ return (t, i, cadr(elementChildren(car(lc))))
+
+# Convert a list of elements to a list of values representing ATOM entries
+def entriesElementsToValues(e):
+ if isNil(e):
+ return e
+ return cons(entryElementsToValues(car(e)), entriesElementsToValues(cdr(e)))
+
+# Convert a list of strings to a list of values representing an ATOM entry
+def readATOMEntry(l):
+ e = readXML(l)
+ if isNil(e):
+ return ()
+ return entryElementsToValues(car(e))
+
+# Convert a list of values representy an ATOM entry to a value
+def entryValue(e):
+ v = elementsToValues((caddr(e),))
+ return cons(car(e), (cadr(e), cdr(car(v))))
+
+# Convert a list of strings to a list of values representing an ATOM feed
+def readATOMFeed(l):
+ f = readXML(l)
+ if isNil(f):
+ return ()
+ t = filter(selector((element, "'title")), car(f))
+ i = filter(selector((element, "'id")), car(f))
+ e = filter(selector((element, "'entry")), car(f))
+ if isNil(e):
+ return (elementValue(car(t)), elementValue(car(i)))
+ return cons(elementValue(car(t)), cons(elementValue(car(i)), entriesElementsToValues(e)))
+
+# Convert a list of values representy an ATOM entry to a list of elements
+def entryElement(l):
+ return (element, "'entry", (attribute, "'xmlns", "http://www.w3.org/2005/Atom"),
+ (element, "'title", (attribute, "'type", "text"), car(l)),
+ (element, "'id", cadr(l)),
+ (element, "'content", (attribute, "'type", "application/xml"), caddr(l)),
+ (element, "'link", (attribute, "'href", cadr(l))))
+
+# Convert a list of values representing ATOM entries to a list of elements
+def entriesElements(l):
+ if isNil(l):
+ return l
+ return cons(entryElement(car(l)), entriesElements(cdr(l)))
+
+# Convert a list of values representing an ATOM entry to an ATOM entry
+def writeATOMEntry(l):
+ return writeXML((entryElement(l),), True)
+
+# Convert a list of values representing an ATOM feed to an ATOM feed
+def writeATOMFeed(l):
+ f = (element, "'feed", (attribute, "'xmlns", "http://www.w3.org/2005/Atom"),
+ (element, "'title", (attribute, "'type", "text"), car(l)),
+ (element, "'id", cadr(l)))
+ if isNil(cddr(l)):
+ return writeXML((f,), True)
+ fe = f + entriesElements(cddr(l))
+ return writeXML((fe,), True)
+
+# Convert an ATOM entry containing a value to an ATOM entry containing an item element
+def entryValuesToElements(v):
+ return cons(car(v), cons(cadr(v), valuesToElements((cons("'item", caddr(v)),))))
+
+# Convert an ATOM feed containing values to an ATOM feed containing elements
+def feedValuesToElementsLoop(v):
+ if isNil(v):
+ return v
+ return cons(entryValuesToElements(car(v)), feedValuesToElementsLoop(cdr(v)))
+
+def feedValuesToElements(v):
+ return cons(car(v), cons(cadr(v), feedValuesToElementsLoop(cddr(v))))
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/client-test.cpp b/sca-cpp/branches/gcc-4.4/modules/wsgi/client-test.cpp
new file mode 100644
index 0000000000..da4fff973b
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/client-test.cpp
@@ -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.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Test HTTP client functions.
+ */
+
+#include "stream.hpp"
+#include "string.hpp"
+#include "../server/client-test.hpp"
+
+int main(const int argc, const char** argv) {
+ tuscany::cout << "Testing..." << tuscany::endl;
+ tuscany::server::testURI = argc < 2? "http://localhost:8090/wsgi" : argv[1];
+ tuscany::server::testBlobs = false;
+
+ tuscany::server::testServer();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/client-test.py b/sca-cpp/branches/gcc-4.4/modules/wsgi/client-test.py
new file mode 100644
index 0000000000..47e6cf4bda
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/client-test.py
@@ -0,0 +1,35 @@
+# 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.
+
+# JSON-RPC test case
+
+def echo(x, ref):
+ return ref("echo", x)
+
+# ATOMPub test case
+
+def get(id, ref):
+ return ref("get", id)
+
+def post(collection, item, ref):
+ return ref("post", collection, item)
+
+def put(id, item, ref):
+ return ref("put", id, item)
+
+def delete(id, ref):
+ return ref("delete", id)
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/composite.py b/sca-cpp/branches/gcc-4.4/modules/wsgi/composite.py
new file mode 100755
index 0000000000..4be44c3101
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/composite.py
@@ -0,0 +1,220 @@
+#!/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.
+
+# Composite deployment and integration with WSGI
+
+from wsgiref.simple_server import make_server
+from wsgiref.handlers import CGIHandler
+from wsgiref.util import request_uri
+from wsgiref.util import FileWrapper
+from os import environ
+import os.path
+import hashlib
+from sys import stderr, argv
+from util import *
+from scdl import *
+from atomutil import *
+from jsonutil import *
+
+# Cache the deployed components between requests
+comps = None
+
+# Return the path of an HTTP request
+def requestPath(e):
+ return e.get("PATH_INFO", "")
+
+# Return the method of an HTTP request
+def requestMethod(e):
+ return e.get("REQUEST_METHOD", "")
+
+# Return the method of an HTTP request
+def requestContentType(e):
+ return e.get("CONTENT_TYPE", "")
+
+# Return the request body input stream
+def requestBody(e):
+ i = e.get("wsgi.input", None)
+ if i == None:
+ return ()
+ l = int(e.get("CONTENT_LENGTH", "0"))
+ return (i.read(l),)
+
+def requestIfNoneMatch(e):
+ return e.get("HTTP_IF_NONE_MATCH", "");
+
+# Hash a list of strings into an MD5 signature
+def md5update(md, s):
+ if isNil(s):
+ return md.hexdigest()
+ md.update(car(s))
+ return md5update(md, cdr(s))
+
+def md5(s):
+ return md5update(hashlib.md5(), s)
+
+# Return an HTTP success result
+def result(e, r, st, h = (), b = None):
+ if st == 201:
+ r("201 Created", list(h))
+ return ()
+
+ if st == 200:
+ if b == None:
+ r("200 OK", list(h))
+ return ()
+
+ # Handle etags to minimize bandwidth usage
+ md = md5(b)
+ if (md == requestIfNoneMatch(e)):
+ r("304 Not Modified", list((("Etag", md), ("Expires", "Tue, 01 Jan 1980 00:00:00 GMT"))))
+ return ()
+ r("200 OK", list(h + (("Etag", md), ("Expires", "Tue, 01 Jan 1980 00:00:00 GMT"))))
+ return b
+
+ return failure(e, r, 500)
+
+# Return an HTTP failure result
+def failure(e, r, st):
+ s = "404 Not Found" if st == 404 else str(st) + " " + "Internal Server Error"
+ r(s, list((("Content-type", "text/html"),)))
+ return ("<html><head><title>"+ s + "</title></head><body><h1>" + s[4:] + "</h1></body></html>",)
+
+# Return a static file
+def fileresult(e, r, ct, f):
+
+ # Read the file, return a 404 if not found
+ p = "htdocs" + f
+ if not os.path.exists(p):
+ return failure(e, r, 404)
+ c = tuple(FileWrapper(open("htdocs" + f)))
+
+ # Handle etags to minimize bandwidth usage
+ md = md5(c)
+ r("200 OK", list((("Content-type", ct),("Etag", md))))
+ return c
+
+# Converts the args received in a POST to a list of key value pairs
+def postArgs(a):
+ if isNil(a):
+ return ((),)
+ l = car(a);
+ return cons(l, postArgs(cdr(a)))
+
+# WSGI application function
+def application(e, r):
+ m = requestMethod(e)
+ fpath = requestPath(e)
+
+ # Debug hook
+ if fpath == "/debug":
+ return result(e, r, 200, (("Content-type", "text/plain"),), ("Debug",))
+
+ # Serve static files
+ if m == "GET":
+ if fpath.endswith(".html"):
+ return fileresult(e, r, "text/html", fpath)
+ if fpath.endswith(".js"):
+ return fileresult(e, r, "application/x-javascript", fpath)
+ if fpath.endswith(".png"):
+ return fileresult(e, r, "image/png", fpath)
+
+ # Find the requested component
+ path = tokens(fpath)
+ uc = uriToComponent(path, comps)
+ uri = car(uc)
+ if uri == None:
+ return failure(e, r, 404)
+ comp = cadr(uc)
+
+ # Call the requested component function
+ id = path[len(uri):]
+ if m == "GET":
+ v = comp("get", id)
+
+ # Write returned content-type / content pair
+ if not isinstance(cadr(v), basestring):
+ return result(e, r, 200, (("Content-type", car(v)),), cadr(v))
+
+ # Write an ATOM feed or entry
+ if isNil(id):
+ return result(e, r, 200, (("Content-type", "application/atom+xml;type=feed"),), writeATOMFeed(feedValuesToElements(v)))
+ return result(e, r, 200, (("Content-type", "application/atom+xml;type=entry"),), writeATOMEntry(entryValuesToElements(v)))
+
+ if m == "POST":
+ ct = requestContentType(e)
+
+ # Handle a JSON-RPC function call
+ if ct.find("application/json-rpc") != -1 or ct.find("text/plain") != -1:
+ json = elementsToValues(readJSON(requestBody(e)))
+ args = postArgs(json)
+ jid = cadr(assoc("'id", args))
+ func = funcName(cadr(assoc("'method", args)))
+ params = cadr(assoc("'params", args))
+ v = comp(func, *params)
+ return result(e, r, 200, (("Content-type", "application/json-rpc"),), jsonResult(jid, v))
+
+ # Handle an ATOM entry POST
+ if ct.find("application/atom+xml") != -1:
+ ae = entryValue(readATOMEntry(requestBody(e)))
+ v = comp("post", id, ae)
+ if isNil(v):
+ return failure(e, r, 500)
+ return result(e, r, 201, (("Location", request_uri(e) + "/" + "/".join(v)),))
+ return failure(e, r, 500)
+
+ if m == "PUT":
+ # Handle an ATOM entry PUT
+ ae = entryValue(readATOMEntry(requestBody(e)))
+ v = comp("put", id, ae)
+ if v == False:
+ return failure(e, r, 404)
+ return result(e, r, 200)
+
+ if m == "DELETE":
+ v = comp("delete", id)
+ if v == False:
+ return failure(e, r, 404)
+ return result(e, r, 200)
+
+ return failure(e, r, 500)
+
+# Return the WSGI server type
+def serverType(e):
+ return e.get("SERVER_SOFTWARE", "")
+
+def main():
+ # Read the deployed composite and evaluate the configured components
+ global comps
+ if comps == None:
+ domain = "domain.composite" if os.path.exists("domain.composite") else "domain-test.composite"
+ comps = evalComponents(components(parse(domain)))
+
+ # Handle the WSGI request with the WSGI runtime
+ st = serverType(environ)
+ if st.find("App Engine") != -1 or st.find("Development") != -1:
+ from google.appengine.ext.webapp.util import run_wsgi_app
+ run_wsgi_app(application)
+ elif st != "":
+ CGIHandler().run(application)
+ else:
+ make_server("", int(argv[1]), application).serve_forever()
+
+# Run the WSGI application
+if __name__ == "__main__":
+ main()
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/domain-test.composite b/sca-cpp/branches/gcc-4.4/modules/wsgi/domain-test.composite
new file mode 100644
index 0000000000..9c44ebf5d8
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/domain-test.composite
@@ -0,0 +1,42 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://domain/test"
+ name="domain-test">
+
+ <component name="wsgi-test">
+ <t:implementation.python script="server-test.py"/>
+ <service name="test">
+ <t:binding.http uri="wsgi"/>
+ </service>
+ </component>
+
+ <component name="client-test">
+ <t:implementation.python script="client-test.py"/>
+ <service name="client">
+ <t:binding.http uri="client"/>
+ </service>
+ <reference name="ref" target="wsgi-test">
+ <t:binding.http/>
+ </reference>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/elemutil.py b/sca-cpp/branches/gcc-4.4/modules/wsgi/elemutil.py
new file mode 100644
index 0000000000..ad971ba6ba
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/elemutil.py
@@ -0,0 +1,168 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Functions to help represent data as lists of elements and attributes
+
+from util import *
+
+element = "'element"
+attribute = "'attribute"
+atsign = "'@"
+
+# Return true if a value is an element
+def isElement(v):
+ if not isList(v) or isNil(v) or v == None or car(v) != element:
+ return False
+ return True
+
+# Return true if a value is an attribute
+def isAttribute(v):
+ if not isList(v) or isNil(v) or v == None or car(v) != attribute:
+ return False
+ return True
+
+# Return the name of attribute
+def attributeName(l):
+ return cadr(l)
+
+# Return the value of attribute
+def attributeValue(l):
+ return caddr(l)
+
+# Return the name of an element
+def elementName(l):
+ return cadr(l)
+
+# Return true if an element has children
+def elementHasChildren(l):
+ return not isNil(cddr(l))
+
+# Return the children of an element
+def elementChildren(l):
+ return cddr(l)
+
+# Return true if an element has a value
+def elementHasValue(l):
+ r = reverse(l)
+ if isSymbol(car(r)):
+ return False
+ if isList(car(r)) and not isNil(car(r)) and isSymbol(car(car(r))):
+ return False
+ return True
+
+# Return the value of an element
+def elementValue(l):
+ return car(reverse(l))
+
+# Convert an element to a value
+def elementToValueIsList(v):
+ if not isList(v):
+ return False
+ return isNil(v) or not isSymbol(car(v))
+
+def elementToValue(t):
+ if isTaggedList(t, attribute):
+ return (atsign + attributeName(t)[1:], attributeValue(t))
+ if isTaggedList(t, element):
+ if elementHasValue(t):
+ if not elementToValueIsList(elementValue(t)):
+ return (elementName(t), elementValue(t))
+ return cons(elementName(t), (elementsToValues(elementValue(t)),))
+ return cons(elementName(t), elementsToValues(elementChildren(t)))
+ if not isList(t):
+ return t
+ return elementsToValues(t)
+
+# Convert a list of elements to a list of values
+def elementToValueIsSymbol(v):
+ if not isList(v):
+ return False
+ if (isNil(v)):
+ return False
+ if not isSymbol(car(v)):
+ return False
+ return True
+
+def elementToValueGroupValues(v, l):
+ if isNil(l) or not elementToValueIsSymbol(v) or not elementToValueIsSymbol(car(l)):
+ return cons(v, l)
+ if car(car(l)) != car(v):
+ return cons(v, l)
+ if not elementToValueIsList(cadr(car(l))):
+ g = (car(v), (cdr(v), cdr(car(l))))
+ return elementToValueGroupValues(g, cdr(l))
+ g = (car(v), cons(cdr(v), cadr(car(l))))
+ return elementToValueGroupValues(g, cdr(l))
+
+def elementsToValues(e):
+ if isNil(e):
+ return e
+ return elementToValueGroupValues(elementToValue(car(e)), elementsToValues(cdr(e)))
+
+# Convert a value to an element
+def valueToElement(t):
+ if isList(t) and not isNil(t) and isSymbol(car(t)):
+ n = car(t)
+ v = cadr(t)
+ if not isList(v):
+ if n[0:2] == atsign:
+ return (attribute, n[1:], v)
+ return (element, n, v)
+ if isNil(v) or not isSymbol(car(v)):
+ return cons(element, cons(n, (valuesToElements(v),)))
+ return cons(element, cons(n, valuesToElements(cdr(t))))
+ if not isList(t):
+ return t
+ return valuesToElements(t)
+
+# Convert a list of values to a list of elements
+def valuesToElements(l):
+ if isNil(l):
+ return l
+ return cons(valueToElement(car(l)), valuesToElements(cdr(l)))
+
+# Return a selector lambda function which can be used to filter elements
+def evalSelect(s, v):
+ if isNil(s):
+ return True
+ if isNil(v):
+ return False
+ if car(s) != car(v):
+ return False
+ return evalSelect(cdr(s), cdr(v))
+
+def selector(s):
+ return lambda v: evalSelect(s, v)
+
+# Return the value of the attribute with the given name
+def namedAttributeValue(name, l):
+ f = filter(lambda v: isAttribute(v) and attributeName(v) == name, l)
+ if isNil(f):
+ return None
+ return caddr(car(f))
+
+# Return child elements with the given name
+def namedElementChildren(name, l):
+ return filter(lambda v: isElement(v) and elementName(v) == name, l)
+
+# Return the child element with the given name
+def namedElementChild(name, l):
+ f = namedElementChildren(name, l)
+ if isNil(f):
+ return None
+ return car(f)
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/gae-start b/sca-cpp/branches/gcc-4.4/modules/wsgi/gae-start
new file mode 100755
index 0000000000..69882750aa
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/gae-start
@@ -0,0 +1,29 @@
+#!/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.
+
+# Start Google AppEngine server
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+port=$2
+
+python_prefix=`cat $here/../python/python.prefix`
+gae_prefix=`cat $here/gae.prefix`
+cd $root
+$python_prefix/bin/python $gae_prefix/dev_appserver.py -p $port $root &
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/gae-stop b/sca-cpp/branches/gcc-4.4/modules/wsgi/gae-stop
new file mode 100755
index 0000000000..64e7031058
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/gae-stop
@@ -0,0 +1,29 @@
+#!/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.
+
+# Stop Google AppEngine server
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+port=$2
+
+python_prefix=`cat $here/../python/python.prefix`
+gae_prefix=`cat $here/gae.prefix`
+py="$python_prefix/bin/python $gae_prefix/dev_appserver.py -p $port $root"
+
+kill `ps -ef | grep -v grep | grep "${py}" | awk '{ print $2 }'`
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/gae-test b/sca-cpp/branches/gcc-4.4/modules/wsgi/gae-test
new file mode 100755
index 0000000000..1791a830ca
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/gae-test
@@ -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.
+
+# Setup
+./gae-start target 8090 2>/dev/null
+sleep 2
+
+# Test
+./client-test 2>/dev/null
+rc=$?
+
+# Cleanup
+./gae-stop target 8090
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/entry.xml b/sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/entry.xml
new file mode 100644
index 0000000000..5796cd655f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/entry.xml
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>111</id><content type="application/xml"><item><javaClass>services.Item</javaClass><name>Apple</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>2.99</price></item></content><link href="111" /></entry>
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/feed.xml b/sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/feed.xml
new file mode 100644
index 0000000000..d15b265f15
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/feed.xml
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Sample Feed</title><id>123456789</id><entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>111</id><content type="application/xml"><item><javaClass>services.Item</javaClass><name>Apple</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>2.99</price></item></content><link href="111" /></entry><entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>222</id><content type="application/xml"><item><javaClass>services.Item</javaClass><name>Orange</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>3.55</price></item></content><link href="222" /></entry><entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>333</id><content type="application/xml"><item>('name', 'Pear')<javaClass>services.Item</javaClass><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>1.55</price></item></content><link href="333" /></entry></feed>
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/index.html b/sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/index.html
new file mode 100644
index 0000000000..cd25bf17b3
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/index.html
@@ -0,0 +1 @@
+<html><body><h1>It works!</h1></body></html> \ No newline at end of file
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/json-request.txt b/sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/json-request.txt
new file mode 100644
index 0000000000..b4bd07fc46
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/json-request.txt
@@ -0,0 +1 @@
+{"id":1,"method":"echo","params":["Hello"]}
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/json-result.txt b/sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/json-result.txt
new file mode 100644
index 0000000000..121bf74902
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/htdocs/json-result.txt
@@ -0,0 +1 @@
+{"id":1,"result":"Hello"} \ No newline at end of file
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/http-test b/sca-cpp/branches/gcc-4.4/modules/wsgi/http-test
new file mode 100755
index 0000000000..6676f6514c
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/http-test
@@ -0,0 +1,39 @@
+#!/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.
+
+uri=$1
+if [ "$uri" = "" ]; then
+ uri="http://localhost:8090"
+fi
+
+# Setup
+mkdir -p tmp
+./wsgi-start target 8090 2>/dev/null
+sleep 2
+
+# Test JSON-RPC
+here=`readlink -f $0`; here=`dirname $here`
+python_prefix=`cat $here/../python/python.prefix`
+$python_prefix/bin/python http-test.py
+rc=$?
+
+# Cleanup
+./wsgi-stop target 8090
+sleep 2
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/http-test.py b/sca-cpp/branches/gcc-4.4/modules/wsgi/http-test.py
new file mode 100755
index 0000000000..87a8780fb3
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/http-test.py
@@ -0,0 +1,32 @@
+#!/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.
+
+# HTTP client proxy functions
+
+from httputil import *
+
+def testClient():
+ c = mkclient("http://localhost:8090/wsgi")
+ assert c("echo", "Hey") == "Hey"
+ return True
+
+if __name__ == "__main__":
+ print "Testing..."
+ testClient()
+ print "OK"
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/httputil.py b/sca-cpp/branches/gcc-4.4/modules/wsgi/httputil.py
new file mode 100644
index 0000000000..77d19eabe2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/httputil.py
@@ -0,0 +1,78 @@
+#!/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.
+
+# HTTP client proxy functions
+
+from httplib import HTTPConnection, HTTPSConnection
+from urlparse import urlparse
+from StringIO import StringIO
+import os.path
+from string import strip
+from base64 import b64encode
+from sys import stderr
+from util import *
+from atomutil import *
+from jsonutil import *
+
+id = 1
+
+# Make a callable HTTP client
+class client:
+ def __init__(self, uri):
+ self.uri = urlparse(uri)
+
+ def __call__(self, func, *args):
+
+ # Connect to the configured URI
+ print >> stderr, "Client POST", self.uri.geturl()
+ c = None
+ headers = {"Content-type": "application/json-rpc"}
+ if self.uri.scheme == "https":
+
+ # With HTTPS, use a cerficate or HTTP basic authentication
+ if os.path.exists("server.key"):
+ c = HTTPSConnection(self.uri.hostname, 443 if self.uri.port == None else self.uri.port, "server.key", "server.crt")
+ else:
+ c = HTTPSConnection(self.uri.hostname, 443 if self.uri.port == None else self.uri.port)
+
+ # For HTTP basic authentication the user and password are
+ # provided by htpasswd.py
+ import htpasswd
+ auth = 'Basic ' + b64encode(htpasswd.user + ':' + htpasswd.passwd)
+ headers["Authorization"] = auth
+ else:
+ c = HTTPConnection(self.uri.hostname, 80 if self.uri.port == None else self.uri.port)
+
+ # POST the JSON-RPC request
+ global id
+ req = StringIO()
+ writeStrings(jsonRequest(id, func, args), req)
+ id = id + 1
+ c.request("POST", self.uri.path, req.getvalue(), headers)
+ res = c.getresponse()
+ print >> stderr, "Client status", res.status
+ if res.status != 200:
+ return None
+ return jsonResultValue((res.read(),))
+
+ def __repr__(self):
+ return repr((self.uri,))
+
+def mkclient(uri):
+ return client(uri)
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/json-test.py b/sca-cpp/branches/gcc-4.4/modules/wsgi/json-test.py
new file mode 100755
index 0000000000..2f2a755bff
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/json-test.py
@@ -0,0 +1,59 @@
+#!/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 JSON data conversion functions
+
+import unittest
+from elemutil import *
+from jsonutil import *
+
+def testJSON():
+ ad = ((attribute, "'city", "san francisco"), (attribute, "'state", "ca"))
+ ac = ((element, "'id", "1234"), (attribute, "'balance", 1000))
+ cr = ((attribute, "'name", "jdoe"), cons(element, cons("'address", ad)), cons(element, cons("'account", ac)))
+ c = (cons(element, cons("'customer", cr)),)
+ s = writeJSON(c);
+ assert car(s) == "{\"customer\":{\"account\":{\"@balance\":1000,\"id\":\"1234\"},\"@name\":\"jdoe\",\"address\":{\"@city\":\"san francisco\",\"@state\":\"ca\"}}}"
+
+ phones = ("408-1234", "650-1234")
+ l = ((element, "'phones", phones), (element, "'lastName", "test\ttab"), (attribute, "'firstName", "test1"))
+ s2 = writeJSON(l);
+ assert car(s2) == "{\"phones\":[\"408-1234\",\"650-1234\"],\"@firstName\":\"test1\",\"lastName\":\"test\\ttab\"}"
+
+ r = readJSON(s2)
+ assert r == ((element, "'lastName", "test\ttab"), (attribute, "'firstName", "test1"), (element, "'phones", phones))
+ w = writeJSON(r)
+ assert car(w) == "{\"lastName\":\"test\\ttab\",\"@firstName\":\"test1\",\"phones\":[\"408-1234\",\"650-1234\"]}"
+
+ l4 = (("'ns1:echoString", ("'@xmlns:ns1", "http://ws.apache.org/axis2/services/echo"), ("'text", "Hello World!")),)
+ s4 = writeJSON(valuesToElements(l4))
+ assert car(s4) == "{\"ns1:echoString\":{\"@xmlns:ns1\":\"http://ws.apache.org/axis2/services/echo\",\"text\":\"Hello World!\"}}"
+
+ r4 = elementsToValues(readJSON(s4))
+ assert r4 == (("'ns1:echoString", ("'text", 'Hello World!'), ("'@xmlns:ns1", 'http://ws.apache.org/axis2/services/echo')),)
+ return True
+
+def testJSONRPC():
+ return True
+
+if __name__ == "__main__":
+ print "Testing..."
+ testJSON()
+ testJSONRPC()
+ print "OK"
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/jsonutil.py b/sca-cpp/branches/gcc-4.4/modules/wsgi/jsonutil.py
new file mode 100644
index 0000000000..ae7839df57
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/jsonutil.py
@@ -0,0 +1,140 @@
+# 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.
+
+# JSON data conversion functions
+
+try:
+ import json
+except:
+ from django.utils import simplejson as json
+
+from StringIO import StringIO
+from util import *
+from elemutil import *
+
+# Return true if a list represents a JS array
+def isJSArray(l):
+ if isNil(l):
+ return True
+ v = car(l)
+ if isSymbol(v):
+ return False
+ if isList(v):
+ if not isNil(v) and isSymbol(car(v)):
+ return False
+ return True
+
+# Converts JSON properties to values
+def jsPropertiesToValues(propertiesSoFar, o, i):
+ if isNil(i):
+ return propertiesSoFar
+ p = car(i)
+ jsv = o[p]
+ v = jsValToValue(jsv)
+
+ if isinstance(p, basestring):
+ n = str(p)
+ if n[0:1] == "@":
+ return jsPropertiesToValues(cons((attribute, "'" + n[1:], v), propertiesSoFar), o, cdr(i))
+ if isList(v) and not isJSArray(v):
+ return jsPropertiesToValues(cons(cons(element, cons("'" + n, v)), propertiesSoFar), o, cdr(i))
+ return jsPropertiesToValues(cons((element, "'" + n, v), propertiesSoFar), o, cdr(i))
+ return jsPropertiesToValues(cons(v, propertiesSoFar), o, cdr(i))
+
+# Converts a JSON val to a value
+def jsValToValue(jsv):
+ if isinstance(jsv, dict):
+ return jsPropertiesToValues((), jsv, tuple(jsv.keys()))
+ if isList(jsv):
+ return jsPropertiesToValues((), jsv, tuple(reversed(range(0, len(jsv)))))
+ if isinstance(jsv, basestring):
+ return str(jsv)
+ return jsv
+
+# Convert a list of strings representing a JSON document to a list of values
+def readJSON(l):
+ s = StringIO()
+ writeStrings(l, s)
+ val = json.loads(s.getvalue())
+ return jsValToValue(val)
+
+# Convert a list of values to JSON array elements
+def valuesToJSElements(a, l, i):
+ if isNil(l):
+ return a
+ pv = valueToJSVal(car(l))
+ a[i] = pv
+ return valuesToJSElements(a, cdr(l), i + 1)
+
+# Convert a value to a JSON value
+def valueToJSVal(v):
+ if not isList(v):
+ return v
+ if isJSArray(v):
+ return valuesToJSElements(list(range(0, len(v))), v, 0)
+ return valuesToJSProperties({}, v)
+
+# Convert a list of values to JSON properties
+def valuesToJSProperties(o, l):
+ if isNil(l):
+ return o
+ token = car(l)
+ if isTaggedList(token, attribute):
+ pv = valueToJSVal(attributeValue(token))
+ o["@" + attributeName(token)[1:]] = pv
+ elif isTaggedList(token, element):
+ if elementHasValue(token):
+ pv = valueToJSVal(elementValue(token))
+ o[elementName(token)[1:]] = pv
+ else:
+ child = {}
+ o[elementName(token)[1:]] = child
+ valuesToJSProperties(child, elementChildren(token))
+ return valuesToJSProperties(o, cdr(l))
+
+# Convert a list of values to a list of strings representing a JSON document
+def writeJSON(l):
+ jsv = valuesToJSProperties({}, l)
+ s = json.dumps(jsv, separators=(',',':'))
+ return (s,)
+
+# Convert a list + params to a JSON-RPC request
+def jsonRequest(id, func, params):
+ r = (("'id", id), ("'method", func), ("'params", params))
+ return writeJSON(valuesToElements(r))
+
+# Convert a value to a JSON-RPC result
+def jsonResult(id, val):
+ return writeJSON(valuesToElements((("'id", id), ("'result", val))))
+
+# Convert a JSON-RPC result to a value
+def jsonResultValue(s):
+ jsres = readJSON(s)
+ res = elementsToValues(jsres)
+ val = cadr(assoc("'result", res))
+ if isList(val) and not isJSArray(val):
+ return (val,)
+ return val
+
+# Return a portable function name from a JSON-RPC function name
+def funcName(f):
+ if len(f) > 7 and f.find("system.") == 0:
+ return f[7:]
+ if len(f) > 8 and f.find("Service.") == 0:
+ return f[8:]
+ return f
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/scdl.py b/sca-cpp/branches/gcc-4.4/modules/wsgi/scdl.py
new file mode 100644
index 0000000000..af332d0249
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/scdl.py
@@ -0,0 +1,167 @@
+# 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.
+
+# SCDL parsing functions
+
+from xml.etree.cElementTree import iterparse
+from util import *
+from httputil import *
+
+# Element tree utility functions, used to parse SCDL documents
+def parse(file):
+ return map(lambda x: x, iterparse(file, events=("start", "end")))
+
+def evt(e):
+ return car(e)
+
+def elt(e):
+ return cadr(e)
+
+def att(e):
+ return elt(e).attrib
+
+def text(e):
+ return elt(e).text
+
+def match(e, ev, tag):
+ return evt(e) == ev and elt(e).tag.find("}" + tag) != -1
+
+# Make a callable component
+class component:
+ def __init__(self, name, impl, svcs, refs, props):
+ self.name = name
+ self.impl = impl
+ self.mod = None
+ self.svcs = svcs
+ self.refs = refs
+ self.props = props
+ self.proxies = ()
+
+ def __call__(self, func, *args):
+ return self.mod.__getattribute__(func)(*(args + self.proxies))
+
+ def __repr__(self):
+ return repr((self.name, self.impl, self.mod, self.svcs, self.refs, self.props, self.proxies))
+
+def mkcomponent(name, impl, svcs, refs, props):
+ return component(name, impl, svcs, refs, props)
+
+# Return the Python module name of a component implementation
+def implementation(e):
+ if len(e) == 0 or match(car(e), "end", "component") == True:
+ return ""
+ if match(car(e), "start", "implementation.python") == False:
+ return implementation(cdr(e))
+ if "script" in att(car(e)):
+ s = att(car(e))["script"]
+ return s[0:len(s) - 3]
+ return None
+
+# Return the URI of a binding under a SCDL service or reference element
+def binding(e):
+ if len(e) == 0 or match(car(e), "end", "reference") == True or match(car(e), "end", "service") == True:
+ return ()
+ if match(car(e), "start", "binding.") == False:
+ return binding(cdr(e))
+ return att(car(e))["uri"]
+
+# Return the list of references under a SCDL component element
+def references(e):
+ if len(e) == 0 or match(car(e), "end", "component") == True:
+ return ()
+ if match(car(e), "start", "reference") == False:
+ return references(cdr(e))
+ if "target" in att(car(e)):
+ return cons(car(tokens(att(car(e))["target"])), references(cdr(e)))
+ return cons(binding(e), references(cdr(e)))
+
+# Return the list of properties under a SCDL component element
+def properties(e):
+ if len(e) == 0 or match(car(e), "end", "component") == True:
+ return ()
+ if match(car(e), "start", "property") == False:
+ return properties(cdr(e))
+ return cons(text(car(e)), properties(cdr(e)))
+
+# Return the list of services under a SCDL component element
+def services(e):
+ if len(e) == 0 or match(car(e), "end", "component") == True:
+ return ()
+ if match(car(e), "start", "service") == False:
+ return services(cdr(e))
+ return cons(tokens(binding(e)), services(cdr(e)))
+
+# Return the name attribute of a SCDL element
+def name(e):
+ return att(car(e))["name"]
+
+# Return the list of components under a SCDL composite element
+def components(e):
+ if len(e) == 0:
+ return ()
+ if match(car(e), "start", "component") == False:
+ return components(cdr(e))
+ n = name(e)
+ return cons(mkcomponent(n, implementation(e), cons(("components", n), services(e)), references(e), properties(e)), components(cdr(e)))
+
+# Find a component with a given name
+def nameToComponent(name, comps):
+ if comps == ():
+ return None
+ if car(comps).name == name:
+ return car(comps)
+ return nameToComponent(name, cdr(comps))
+
+# Find the URI matching a given URI in a list of service URIs
+def matchingURI(u, svcs):
+ if svcs == ():
+ return None
+ if car(svcs) == u[0:len(car(svcs))]:
+ return car(svcs)
+ return matchingURI(u, cdr(svcs))
+
+# Return the (service URI, component) pair matching a given URI
+def uriToComponent(u, comps):
+ if comps == ():
+ return (None, None)
+ m = matchingURI(u, car(comps).svcs)
+ if m != None:
+ return (m, car(comps))
+ return uriToComponent(u, cdr(comps))
+
+# Evaluate a reference, return a proxy to the resolved component or an
+# HTTP client configured with the reference target uri
+def evalReference(r, comps):
+ if r.startswith("http://") or r.startswith("https://"):
+ return mkclient(r)
+ return nameToComponent(r, comps)
+
+# Evaluate a component, resolve its implementation and references
+def evalComponent(comp, comps):
+ comp.mod = __import__(comp.impl)
+
+ # Make a list of proxy lambda functions for the component references and properties
+ # A reference proxy is the callable lambda function of the component wired to the reference
+ # A property proxy is a lambda function that returns the value of the property
+ comp.proxies = tuple(map(lambda r: evalReference(r, comps), comp.refs)) + tuple(map(lambda v: lambda: v, comp.props))
+
+ return comp
+
+# Evaluate a list of components
+def evalComponents(comps):
+ return tuple(map(lambda c: evalComponent(c, comps), comps))
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/server-test b/sca-cpp/branches/gcc-4.4/modules/wsgi/server-test
new file mode 100755
index 0000000000..9bd862c53a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/server-test
@@ -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.
+
+# Setup
+./wsgi-start target 8090 2>/dev/null
+sleep 2
+
+# Test
+./client-test 2>/dev/null
+rc=$?
+
+# Cleanup
+./wsgi-stop target 8090
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/server-test.py b/sca-cpp/branches/gcc-4.4/modules/wsgi/server-test.py
new file mode 100644
index 0000000000..9e084a3f92
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/server-test.py
@@ -0,0 +1,44 @@
+# 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.
+
+# JSON-RPC test case
+
+def echo(x):
+ return x
+
+# ATOMPub test case
+
+def get(id):
+ if id == ("index.html",):
+ return ("text/plain", ("It works!",))
+ if id == ():
+ return ("Sample Feed", "123456789",
+ ("Item", "111", (("'javaClass", "services.Item"), ("'name", "Apple"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 2.99))),
+ ("Item", "222", (("'javaClass", "services.Item"), ("'name", "Orange"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 3.55))),
+ ("Item", "333", (("'javaClass", "services.Item"), ("name", "Pear"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 1.55))))
+
+ entry = (("'javaClass", "services.Item"), ("'name", "Apple"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 2.99))
+ return ("Item", id[0], entry)
+
+def post(collection, item):
+ return ("123456789",)
+
+def put(id, item):
+ return True
+
+def delete(id):
+ return True
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/util-test b/sca-cpp/branches/gcc-4.4/modules/wsgi/util-test
new file mode 100755
index 0000000000..a1c54e80f1
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/util-test
@@ -0,0 +1,35 @@
+#!/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 util test cases
+here=`readlink -f $0`; here=`dirname $here`
+python_prefix=`cat $here/../python/python.prefix`
+
+$python_prefix/bin/python xml-test.py
+rc=$?
+if [ "$rc" = "0" ]; then
+ $python_prefix/bin/python atom-test.py
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $python_prefix/bin/python json-test.py
+ rc=$?
+fi
+
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/util.py b/sca-cpp/branches/gcc-4.4/modules/wsgi/util.py
new file mode 100644
index 0000000000..d945c7bdef
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/util.py
@@ -0,0 +1,83 @@
+# 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
+
+# Scheme-like lists
+def cons(a, b):
+ return (a,) + b
+
+def car(l):
+ return l[0]
+
+def cdr(l):
+ return l[1:]
+
+def cadr(l):
+ return car(cdr(l))
+
+def cddr(l):
+ return cdr(cdr(l))
+
+def caddr(l):
+ return car(cddr(l))
+
+def reverse(l):
+ r = list(l)
+ r.reverse()
+ return tuple(r)
+
+def isNil(l):
+ return l == ()
+
+def isSymbol(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 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))
+
+# Split a path into a list of segments
+def tokens(path):
+ return tuple(filter(lambda s: len(s) != 0, path.split("/")))
+
+# 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)
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/wiring-test b/sca-cpp/branches/gcc-4.4/modules/wsgi/wiring-test
new file mode 100755
index 0000000000..f1d0e8332f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/wiring-test
@@ -0,0 +1,75 @@
+#!/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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../http/curl.prefix`
+uri=$1
+if [ "$uri" = "" ]; then
+ uri="http://localhost:8090"
+fi
+
+# Setup
+mkdir -p tmp
+./wsgi-start target 8090 2>/dev/null
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl $uri/index.html 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/index.html
+rc=$?
+
+# Test ATOMPub
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl $uri/client/ >tmp/feed.xml 2>/dev/null
+ diff tmp/feed.xml htdocs/feed.xml
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl $uri/client/111 >tmp/entry.xml 2>/dev/null
+ diff tmp/entry.xml htdocs/entry.xml
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl $uri/client/ -X POST -H "Content-type: application/atom+xml" --data @htdocs/entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl $uri/client/111 -X PUT -H "Content-type: application/atom+xml" --data @htdocs/entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl $uri/client/111 -X DELETE 2>/dev/null
+ rc=$?
+fi
+
+# Test JSON-RPC
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl $uri/client/ -X POST -H "Content-type: application/json-rpc" --data @htdocs/json-request.txt >tmp/json-result.txt 2>/dev/null
+ diff tmp/json-result.txt htdocs/json-result.txt
+ rc=$?
+fi
+
+# Cleanup
+./wsgi-stop target 8090
+sleep 2
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/wsgi-start b/sca-cpp/branches/gcc-4.4/modules/wsgi/wsgi-start
new file mode 100755
index 0000000000..d020f3da14
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/wsgi-start
@@ -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.
+
+# Start WSGI server
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+port=$2
+
+python_prefix=`cat $here/../python/python.prefix`
+cd $root
+$python_prefix/bin/python composite.py $port &
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/wsgi-stop b/sca-cpp/branches/gcc-4.4/modules/wsgi/wsgi-stop
new file mode 100755
index 0000000000..7e12967adb
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/wsgi-stop
@@ -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.
+
+# Stop WSGI server
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+port=$2
+
+python_prefix=`cat $here/../python/python.prefix`
+py="$python_prefix/bin/python composite.py $port"
+
+kill `ps -ef | grep -v grep | grep "${py}" | awk '{ print $2 }'`
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/wsgi-test b/sca-cpp/branches/gcc-4.4/modules/wsgi/wsgi-test
new file mode 100755
index 0000000000..3dce709a3b
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/wsgi-test
@@ -0,0 +1,71 @@
+#!/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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../http/curl.prefix`
+
+# Setup
+mkdir -p tmp
+./wsgi-start target 8090 2>/dev/null
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/index.html 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/index.html
+rc=$?
+
+# Test ATOMPub
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/wsgi/ >tmp/feed.xml 2>/dev/null
+ diff tmp/feed.xml htdocs/feed.xml
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/wsgi/111 >tmp/entry.xml 2>/dev/null
+ diff tmp/entry.xml htdocs/entry.xml
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/wsgi/ -X POST -H "Content-type: application/atom+xml" --data @htdocs/entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/wsgi/111 -X PUT -H "Content-type: application/atom+xml" --data @htdocs/entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/wsgi/111 -X DELETE 2>/dev/null
+ rc=$?
+fi
+
+# Test JSON-RPC
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/wsgi/ -X POST -H "Content-type: application/json-rpc" --data @htdocs/json-request.txt >tmp/json-result.txt 2>/dev/null
+ diff tmp/json-result.txt htdocs/json-result.txt
+ rc=$?
+fi
+
+# Cleanup
+./wsgi-stop target 8090
+sleep 2
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/xml-test.py b/sca-cpp/branches/gcc-4.4/modules/wsgi/xml-test.py
new file mode 100755
index 0000000000..f60322bdc1
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/xml-test.py
@@ -0,0 +1,74 @@
+#!/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 XML handling functions
+
+import unittest
+from elemutil import *
+from xmlutil import *
+
+customerXML = \
+ "<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n" \
+ "<customer>" \
+ "<name>jdoe</name>" \
+ "<address><city>san francisco</city><state>ca</state></address>" \
+ "<account><id>1234</id><balance>1000</balance></account>" \
+ "<account><id>6789</id><balance>2000</balance></account>" \
+ "<account><id>4567</id><balance>3000</balance></account>" \
+ "</customer>\n"
+
+def testElements():
+ ad = (("'city", "san francisco"), ("'state", "ca"))
+ ac1 = (("'id", "1234"), ("'balance", 1000))
+ ac2 = (("'id", "6789"), ("'balance", 2000))
+ ac3 = (("'id", "4567"), ("'balance", 3000))
+ c = (("'customer", ("'name", "jdoe"), cons("'address", ad), ("'account", (ac1, ac2, ac3))),)
+ e = valuesToElements(c)
+ v = elementsToValues(e)
+ assert v == c
+ s = writeXML(e, True)
+ assert car(s) == customerXML
+
+ c2 = (("'customer", ("'name", "jdoe"), cons("'address", ad), cons("'account", ac1), cons("'account", ac2), cons("'account", ac3)),)
+ e2 = valuesToElements(c2);
+ v2 = elementsToValues(e2);
+ s2 = writeXML(e2, True)
+ assert car(s2) == customerXML
+
+ c3 = readXML((customerXML,))
+ v3 = elementsToValues(c3)
+ e3 = valuesToElements(v3)
+ s3 = writeXML(e3, True)
+ assert car(s3) == customerXML
+ return True
+
+def testValues():
+ l = (("'ns1:echoString", ("'@xmlns:ns1", "http://ws.apache.org/axis2/services/echo"), ("'text", "Hello World!")),)
+ e = valuesToElements(l)
+ lx = writeXML(e, True)
+ x = readXML(lx)
+ v = elementsToValues(x)
+ assert v == l
+ return True
+
+if __name__ == "__main__":
+ print "Testing..."
+ testElements()
+ testValues()
+ print "OK"
+
diff --git a/sca-cpp/branches/gcc-4.4/modules/wsgi/xmlutil.py b/sca-cpp/branches/gcc-4.4/modules/wsgi/xmlutil.py
new file mode 100644
index 0000000000..a1bc04629a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/modules/wsgi/xmlutil.py
@@ -0,0 +1,114 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# XML handling functions
+
+from StringIO import StringIO
+from xml.parsers import expat
+import xml.etree.ElementTree as et
+from util import *
+from elemutil import *
+
+# Read a list of XML attributes
+def readAttributes(a):
+ if a == ():
+ return a
+ return cons((attribute, "'" + car(car(a)), cadr(car(a))), readAttributes(cdr(a)))
+
+# Read an XML element
+def readElement(e):
+ l = (element, "'" + e.tag) + readAttributes(tuple(e.items())) + readElements(tuple(e.getchildren()))
+ if e.text == None:
+ return l
+ return l + (e.text,)
+
+# Read a list of XML elements
+def readElements(l):
+ if l == ():
+ return l
+ return cons(readElement(car(l)), readElements(cdr(l)))
+
+# Parse a list of strings representing an XML document
+class NamespaceParser(et.XMLTreeBuilder):
+ def __init__(self):
+ et.XMLTreeBuilder.__init__(self)
+ self._parser = parser = expat.ParserCreate(None)
+ parser.DefaultHandlerExpand = self._default
+ parser.StartElementHandler = self._start
+ parser.EndElementHandler = self._end
+ parser.CharacterDataHandler = self._data
+ try:
+ parser.buffer_text = 1
+ except AttributeError:
+ pass
+ try:
+ parser.ordered_attributes = 1
+ parser.specified_attributes = 1
+ parser.StartElementHandler = self._start_list
+ except AttributeError:
+ pass
+
+def parseXML(l):
+ s = StringIO()
+ writeStrings(l, s)
+ parser = NamespaceParser()
+ parser.feed(s.getvalue())
+ return parser.close()
+
+# Read a list of values from a list of strings representing an XML document
+def readXML(l):
+ e = parseXML(l)
+ return (readElement(e),)
+
+# Write a list of XML element and attribute tokens
+def expandElementValues(n, l):
+ if isNil(l):
+ return l
+ return cons(cons(element, cons(n, car(l))), expandElementValues(n, cdr(l)))
+
+def writeList(l, xml):
+ if isNil(l):
+ return xml
+ token = car(l)
+ if isTaggedList(token, attribute):
+ xml.attrib[attributeName(token)[1:]] = str(attributeValue(token))
+ elif isTaggedList(token, element):
+ if elementHasValue(token):
+ v = elementValue(token)
+ if isList(v):
+ e = expandElementValues(elementName(token), v)
+ writeList(e, xml)
+ else:
+ child = et.Element(elementName(token)[1:])
+ writeList(elementChildren(token), child)
+ xml.append(child)
+ else:
+ child = et.Element(elementName(token)[1:])
+ writeList(elementChildren(token), child)
+ xml.append(child)
+ else:
+ xml.text = str(token)
+ writeList(cdr(l), xml)
+ return xml
+
+# Convert a list of values to a list of strings representing an XML document
+def writeXML(l, xmlTag):
+ e = writeList(l, [])
+ if not xmlTag:
+ return (et.tostring(car(e)),)
+ return (et.tostring(car(e), "UTF-8") + "\n",)
+
diff --git a/sca-cpp/branches/gcc-4.4/samples/Makefile.am b/sca-cpp/branches/gcc-4.4/samples/Makefile.am
new file mode 100644
index 0000000000..de5c2d1b1e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/samples/Makefile.am
@@ -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/gcc-4.4/samples/README b/sca-cpp/branches/gcc-4.4/samples/README
new file mode 100644
index 0000000000..818a2faaf8
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/samples/README
@@ -0,0 +1,3 @@
+Apache Tuscany SCA Samples
+==========================
+
diff --git a/sca-cpp/branches/gcc-4.4/test/Makefile.am b/sca-cpp/branches/gcc-4.4/test/Makefile.am
new file mode 100644
index 0000000000..76b761c4c8
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/Makefile.am
@@ -0,0 +1,19 @@
+# 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.
+
+SUBDIRS = store-scheme store-cpp store-python store-java store-gae store-sql
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-cpp/Makefile.am b/sca-cpp/branches/gcc-4.4/test/store-cpp/Makefile.am
new file mode 100644
index 0000000000..00d037cc97
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-cpp/Makefile.am
@@ -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.
+
+test_LTLIBRARIES = libcurrency-converter.la libfruits-catalog.la libshopping-cart.la
+testdir = $(prefix)/test
+
+libcurrency_converter_la_SOURCES = currency-converter.cpp
+
+libfruits_catalog_la_SOURCES = fruits-catalog.cpp
+
+libshopping_cart_la_SOURCES = shopping-cart.cpp
+
+TESTS = server-test
diff --git a/sca-cpp/branches/gcc-4.4/test/store-cpp/currency-converter.cpp b/sca-cpp/branches/gcc-4.4/test/store-cpp/currency-converter.cpp
new file mode 100644
index 0000000000..5f0702490a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-cpp/currency-converter.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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$ */
+
+/**
+ * Currency converter component implementation.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+
+namespace tuscany {
+namespace store {
+
+/**
+ * Convert an amount from USD to a currency.
+ */
+const failable<value> convert(unused const value& from, const value& to, const value& amount) {
+ if (to == string("EUR"))
+ return value(0.70 * (double)amount);
+ return amount;
+}
+
+/**
+ * Return a currency symbol.
+ */
+const failable<value> symbol(const value& currency) {
+ if (currency == string("EUR"))
+ return value(string("E"));
+ return value(string("$"));
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+ const tuscany::value func(car(params));
+ if (func == "convert")
+ return tuscany::store::convert(cadr(params), caddr(params), cadddr(params));
+ if (func == "symbol")
+ return tuscany::store::symbol(cadr(params));
+ return tuscany::mkfailure<tuscany::value>();
+}
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/test/store-cpp/fruits-catalog.cpp b/sca-cpp/branches/gcc-4.4/test/store-cpp/fruits-catalog.cpp
new file mode 100644
index 0000000000..20f2bd35f7
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-cpp/fruits-catalog.cpp
@@ -0,0 +1,85 @@
+/*
+ * 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$ */
+
+/**
+ * Catalog component implementation.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+
+namespace tuscany {
+namespace store {
+
+/**
+ * Returns the catalog.
+ */
+struct convert {
+ const lambda<value(const list<value>&)> converter;
+ const string currency;
+ convert(const lambda<value(const list<value>&)>& converter, const string& currency) : converter(converter), currency(currency) {
+ }
+ const value operator()(const value& price) const {
+ return converter(mklist<value>("convert", string("USD"), currency, price));
+ }
+};
+
+const list<value> mkfruit(const string& name, const string& code, const string& symbol, const double price) {
+ return list<value>() +
+ mklist<value>("javaClass", string("services.Item")) + mklist<value>("name", name) + mklist<value>("currencyCode", code) + mklist<value>("currencySymbol", symbol) + mklist<value>("price", price);
+}
+
+const failable<value> get(const lambda<value(const list<value>&)> converter, const lambda<value(const list<value>&)> currencyCode) {
+ const string currency(currencyCode(list<value>()));
+ const string symbol(converter(mklist<value>("symbol", currency)));
+ const lambda<value(const value&)> conv(convert(converter, currency));
+
+ return value(list<value>() +
+ mkfruit("Apple", currency, symbol, conv(2.99)) +
+ mkfruit("Orange", currency, symbol, conv(3.55)) +
+ mkfruit("Pear", currency, symbol, conv(1.55)));
+}
+
+/**
+ * TODO remove this JSON-RPC specific function.
+ */
+const failable<value> listMethods(unused const lambda<value(const list<value>&)> converter, unused const lambda<value(const list<value>&)> currencyCode) {
+ return value(mklist<value>(string("Service.get")));
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+ const tuscany::value func(car(params));
+ if (func == "get")
+ return tuscany::store::get(cadr(params), caddr(params));
+ if (func == "listMethods")
+ return tuscany::store::listMethods(cadr(params), caddr(params));
+ return tuscany::mkfailure<tuscany::value>();
+}
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/test/store-cpp/htdocs/.htaccess b/sca-cpp/branches/gcc-4.4/test/store-cpp/htdocs/.htaccess
new file mode 100644
index 0000000000..e2e343b6b2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-cpp/htdocs/.htaccess
@@ -0,0 +1,19 @@
+#
+# 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.
+
+DirectoryIndex store.html
diff --git a/sca-cpp/branches/gcc-4.4/test/store-cpp/htdocs/store.html b/sca-cpp/branches/gcc-4.4/test/store-cpp/htdocs/store.html
new file mode 100644
index 0000000000..21eabca7a7
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-cpp/htdocs/store.html
@@ -0,0 +1,169 @@
+<!--
+ * 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>Store</title>
+
+<script type="text/javascript" src="store.js"></script>
+
+<script language="JavaScript">
+
+ //@Reference
+ var catalog = new tuscany.sca.Reference("catalog");
+
+ //@Reference
+ var shoppingCart = new tuscany.sca.Reference("shoppingCart");
+
+ //@Reference
+ var shoppingTotal = new tuscany.sca.Reference("shoppingTotal");
+
+ var catalogItems;
+
+ function catalog_getResponse(items,exception) {
+ if(exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+ // TEMP
+ shoppingTotal.gettotal(shoppingTotal_getTotalResponse);
+ }
+
+ function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ if (entries.length != 0) {
+ try {
+ shoppingTotal.gettotal(shoppingTotal_getTotalResponse);
+ }
+ catch(e){
+ alert(e);
+ }
+ }
+ }
+ }
+
+ function shoppingTotal_getTotalResponse(total,exception) {
+ if(exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+ }
+
+ function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+ }
+
+ function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<javaClass>' + catalogItems[i].javaClass + '</javaClass>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+ }
+ function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+ }
+ function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+ }
+
+ function init() {
+
+ try {
+ catalog.get(catalog_getResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ }
+ catch(e){
+ alert(e);
+ }
+ }
+
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Store</h1>
+ <div id="store">
+ <h2>Catalog</h2>
+ <form name="catalogForm">
+ <div id="catalog" ></div>
+ <br>
+ <input type="button" onClick="addToCart()" value="Add to Cart">
+ </form>
+
+ <br>
+
+ <h2>Your Shopping Cart</h2>
+ <form name="shoppingCartForm">
+ <div id="shoppingCart"></div>
+ <br>
+ <div id="total"></div>
+ <br>
+ <input type="button" onClick="checkoutCart()" value="Checkout">
+ <input type="button" onClick="deleteCart()" value="Empty">
+ <a href="../shoppingCart/">(feed)</a>
+ </form>
+ </div>
+</body>
+</html>
diff --git a/sca-cpp/branches/gcc-4.4/test/store-cpp/htdocs/store.js b/sca-cpp/branches/gcc-4.4/test/store-cpp/htdocs/store.js
new file mode 100644
index 0000000000..9cd8eb526d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-cpp/htdocs/store.js
@@ -0,0 +1,661 @@
+
+/* Apache Tuscany SCA Widget header */
+
+/*
+ * JSON-RPC JavaScript client
+ *
+ * $Id: jsonrpc.js,v 1.36.2.3 2006/03/08 15:09:37 mclark Exp $
+ *
+ * Copyright (c) 2003-2004 Jan-Klaas Kollhof
+ * Copyright (c) 2005 Michael Clark, Metaparadigm Pte Ltd
+ *
+ * This code is based on Jan-Klaas' JavaScript o lait library (jsolait).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * Modifications for Apache Tuscany:
+ * - JSONRpcClient_createMethod changed so callback is last arg
+ */
+
+/* escape a character */
+
+escapeJSONChar =
+function escapeJSONChar(c)
+{
+ if(c == "\"" || c == "\\") return "\\" + c;
+ else if (c == "\b") return "\\b";
+ else if (c == "\f") return "\\f";
+ else if (c == "\n") return "\\n";
+ else if (c == "\r") return "\\r";
+ else if (c == "\t") return "\\t";
+ var hex = c.charCodeAt(0).toString(16);
+ if(hex.length == 1) return "\\u000" + hex;
+ else if(hex.length == 2) return "\\u00" + hex;
+ else if(hex.length == 3) return "\\u0" + hex;
+ else return "\\u" + hex;
+};
+
+
+/* encode a string into JSON format */
+
+escapeJSONString =
+function escapeJSONString(s)
+{
+ /* The following should suffice but Safari's regex is b0rken
+ (doesn't support callback substitutions)
+ return "\"" + s.replace(/([^\u0020-\u007f]|[\\\"])/g,
+ escapeJSONChar) + "\"";
+ */
+
+ /* Rather inefficient way to do it */
+ var parts = s.split("");
+ for(var i=0; i < parts.length; i++) {
+ var c =parts[i];
+ if(c == '"' ||
+ c == '\\' ||
+ c.charCodeAt(0) < 32 ||
+ c.charCodeAt(0) >= 128)
+ parts[i] = escapeJSONChar(parts[i]);
+ }
+ return "\"" + parts.join("") + "\"";
+};
+
+
+/* Marshall objects to JSON format */
+
+toJSON = function toJSON(o)
+{
+ if(o == null) {
+ return "null";
+ } else if(o.constructor == String) {
+ return escapeJSONString(o);
+ } else if(o.constructor == Number) {
+ return o.toString();
+ } else if(o.constructor == Boolean) {
+ return o.toString();
+ } else if(o.constructor == Date) {
+ return '{javaClass: "java.util.Date", time: ' + o.valueOf() +'}';
+ } else if(o.constructor == Array) {
+ var v = [];
+ for(var i = 0; i < o.length; i++) v.push(toJSON(o[i]));
+ return "[" + v.join(", ") + "]";
+ } else {
+ var v = [];
+ for(attr in o) {
+ if(o[attr] == null) v.push("\"" + attr + "\": null");
+ else if(typeof o[attr] == "function"); /* skip */
+ else v.push(escapeJSONString(attr) + ": " + toJSON(o[attr]));
+ }
+ return "{" + v.join(", ") + "}";
+ }
+};
+
+
+/* JSONRpcClient constructor */
+
+JSONRpcClient =
+function JSONRpcClient_ctor(serverURL, user, pass, objectID)
+{
+ this.serverURL = serverURL;
+ this.user = user;
+ this.pass = pass;
+ this.objectID = objectID;
+
+ /* Add standard methods */
+ if(this.objectID) {
+ this._addMethods(["listMethods"]);
+ var req = this._makeRequest("listMethods", []);
+ } else {
+ this._addMethods(["system.listMethods"]);
+ var req = this._makeRequest("system.listMethods", []);
+ }
+ var m = this._sendRequest(req);
+ this._addMethods(m);
+};
+
+
+/* JSONRpcCLient.Exception */
+
+JSONRpcClient.Exception =
+function JSONRpcClient_Exception_ctor(code, message, javaStack)
+{
+ this.code = code;
+ var name;
+ if(javaStack) {
+ this.javaStack = javaStack;
+ var m = javaStack.match(/^([^:]*)/);
+ if(m) name = m[0];
+ }
+ if(name) this.name = name;
+ else this.name = "JSONRpcClientException";
+ this.message = message;
+};
+
+JSONRpcClient.Exception.CODE_REMOTE_EXCEPTION = 490;
+JSONRpcClient.Exception.CODE_ERR_CLIENT = 550;
+JSONRpcClient.Exception.CODE_ERR_PARSE = 590;
+JSONRpcClient.Exception.CODE_ERR_NOMETHOD = 591;
+JSONRpcClient.Exception.CODE_ERR_UNMARSHALL = 592;
+JSONRpcClient.Exception.CODE_ERR_MARSHALL = 593;
+
+JSONRpcClient.Exception.prototype = new Error();
+
+JSONRpcClient.Exception.prototype.toString =
+function JSONRpcClient_Exception_toString(code, msg)
+{
+ return this.name + ": " + this.message;
+};
+
+
+/* Default top level exception handler */
+
+JSONRpcClient.default_ex_handler =
+function JSONRpcClient_default_ex_handler(e) { alert(e); };
+
+
+/* Client settable variables */
+
+JSONRpcClient.toplevel_ex_handler = JSONRpcClient.default_ex_handler;
+JSONRpcClient.profile_async = false;
+JSONRpcClient.max_req_active = 1;
+JSONRpcClient.requestId = 1;
+
+
+/* JSONRpcClient implementation */
+
+JSONRpcClient.prototype._createMethod =
+function JSONRpcClient_createMethod(methodName)
+{
+ var fn=function()
+ {
+ var args = [];
+ var callback = null;
+ for(var i=0;i<arguments.length;i++) args.push(arguments[i]);
+
+/* TUSCANY change callback to be last arg instead of first to match binding.ajax
+ if(typeof args[0] == "function") callback = args.shift();
+*/
+ if(typeof args[arguments.length-1] == "function") callback = args.pop();
+
+ var req = fn.client._makeRequest.call(fn.client, fn.methodName,
+ args, callback);
+ if(callback == null) {
+ return fn.client._sendRequest.call(fn.client, req);
+ } else {
+ JSONRpcClient.async_requests.push(req);
+ JSONRpcClient.kick_async();
+ return req.requestId;
+ }
+ };
+ fn.client = this;
+ fn.methodName = methodName;
+ return fn;
+};
+
+JSONRpcClient.prototype._addMethods =
+function JSONRpcClient_addMethods(methodNames)
+{
+ for(var i=0; i<methodNames.length; i++) {
+ var obj = this;
+ var names = methodNames[i].split(".");
+ for(var n=0; n<names.length-1; n++) {
+ var name = names[n];
+ if(obj[name]) {
+ obj = obj[name];
+ } else {
+ obj[name] = new Object();
+ obj = obj[name];
+ }
+ }
+ var name = names[names.length-1];
+ if(!obj[name]) {
+ var method = this._createMethod(methodNames[i]);
+ obj[name] = method;
+ }
+ }
+};
+
+JSONRpcClient._getCharsetFromHeaders =
+function JSONRpcClient_getCharsetFromHeaders(http)
+{
+ try {
+ var contentType = http.getResponseHeader("Content-type");
+ var parts = contentType.split(/\s*;\s*/);
+ for(var i =0; i < parts.length; i++) {
+ if(parts[i].substring(0, 8) == "charset=")
+ return parts[i].substring(8, parts[i].length);
+ }
+ } catch (e) {}
+ return "UTF-8"; /* default */
+};
+
+/* Async queue globals */
+JSONRpcClient.async_requests = [];
+JSONRpcClient.async_inflight = {};
+JSONRpcClient.async_responses = [];
+JSONRpcClient.async_timeout = null;
+JSONRpcClient.num_req_active = 0;
+
+JSONRpcClient._async_handler =
+function JSONRpcClient_async_handler()
+{
+ JSONRpcClient.async_timeout = null;
+
+ while(JSONRpcClient.async_responses.length > 0) {
+ var res = JSONRpcClient.async_responses.shift();
+ if(res.canceled) continue;
+ if(res.profile) res.profile.dispatch = new Date();
+ try {
+ res.cb(res.result, res.ex, res.profile);
+ } catch(e) {
+ JSONRpcClient.toplevel_ex_handler(e);
+ }
+ }
+
+ while(JSONRpcClient.async_requests.length > 0 &&
+ JSONRpcClient.num_req_active < JSONRpcClient.max_req_active) {
+ var req = JSONRpcClient.async_requests.shift();
+ if(req.canceled) continue;
+ req.client._sendRequest.call(req.client, req);
+ }
+};
+
+JSONRpcClient.kick_async =
+function JSONRpcClient_kick_async()
+{
+ if(JSONRpcClient.async_timeout == null)
+ JSONRpcClient.async_timeout =
+ setTimeout(JSONRpcClient._async_handler, 0);
+};
+
+JSONRpcClient.cancelRequest =
+function JSONRpcClient_cancelRequest(requestId)
+{
+ /* If it is in flight then mark it as canceled in the inflight map
+ and the XMLHttpRequest callback will discard the reply. */
+ if(JSONRpcClient.async_inflight[requestId]) {
+ JSONRpcClient.async_inflight[requestId].canceled = true;
+ return true;
+ }
+
+ /* If its not in flight yet then we can just mark it as canceled in
+ the the request queue and it will get discarded before being sent. */
+ for(var i in JSONRpcClient.async_requests) {
+ if(JSONRpcClient.async_requests[i].requestId == requestId) {
+ JSONRpcClient.async_requests[i].canceled = true;
+ return true;
+ }
+ }
+
+ /* It may have returned from the network and be waiting for its callback
+ to be dispatched, so mark it as canceled in the response queue
+ and the response will get discarded before calling the callback. */
+ for(var i in JSONRpcClient.async_responses) {
+ if(JSONRpcClient.async_responses[i].requestId == requestId) {
+ JSONRpcClient.async_responses[i].canceled = true;
+ return true;
+ }
+ }
+
+ return false;
+};
+
+JSONRpcClient.prototype._makeRequest =
+function JSONRpcClient_makeRequest(methodName, args, cb)
+{
+ var req = {};
+ req.client = this;
+ req.requestId = JSONRpcClient.requestId++;
+
+ var obj = {};
+ obj.id = req.requestId;
+ if (this.objectID)
+ obj.method = ".obj#" + this.objectID + "." + methodName;
+ else
+ obj.method = methodName;
+ obj.params = args;
+
+ if (cb) req.cb = cb;
+ if (JSONRpcClient.profile_async)
+ req.profile = { "submit": new Date() };
+ req.data = toJSON(obj);
+
+ return req;
+};
+
+JSONRpcClient.prototype._sendRequest =
+function JSONRpcClient_sendRequest(req)
+{
+ if(req.profile) req.profile.start = new Date();
+
+ /* Get free http object from the pool */
+ var http = JSONRpcClient.poolGetHTTPRequest();
+ JSONRpcClient.num_req_active++;
+
+ /* Send the request */
+ if (typeof(this.user) == "undefined") {
+ http.open("POST", this.serverURL, (req.cb != null));
+ } else {
+ http.open("POST", this.serverURL, (req.cb != null), this.user, this.pass);
+ }
+
+ /* setRequestHeader is missing in Opera 8 Beta */
+ try { http.setRequestHeader("Content-type", "text/plain"); } catch(e) {}
+
+ /* Construct call back if we have one */
+ if(req.cb) {
+ var self = this;
+ http.onreadystatechange = function() {
+ if(http.readyState == 4) {
+ http.onreadystatechange = function () {};
+ var res = { "cb": req.cb, "result": null, "ex": null};
+ if (req.profile) {
+ res.profile = req.profile;
+ res.profile.end = new Date();
+ }
+ try { res.result = self._handleResponse(http); }
+ catch(e) { res.ex = e; }
+ if(!JSONRpcClient.async_inflight[req.requestId].canceled)
+ JSONRpcClient.async_responses.push(res);
+ delete JSONRpcClient.async_inflight[req.requestId];
+ JSONRpcClient.kick_async();
+ }
+ };
+ } else {
+ http.onreadystatechange = function() {};
+ }
+
+ JSONRpcClient.async_inflight[req.requestId] = req;
+
+ try {
+ http.send(req.data);
+ } catch(e) {
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+ throw new JSONRpcClient.Exception
+ (JSONRpcClient.Exception.CODE_ERR_CLIENT, "Connection failed");
+ }
+
+ if(!req.cb) return this._handleResponse(http);
+};
+
+JSONRpcClient.prototype._handleResponse =
+function JSONRpcClient_handleResponse(http)
+{
+ /* Get the charset */
+ if(!this.charset) {
+ this.charset = JSONRpcClient._getCharsetFromHeaders(http);
+ }
+
+ /* Get request results */
+ var status, statusText, data;
+ try {
+ status = http.status;
+ statusText = http.statusText;
+ data = http.responseText;
+ } catch(e) {
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+ JSONRpcClient.kick_async();
+ throw new JSONRpcClient.Exception
+ (JSONRpcClient.Exception.CODE_ERR_CLIENT, "Connection failed");
+ }
+
+ /* Return http object to the pool; */
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+
+ /* Unmarshall the response */
+ if(status != 200) {
+ throw new JSONRpcClient.Exception(status, statusText);
+ }
+ var obj;
+ try {
+ eval("obj = " + data);
+ } catch(e) {
+ throw new JSONRpcClient.Exception(550, "error parsing result");
+ }
+ if(obj.error)
+ throw new JSONRpcClient.Exception(obj.error.code, obj.error.msg,
+ obj.error.trace);
+ var res = obj.result;
+
+ /* Handle CallableProxy */
+ if(res && res.objectID && res.JSONRPCType == "CallableReference")
+ return new JSONRpcClient(this.serverURL, this.user,
+ this.pass, res.objectID);
+
+ return res;
+};
+
+
+/* XMLHttpRequest wrapper code */
+
+/* XMLHttpRequest pool globals */
+JSONRpcClient.http_spare = [];
+JSONRpcClient.http_max_spare = 8;
+
+JSONRpcClient.poolGetHTTPRequest =
+function JSONRpcClient_pool_getHTTPRequest()
+{
+ if(JSONRpcClient.http_spare.length > 0) {
+ return JSONRpcClient.http_spare.pop();
+ }
+ return JSONRpcClient.getHTTPRequest();
+};
+
+JSONRpcClient.poolReturnHTTPRequest =
+function JSONRpcClient_poolReturnHTTPRequest(http)
+{
+ if(JSONRpcClient.http_spare.length >= JSONRpcClient.http_max_spare)
+ delete http;
+ else
+ JSONRpcClient.http_spare.push(http);
+};
+
+JSONRpcClient.msxmlNames = [ "MSXML2.XMLHTTP.5.0",
+ "MSXML2.XMLHTTP.4.0",
+ "MSXML2.XMLHTTP.3.0",
+ "MSXML2.XMLHTTP",
+ "Microsoft.XMLHTTP" ];
+
+JSONRpcClient.getHTTPRequest =
+function JSONRpcClient_getHTTPRequest()
+{
+ /* Mozilla XMLHttpRequest */
+ try {
+ JSONRpcClient.httpObjectName = "XMLHttpRequest";
+ return new XMLHttpRequest();
+ } catch(e) {}
+
+ /* Microsoft MSXML ActiveX */
+ for (var i=0;i < JSONRpcClient.msxmlNames.length; i++) {
+ try {
+ JSONRpcClient.httpObjectName = JSONRpcClient.msxmlNames[i];
+ return new ActiveXObject(JSONRpcClient.msxmlNames[i]);
+ } catch (e) {}
+ }
+
+ /* None found */
+ JSONRpcClient.httpObjectName = null;
+ throw new JSONRpcClient.Exception(0, "Can't create XMLHttpRequest object");
+};
+
+
+/*
+ * 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.
+ */
+
+function AtomClient(uri) {
+
+ this.msxmlNames = [ "MSXML2.XMLHTTP.5.0",
+ "MSXML2.XMLHTTP.4.0",
+ "MSXML2.XMLHTTP.3.0",
+ "MSXML2.XMLHTTP",
+ "Microsoft.XMLHTTP" ];
+
+ this.uri=uri;
+
+ this.get = function(id, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("get - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("GET", uri + '/' + id, true);
+ xhr.send(null);
+ }
+
+ this.post = function (entry, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 201) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("post - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("POST", uri, true);
+ xhr.setRequestHeader("Content-Type", "application/atom+xml");
+ xhr.send(entry);
+ }
+
+ this.put = function (id, entry, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("put - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("PUT", uri + '/' + id, true);
+ xhr.setRequestHeader("Content-Type", "application/atom+xml");
+ xhr.send(entry);
+ }
+
+ this.del = function (id, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ if (responseFunction != null) responseFunction();
+ } else {
+ alert("delete - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("DELETE", uri + '/' + id, true);
+ xhr.send(null);
+ }
+ this.createXMLHttpRequest = function () {
+ /* Mozilla XMLHttpRequest */
+ try {return new XMLHttpRequest();} catch(e) {}
+
+ /* Microsoft MSXML ActiveX */
+ for (var i=0;i < this.msxmlNames.length; i++) {
+ try {return new ActiveXObject(this.msxmlNames[i]);} catch (e) {}
+ }
+ alert("XML http request not supported");
+ return null;
+ }
+ if (typeof DOMParser == "undefined") {
+ DOMParser = function () {}
+
+ DOMParser.prototype.parseFromString = function (str, contentType) {
+ if (typeof ActiveXObject != "undefined") {
+ var d = new ActiveXObject("MSXML.DomDocument");
+ d.loadXML(str);
+ return d;
+ } else if (typeof XMLHttpRequest != "undefined") {
+ var req = new XMLHttpRequest;
+ req.open("GET", "data:" + (contentType || "application/xml") +
+ ";charset=utf-8," + encodeURIComponent(str), false);
+ if (req.overrideMimeType) {
+ req.overrideMimeType(contentType);
+ }
+ req.send(null);
+ return req.responseXML;
+ }
+ }
+ }
+}
+
+
+
+/* Tuscany Reference/Property injection code */
+
+if (!tuscany) {
+var tuscany = {};
+}
+if (!tuscany.sca) {
+tuscany.sca = {};
+}
+
+tuscany.sca.propertyMap = new String();
+tuscany.sca.Property = function (name) {
+ return tuscany.sca.propertyMap[name];
+}
+
+tuscany.sca.referenceMap = new Object();
+tuscany.sca.referenceMap.catalog = new JSONRpcClient("/catalog").Service;
+tuscany.sca.referenceMap.shoppingCart = new AtomClient("/shoppingCart");
+tuscany.sca.referenceMap.shoppingTotal = new JSONRpcClient("/total").Service;
+tuscany.sca.Reference = function (name) {
+ return tuscany.sca.referenceMap[name];
+}
+
+/** End of Apache Tuscany SCA Widget */
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-cpp/server-test b/sca-cpp/branches/gcc-4.4/test/store-cpp/server-test
new file mode 100755
index 0000000000..d2013f6892
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-cpp/server-test
@@ -0,0 +1,40 @@
+#!/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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/store.html 2>/dev/null >tmp/store.html
+diff tmp/store.html htdocs/store.html
+rc=$?
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/test/store-cpp/shopping-cart.cpp b/sca-cpp/branches/gcc-4.4/test/store-cpp/shopping-cart.cpp
new file mode 100644
index 0000000000..eaad0d3c77
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-cpp/shopping-cart.cpp
@@ -0,0 +1,152 @@
+/*
+ * 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$ */
+
+/**
+ * Shopping cart component implementation.
+ */
+
+#include <apr_general.h>
+#include <apr_uuid.h>
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+
+namespace tuscany {
+namespace store {
+
+const string cartId("1234");
+
+/**
+ * Get the shopping cart from the cache. Return an empty
+ * cart if not found.
+ */
+const list<value> getcart(const value& id, const lambda<value(const list<value>&)> cache) {
+ const value cart = cache(mklist<value>("get", mklist<value>(id)));
+ if (isNil(cart))
+ return value(list<value>());
+ return (list<value>)cart;
+}
+
+/**
+ * Returns a UUID.
+ */
+const value uuid() {
+ apr_uuid_t uuid;
+ apr_uuid_get(&uuid);
+ char buf[APR_UUID_FORMATTED_LENGTH];
+ apr_uuid_format(buf, &uuid);
+ return string(buf, APR_UUID_FORMATTED_LENGTH);
+}
+
+/**
+ * Post a new item to the cart. Create a new cart if necessary.
+ */
+const failable<value> post(unused const list<value>& collection, const value& item, const lambda<value(const list<value>&)> cache) {
+ const value id(uuid());
+ const list<value> newItem(mklist<value>(car<value>(item), id, caddr<value>(item)));
+ const list<value> cart(cons<value>(newItem, getcart(cartId, cache)));
+ cache(mklist<value>("put", mklist<value>(cartId), cart));
+ return value(mklist<value>(id));
+}
+
+/**
+ * Find an item in the cart.
+ */
+const value find(const value& id, const list<value>& cart) {
+ if (isNil(cart))
+ return cons<value>(string("Item"), mklist<value>("0", list<value>()));
+ if (id == cadr<value>(car(cart)))
+ return car(cart);
+ return find(id, cdr(cart));
+}
+
+/**
+ * Return items from the cart.
+ */
+const failable<value> get(const list<value>& id, const lambda<value(const list<value>&)> cache) {
+ if (isNil(id))
+ return value(append(mklist<value>(string("Your Cart"), cartId), getcart(cartId, cache)));
+ return find(car(id), getcart(cartId, cache));
+}
+
+/**
+ * Delete items from the cart.
+ */
+const failable<value> del(const list<value>& id, unused const lambda<value(const list<value>&)> cache) {
+ if (isNil(id))
+ return cache(mklist<value>("delete", mklist<value>(cartId)));
+ return value(true);
+}
+
+/**
+ * Return the price of an item.
+ */
+const double price(const list<value>& item) {
+ return cadr<value>(assoc<value>("price", caddr(item)));
+}
+
+/**
+ * Sum the prices of a list of items.
+ */
+const double sum(const list<value>& items) {
+ if (isNil(items))
+ return 0;
+ return price(car(items)) + sum(cdr(items));
+}
+
+/**
+ * Return the total price of the items in the cart.
+ */
+const failable<value> gettotal(const lambda<value(const list<value>&)> cache) {
+ const list<value> cart(getcart(cartId, cache));
+ return value(sum(cart));
+}
+
+/**
+ * TODO remove this JSON-RPC specific function.
+ */
+const failable<value> listMethods(unused const lambda<value(const list<value>&)> converter) {
+ return value(mklist<value>(string("Service.gettotal")));
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+ const tuscany::value func(car(params));
+ if (func == "post")
+ return tuscany::store::post(cadr(params), caddr(params), cadddr(params));
+ if (func == "get")
+ return tuscany::store::get(cadr(params), caddr(params));
+ if (func == "delete")
+ return tuscany::store::del(cadr(params), caddr(params));
+ if (func == "gettotal")
+ return tuscany::store::gettotal(cadr(params));
+ if (func == "listMethods")
+ return tuscany::store::listMethods(cadr(params));
+ return tuscany::mkfailure<tuscany::value>();
+}
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/test/store-cpp/ssl-start b/sca-cpp/branches/gcc-4.4/test/store-cpp/ssl-start
new file mode 100755
index 0000000000..9cb5b88974
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-cpp/ssl-start
@@ -0,0 +1,34 @@
+#!/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-ca-conf tmp localhost
+../../modules/http/httpd-cert-conf tmp localhost
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/http/httpd-ssl-conf tmp localhost 8453 htdocs
+../../modules/server/server-conf tmp
+../../modules/server/cpp-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sca-cpp/branches/gcc-4.4/test/store-cpp/start b/sca-cpp/branches/gcc-4.4/test/store-cpp/start
new file mode 100755
index 0000000000..7b9c0d6379
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-cpp/start
@@ -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.
+
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/server/server-conf tmp
+../../modules/server/cpp-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sca-cpp/branches/gcc-4.4/test/store-cpp/stop b/sca-cpp/branches/gcc-4.4/test/store-cpp/stop
new file mode 100755
index 0000000000..a59273b8ed
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-cpp/stop
@@ -0,0 +1,21 @@
+#!/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
+../../components/cache/memcached-stop
diff --git a/sca-cpp/branches/gcc-4.4/test/store-cpp/store.composite b/sca-cpp/branches/gcc-4.4/test/store-cpp/store.composite
new file mode 100644
index 0000000000..056f7b4c68
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-cpp/store.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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Catalog">
+ <implementation.cpp path=".libs" library="libfruits-catalog"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <implementation.cpp path=".libs" library="libshopping-cart"/>
+ <service name="ShoppingCart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <implementation.cpp path=".libs" library="libcurrency-converter"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+ <component name="Cache">
+ <implementation.cpp path="../../components/cache/.libs" library="libmemcache"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/Makefile.am b/sca-cpp/branches/gcc-4.4/test/store-gae/Makefile.am
new file mode 100644
index 0000000000..bb39293d21
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/Makefile.am
@@ -0,0 +1,35 @@
+# 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
+if WANT_GAE
+
+noinst_DATA = target.stamp
+
+target.stamp: app.yaml *.py *.composite $(top_builddir)/modules/wsgi/*.py htdocs/*
+ mkdir -p target
+ cp app.yaml *.py *.composite `ls $(top_builddir)/modules/wsgi/*.py | grep -v "\-test"` target
+ cp -R htdocs target/htdocs
+ touch target.stamp
+
+clean-local:
+ rm -rf target.stamp target
+
+TESTS = server-test
+
+endif
+endif
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/app.yaml b/sca-cpp/branches/gcc-4.4/test/store-gae/app.yaml
new file mode 100644
index 0000000000..e5807c233a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/app.yaml
@@ -0,0 +1,52 @@
+# 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.
+
+application: sca-store
+version: 1
+runtime: python
+api_version: 1
+skip_files:
+- ^(.*/)?app\.yaml
+- ^(.*/)?app\.yml
+- ^(.*/)?index\.yaml
+- ^(.*/)?index\.yml
+- ^(.*/)?#.*#
+- ^(.*/)?.*~
+- ^(.*/)?.*\.py[co]
+- ^(.*/)?.*/RCS/.*
+- ^(.*/)?\..*
+- ^(.*/)?.*-test$
+- ^(.*/)?.*\.cpp$
+- ^(.*/)?.*\.o$
+- ^(.*/)?core$
+- ^(.*/)?.*\.out$
+- ^(.*/)?.*\.log$
+- ^(.*/)?Makefile.*
+- ^(.*/)?tmp/.*
+- ^(.*/)?wsgi-start
+- ^(.*/)?wsgi-stop
+
+handlers:
+- url: /(.*\.(html|png))
+ static_files: htdocs/\1
+ upload: htdocs/(.*\.(html|png))
+ secure: always
+
+- url: /.*
+ script: composite.py
+ secure: always
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/currency-converter.py b/sca-cpp/branches/gcc-4.4/test/store-gae/currency-converter.py
new file mode 100644
index 0000000000..2fded8f616
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/currency-converter.py
@@ -0,0 +1,29 @@
+# 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.
+
+# Currency converter implementation
+
+def convert(fr, to, amount):
+ if to == "EUR":
+ return amount * 0.70
+ return amount
+
+def symbol(currency):
+ if currency == "EUR":
+ return "E"
+ return "$"
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/domain-backend.composite b/sca-cpp/branches/gcc-4.4/test/store-gae/domain-backend.composite
new file mode 100644
index 0000000000..a543b9a6b5
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/domain-backend.composite
@@ -0,0 +1,32 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store-backend">
+
+ <component name="Cache">
+ <implementation.python script="gmemcache.py"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/domain-frontend.composite b/sca-cpp/branches/gcc-4.4/test/store-gae/domain-frontend.composite
new file mode 100644
index 0000000000..a183c84a76
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/domain-frontend.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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store-frontend">
+
+ <component name="Store">
+ <t:implementation.python script="store.py"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog">
+ <t:binding.http uri="https://sca-store-backend.appspot.com/catalog"/>
+ </reference>
+ <reference name="shoppingCart">
+ <t:binding.http uri="https://sca-store-backend.appspot.com/shoppingCart"/>
+ </reference>
+ <reference name="shoppingTotal">
+ <t:binding.http uri="https://sca-store-backend.appspot.com/shoppingCart"/>
+ </reference>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.python script="fruits-catalog.py"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.python script="shopping-cart.py"/>
+ <service name="ShoppingCart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache">
+ <t:binding.http uri="https://sca-store-backend.appspot.com/cache"/>
+ </reference>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.python script="currency-converter.py"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/domain-single.composite b/sca-cpp/branches/gcc-4.4/test/store-gae/domain-single.composite
new file mode 100644
index 0000000000..41ce77bedd
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/domain-single.composite
@@ -0,0 +1,69 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.python script="store.py"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.python script="fruits-catalog.py"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.python script="shopping-cart.py"/>
+ <service name="ShoppingCart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.python script="currency-converter.py"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+ <component name="Cache">
+ <implementation.python script="gmemcache.py"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/domain.composite b/sca-cpp/branches/gcc-4.4/test/store-gae/domain.composite
new file mode 100644
index 0000000000..41ce77bedd
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/domain.composite
@@ -0,0 +1,69 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.python script="store.py"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.python script="fruits-catalog.py"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.python script="shopping-cart.py"/>
+ <service name="ShoppingCart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.python script="currency-converter.py"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+ <component name="Cache">
+ <implementation.python script="gmemcache.py"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/fruits-catalog.py b/sca-cpp/branches/gcc-4.4/test/store-gae/fruits-catalog.py
new file mode 100644
index 0000000000..75c18f5f99
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/fruits-catalog.py
@@ -0,0 +1,34 @@
+# 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.
+
+# Catalog implementation
+
+def get(converter, currencyCode):
+ code = currencyCode()
+ def convert(price):
+ return converter("convert", "USD", code, price)
+ symbol = converter("symbol", code)
+ return (
+ (("'javaClass", "services.Item"), ("'name", "Apple"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(2.99))),
+ (("'javaClass", "services.Item"), ("'name", "Orange"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(3.55))),
+ (("'javaClass", "services.Item"), ("'name", "Pear"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(1.55)))
+ )
+
+# TODO remove these JSON-RPC specific functions
+def listMethods(converter, currencyCode):
+ return ("Service.get",)
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/gmemcache.py b/sca-cpp/branches/gcc-4.4/test/store-gae/gmemcache.py
new file mode 100644
index 0000000000..61f1dc3486
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/gmemcache.py
@@ -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.
+
+# Google AppEngine Memcached based cache implementation
+import uuid
+from google.appengine.api import memcache
+
+# Post a new item to the cache
+def post(collection, item):
+ id = collection + (str(uuid.uuid1()),)
+ r = memcache.add(repr(id), item, 600)
+ if r == False:
+ return None
+ return id
+
+# Get items from the cache
+def get(id):
+ item = memcache.get(repr(id))
+ return item
+
+# Update an item in the cache
+def put(id, item):
+ return memcache.set(repr(id), item, 600)
+
+# Delete items from the cache
+def delete(id):
+ r = memcache.delete(repr(id))
+ if r != 2:
+ return False
+ return True
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/htdocs/store.html b/sca-cpp/branches/gcc-4.4/test/store-gae/htdocs/store.html
new file mode 100644
index 0000000000..21eabca7a7
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/htdocs/store.html
@@ -0,0 +1,169 @@
+<!--
+ * 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>Store</title>
+
+<script type="text/javascript" src="store.js"></script>
+
+<script language="JavaScript">
+
+ //@Reference
+ var catalog = new tuscany.sca.Reference("catalog");
+
+ //@Reference
+ var shoppingCart = new tuscany.sca.Reference("shoppingCart");
+
+ //@Reference
+ var shoppingTotal = new tuscany.sca.Reference("shoppingTotal");
+
+ var catalogItems;
+
+ function catalog_getResponse(items,exception) {
+ if(exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+ // TEMP
+ shoppingTotal.gettotal(shoppingTotal_getTotalResponse);
+ }
+
+ function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ if (entries.length != 0) {
+ try {
+ shoppingTotal.gettotal(shoppingTotal_getTotalResponse);
+ }
+ catch(e){
+ alert(e);
+ }
+ }
+ }
+ }
+
+ function shoppingTotal_getTotalResponse(total,exception) {
+ if(exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+ }
+
+ function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+ }
+
+ function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<javaClass>' + catalogItems[i].javaClass + '</javaClass>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+ }
+ function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+ }
+ function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+ }
+
+ function init() {
+
+ try {
+ catalog.get(catalog_getResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ }
+ catch(e){
+ alert(e);
+ }
+ }
+
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Store</h1>
+ <div id="store">
+ <h2>Catalog</h2>
+ <form name="catalogForm">
+ <div id="catalog" ></div>
+ <br>
+ <input type="button" onClick="addToCart()" value="Add to Cart">
+ </form>
+
+ <br>
+
+ <h2>Your Shopping Cart</h2>
+ <form name="shoppingCartForm">
+ <div id="shoppingCart"></div>
+ <br>
+ <div id="total"></div>
+ <br>
+ <input type="button" onClick="checkoutCart()" value="Checkout">
+ <input type="button" onClick="deleteCart()" value="Empty">
+ <a href="../shoppingCart/">(feed)</a>
+ </form>
+ </div>
+</body>
+</html>
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/htdocs/store.js b/sca-cpp/branches/gcc-4.4/test/store-gae/htdocs/store.js
new file mode 100644
index 0000000000..9cd8eb526d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/htdocs/store.js
@@ -0,0 +1,661 @@
+
+/* Apache Tuscany SCA Widget header */
+
+/*
+ * JSON-RPC JavaScript client
+ *
+ * $Id: jsonrpc.js,v 1.36.2.3 2006/03/08 15:09:37 mclark Exp $
+ *
+ * Copyright (c) 2003-2004 Jan-Klaas Kollhof
+ * Copyright (c) 2005 Michael Clark, Metaparadigm Pte Ltd
+ *
+ * This code is based on Jan-Klaas' JavaScript o lait library (jsolait).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * Modifications for Apache Tuscany:
+ * - JSONRpcClient_createMethod changed so callback is last arg
+ */
+
+/* escape a character */
+
+escapeJSONChar =
+function escapeJSONChar(c)
+{
+ if(c == "\"" || c == "\\") return "\\" + c;
+ else if (c == "\b") return "\\b";
+ else if (c == "\f") return "\\f";
+ else if (c == "\n") return "\\n";
+ else if (c == "\r") return "\\r";
+ else if (c == "\t") return "\\t";
+ var hex = c.charCodeAt(0).toString(16);
+ if(hex.length == 1) return "\\u000" + hex;
+ else if(hex.length == 2) return "\\u00" + hex;
+ else if(hex.length == 3) return "\\u0" + hex;
+ else return "\\u" + hex;
+};
+
+
+/* encode a string into JSON format */
+
+escapeJSONString =
+function escapeJSONString(s)
+{
+ /* The following should suffice but Safari's regex is b0rken
+ (doesn't support callback substitutions)
+ return "\"" + s.replace(/([^\u0020-\u007f]|[\\\"])/g,
+ escapeJSONChar) + "\"";
+ */
+
+ /* Rather inefficient way to do it */
+ var parts = s.split("");
+ for(var i=0; i < parts.length; i++) {
+ var c =parts[i];
+ if(c == '"' ||
+ c == '\\' ||
+ c.charCodeAt(0) < 32 ||
+ c.charCodeAt(0) >= 128)
+ parts[i] = escapeJSONChar(parts[i]);
+ }
+ return "\"" + parts.join("") + "\"";
+};
+
+
+/* Marshall objects to JSON format */
+
+toJSON = function toJSON(o)
+{
+ if(o == null) {
+ return "null";
+ } else if(o.constructor == String) {
+ return escapeJSONString(o);
+ } else if(o.constructor == Number) {
+ return o.toString();
+ } else if(o.constructor == Boolean) {
+ return o.toString();
+ } else if(o.constructor == Date) {
+ return '{javaClass: "java.util.Date", time: ' + o.valueOf() +'}';
+ } else if(o.constructor == Array) {
+ var v = [];
+ for(var i = 0; i < o.length; i++) v.push(toJSON(o[i]));
+ return "[" + v.join(", ") + "]";
+ } else {
+ var v = [];
+ for(attr in o) {
+ if(o[attr] == null) v.push("\"" + attr + "\": null");
+ else if(typeof o[attr] == "function"); /* skip */
+ else v.push(escapeJSONString(attr) + ": " + toJSON(o[attr]));
+ }
+ return "{" + v.join(", ") + "}";
+ }
+};
+
+
+/* JSONRpcClient constructor */
+
+JSONRpcClient =
+function JSONRpcClient_ctor(serverURL, user, pass, objectID)
+{
+ this.serverURL = serverURL;
+ this.user = user;
+ this.pass = pass;
+ this.objectID = objectID;
+
+ /* Add standard methods */
+ if(this.objectID) {
+ this._addMethods(["listMethods"]);
+ var req = this._makeRequest("listMethods", []);
+ } else {
+ this._addMethods(["system.listMethods"]);
+ var req = this._makeRequest("system.listMethods", []);
+ }
+ var m = this._sendRequest(req);
+ this._addMethods(m);
+};
+
+
+/* JSONRpcCLient.Exception */
+
+JSONRpcClient.Exception =
+function JSONRpcClient_Exception_ctor(code, message, javaStack)
+{
+ this.code = code;
+ var name;
+ if(javaStack) {
+ this.javaStack = javaStack;
+ var m = javaStack.match(/^([^:]*)/);
+ if(m) name = m[0];
+ }
+ if(name) this.name = name;
+ else this.name = "JSONRpcClientException";
+ this.message = message;
+};
+
+JSONRpcClient.Exception.CODE_REMOTE_EXCEPTION = 490;
+JSONRpcClient.Exception.CODE_ERR_CLIENT = 550;
+JSONRpcClient.Exception.CODE_ERR_PARSE = 590;
+JSONRpcClient.Exception.CODE_ERR_NOMETHOD = 591;
+JSONRpcClient.Exception.CODE_ERR_UNMARSHALL = 592;
+JSONRpcClient.Exception.CODE_ERR_MARSHALL = 593;
+
+JSONRpcClient.Exception.prototype = new Error();
+
+JSONRpcClient.Exception.prototype.toString =
+function JSONRpcClient_Exception_toString(code, msg)
+{
+ return this.name + ": " + this.message;
+};
+
+
+/* Default top level exception handler */
+
+JSONRpcClient.default_ex_handler =
+function JSONRpcClient_default_ex_handler(e) { alert(e); };
+
+
+/* Client settable variables */
+
+JSONRpcClient.toplevel_ex_handler = JSONRpcClient.default_ex_handler;
+JSONRpcClient.profile_async = false;
+JSONRpcClient.max_req_active = 1;
+JSONRpcClient.requestId = 1;
+
+
+/* JSONRpcClient implementation */
+
+JSONRpcClient.prototype._createMethod =
+function JSONRpcClient_createMethod(methodName)
+{
+ var fn=function()
+ {
+ var args = [];
+ var callback = null;
+ for(var i=0;i<arguments.length;i++) args.push(arguments[i]);
+
+/* TUSCANY change callback to be last arg instead of first to match binding.ajax
+ if(typeof args[0] == "function") callback = args.shift();
+*/
+ if(typeof args[arguments.length-1] == "function") callback = args.pop();
+
+ var req = fn.client._makeRequest.call(fn.client, fn.methodName,
+ args, callback);
+ if(callback == null) {
+ return fn.client._sendRequest.call(fn.client, req);
+ } else {
+ JSONRpcClient.async_requests.push(req);
+ JSONRpcClient.kick_async();
+ return req.requestId;
+ }
+ };
+ fn.client = this;
+ fn.methodName = methodName;
+ return fn;
+};
+
+JSONRpcClient.prototype._addMethods =
+function JSONRpcClient_addMethods(methodNames)
+{
+ for(var i=0; i<methodNames.length; i++) {
+ var obj = this;
+ var names = methodNames[i].split(".");
+ for(var n=0; n<names.length-1; n++) {
+ var name = names[n];
+ if(obj[name]) {
+ obj = obj[name];
+ } else {
+ obj[name] = new Object();
+ obj = obj[name];
+ }
+ }
+ var name = names[names.length-1];
+ if(!obj[name]) {
+ var method = this._createMethod(methodNames[i]);
+ obj[name] = method;
+ }
+ }
+};
+
+JSONRpcClient._getCharsetFromHeaders =
+function JSONRpcClient_getCharsetFromHeaders(http)
+{
+ try {
+ var contentType = http.getResponseHeader("Content-type");
+ var parts = contentType.split(/\s*;\s*/);
+ for(var i =0; i < parts.length; i++) {
+ if(parts[i].substring(0, 8) == "charset=")
+ return parts[i].substring(8, parts[i].length);
+ }
+ } catch (e) {}
+ return "UTF-8"; /* default */
+};
+
+/* Async queue globals */
+JSONRpcClient.async_requests = [];
+JSONRpcClient.async_inflight = {};
+JSONRpcClient.async_responses = [];
+JSONRpcClient.async_timeout = null;
+JSONRpcClient.num_req_active = 0;
+
+JSONRpcClient._async_handler =
+function JSONRpcClient_async_handler()
+{
+ JSONRpcClient.async_timeout = null;
+
+ while(JSONRpcClient.async_responses.length > 0) {
+ var res = JSONRpcClient.async_responses.shift();
+ if(res.canceled) continue;
+ if(res.profile) res.profile.dispatch = new Date();
+ try {
+ res.cb(res.result, res.ex, res.profile);
+ } catch(e) {
+ JSONRpcClient.toplevel_ex_handler(e);
+ }
+ }
+
+ while(JSONRpcClient.async_requests.length > 0 &&
+ JSONRpcClient.num_req_active < JSONRpcClient.max_req_active) {
+ var req = JSONRpcClient.async_requests.shift();
+ if(req.canceled) continue;
+ req.client._sendRequest.call(req.client, req);
+ }
+};
+
+JSONRpcClient.kick_async =
+function JSONRpcClient_kick_async()
+{
+ if(JSONRpcClient.async_timeout == null)
+ JSONRpcClient.async_timeout =
+ setTimeout(JSONRpcClient._async_handler, 0);
+};
+
+JSONRpcClient.cancelRequest =
+function JSONRpcClient_cancelRequest(requestId)
+{
+ /* If it is in flight then mark it as canceled in the inflight map
+ and the XMLHttpRequest callback will discard the reply. */
+ if(JSONRpcClient.async_inflight[requestId]) {
+ JSONRpcClient.async_inflight[requestId].canceled = true;
+ return true;
+ }
+
+ /* If its not in flight yet then we can just mark it as canceled in
+ the the request queue and it will get discarded before being sent. */
+ for(var i in JSONRpcClient.async_requests) {
+ if(JSONRpcClient.async_requests[i].requestId == requestId) {
+ JSONRpcClient.async_requests[i].canceled = true;
+ return true;
+ }
+ }
+
+ /* It may have returned from the network and be waiting for its callback
+ to be dispatched, so mark it as canceled in the response queue
+ and the response will get discarded before calling the callback. */
+ for(var i in JSONRpcClient.async_responses) {
+ if(JSONRpcClient.async_responses[i].requestId == requestId) {
+ JSONRpcClient.async_responses[i].canceled = true;
+ return true;
+ }
+ }
+
+ return false;
+};
+
+JSONRpcClient.prototype._makeRequest =
+function JSONRpcClient_makeRequest(methodName, args, cb)
+{
+ var req = {};
+ req.client = this;
+ req.requestId = JSONRpcClient.requestId++;
+
+ var obj = {};
+ obj.id = req.requestId;
+ if (this.objectID)
+ obj.method = ".obj#" + this.objectID + "." + methodName;
+ else
+ obj.method = methodName;
+ obj.params = args;
+
+ if (cb) req.cb = cb;
+ if (JSONRpcClient.profile_async)
+ req.profile = { "submit": new Date() };
+ req.data = toJSON(obj);
+
+ return req;
+};
+
+JSONRpcClient.prototype._sendRequest =
+function JSONRpcClient_sendRequest(req)
+{
+ if(req.profile) req.profile.start = new Date();
+
+ /* Get free http object from the pool */
+ var http = JSONRpcClient.poolGetHTTPRequest();
+ JSONRpcClient.num_req_active++;
+
+ /* Send the request */
+ if (typeof(this.user) == "undefined") {
+ http.open("POST", this.serverURL, (req.cb != null));
+ } else {
+ http.open("POST", this.serverURL, (req.cb != null), this.user, this.pass);
+ }
+
+ /* setRequestHeader is missing in Opera 8 Beta */
+ try { http.setRequestHeader("Content-type", "text/plain"); } catch(e) {}
+
+ /* Construct call back if we have one */
+ if(req.cb) {
+ var self = this;
+ http.onreadystatechange = function() {
+ if(http.readyState == 4) {
+ http.onreadystatechange = function () {};
+ var res = { "cb": req.cb, "result": null, "ex": null};
+ if (req.profile) {
+ res.profile = req.profile;
+ res.profile.end = new Date();
+ }
+ try { res.result = self._handleResponse(http); }
+ catch(e) { res.ex = e; }
+ if(!JSONRpcClient.async_inflight[req.requestId].canceled)
+ JSONRpcClient.async_responses.push(res);
+ delete JSONRpcClient.async_inflight[req.requestId];
+ JSONRpcClient.kick_async();
+ }
+ };
+ } else {
+ http.onreadystatechange = function() {};
+ }
+
+ JSONRpcClient.async_inflight[req.requestId] = req;
+
+ try {
+ http.send(req.data);
+ } catch(e) {
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+ throw new JSONRpcClient.Exception
+ (JSONRpcClient.Exception.CODE_ERR_CLIENT, "Connection failed");
+ }
+
+ if(!req.cb) return this._handleResponse(http);
+};
+
+JSONRpcClient.prototype._handleResponse =
+function JSONRpcClient_handleResponse(http)
+{
+ /* Get the charset */
+ if(!this.charset) {
+ this.charset = JSONRpcClient._getCharsetFromHeaders(http);
+ }
+
+ /* Get request results */
+ var status, statusText, data;
+ try {
+ status = http.status;
+ statusText = http.statusText;
+ data = http.responseText;
+ } catch(e) {
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+ JSONRpcClient.kick_async();
+ throw new JSONRpcClient.Exception
+ (JSONRpcClient.Exception.CODE_ERR_CLIENT, "Connection failed");
+ }
+
+ /* Return http object to the pool; */
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+
+ /* Unmarshall the response */
+ if(status != 200) {
+ throw new JSONRpcClient.Exception(status, statusText);
+ }
+ var obj;
+ try {
+ eval("obj = " + data);
+ } catch(e) {
+ throw new JSONRpcClient.Exception(550, "error parsing result");
+ }
+ if(obj.error)
+ throw new JSONRpcClient.Exception(obj.error.code, obj.error.msg,
+ obj.error.trace);
+ var res = obj.result;
+
+ /* Handle CallableProxy */
+ if(res && res.objectID && res.JSONRPCType == "CallableReference")
+ return new JSONRpcClient(this.serverURL, this.user,
+ this.pass, res.objectID);
+
+ return res;
+};
+
+
+/* XMLHttpRequest wrapper code */
+
+/* XMLHttpRequest pool globals */
+JSONRpcClient.http_spare = [];
+JSONRpcClient.http_max_spare = 8;
+
+JSONRpcClient.poolGetHTTPRequest =
+function JSONRpcClient_pool_getHTTPRequest()
+{
+ if(JSONRpcClient.http_spare.length > 0) {
+ return JSONRpcClient.http_spare.pop();
+ }
+ return JSONRpcClient.getHTTPRequest();
+};
+
+JSONRpcClient.poolReturnHTTPRequest =
+function JSONRpcClient_poolReturnHTTPRequest(http)
+{
+ if(JSONRpcClient.http_spare.length >= JSONRpcClient.http_max_spare)
+ delete http;
+ else
+ JSONRpcClient.http_spare.push(http);
+};
+
+JSONRpcClient.msxmlNames = [ "MSXML2.XMLHTTP.5.0",
+ "MSXML2.XMLHTTP.4.0",
+ "MSXML2.XMLHTTP.3.0",
+ "MSXML2.XMLHTTP",
+ "Microsoft.XMLHTTP" ];
+
+JSONRpcClient.getHTTPRequest =
+function JSONRpcClient_getHTTPRequest()
+{
+ /* Mozilla XMLHttpRequest */
+ try {
+ JSONRpcClient.httpObjectName = "XMLHttpRequest";
+ return new XMLHttpRequest();
+ } catch(e) {}
+
+ /* Microsoft MSXML ActiveX */
+ for (var i=0;i < JSONRpcClient.msxmlNames.length; i++) {
+ try {
+ JSONRpcClient.httpObjectName = JSONRpcClient.msxmlNames[i];
+ return new ActiveXObject(JSONRpcClient.msxmlNames[i]);
+ } catch (e) {}
+ }
+
+ /* None found */
+ JSONRpcClient.httpObjectName = null;
+ throw new JSONRpcClient.Exception(0, "Can't create XMLHttpRequest object");
+};
+
+
+/*
+ * 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.
+ */
+
+function AtomClient(uri) {
+
+ this.msxmlNames = [ "MSXML2.XMLHTTP.5.0",
+ "MSXML2.XMLHTTP.4.0",
+ "MSXML2.XMLHTTP.3.0",
+ "MSXML2.XMLHTTP",
+ "Microsoft.XMLHTTP" ];
+
+ this.uri=uri;
+
+ this.get = function(id, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("get - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("GET", uri + '/' + id, true);
+ xhr.send(null);
+ }
+
+ this.post = function (entry, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 201) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("post - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("POST", uri, true);
+ xhr.setRequestHeader("Content-Type", "application/atom+xml");
+ xhr.send(entry);
+ }
+
+ this.put = function (id, entry, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("put - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("PUT", uri + '/' + id, true);
+ xhr.setRequestHeader("Content-Type", "application/atom+xml");
+ xhr.send(entry);
+ }
+
+ this.del = function (id, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ if (responseFunction != null) responseFunction();
+ } else {
+ alert("delete - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("DELETE", uri + '/' + id, true);
+ xhr.send(null);
+ }
+ this.createXMLHttpRequest = function () {
+ /* Mozilla XMLHttpRequest */
+ try {return new XMLHttpRequest();} catch(e) {}
+
+ /* Microsoft MSXML ActiveX */
+ for (var i=0;i < this.msxmlNames.length; i++) {
+ try {return new ActiveXObject(this.msxmlNames[i]);} catch (e) {}
+ }
+ alert("XML http request not supported");
+ return null;
+ }
+ if (typeof DOMParser == "undefined") {
+ DOMParser = function () {}
+
+ DOMParser.prototype.parseFromString = function (str, contentType) {
+ if (typeof ActiveXObject != "undefined") {
+ var d = new ActiveXObject("MSXML.DomDocument");
+ d.loadXML(str);
+ return d;
+ } else if (typeof XMLHttpRequest != "undefined") {
+ var req = new XMLHttpRequest;
+ req.open("GET", "data:" + (contentType || "application/xml") +
+ ";charset=utf-8," + encodeURIComponent(str), false);
+ if (req.overrideMimeType) {
+ req.overrideMimeType(contentType);
+ }
+ req.send(null);
+ return req.responseXML;
+ }
+ }
+ }
+}
+
+
+
+/* Tuscany Reference/Property injection code */
+
+if (!tuscany) {
+var tuscany = {};
+}
+if (!tuscany.sca) {
+tuscany.sca = {};
+}
+
+tuscany.sca.propertyMap = new String();
+tuscany.sca.Property = function (name) {
+ return tuscany.sca.propertyMap[name];
+}
+
+tuscany.sca.referenceMap = new Object();
+tuscany.sca.referenceMap.catalog = new JSONRpcClient("/catalog").Service;
+tuscany.sca.referenceMap.shoppingCart = new AtomClient("/shoppingCart");
+tuscany.sca.referenceMap.shoppingTotal = new JSONRpcClient("/total").Service;
+tuscany.sca.Reference = function (name) {
+ return tuscany.sca.referenceMap[name];
+}
+
+/** End of Apache Tuscany SCA Widget */
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/htpasswd.py b/sca-cpp/branches/gcc-4.4/test/store-gae/htpasswd.py
new file mode 100644
index 0000000000..75d94f58b6
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/htpasswd.py
@@ -0,0 +1,21 @@
+# 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.
+
+# Configure the user and password used for HTTP basic authentication
+user = "foo"
+passwd = "foo"
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/server-test b/sca-cpp/branches/gcc-4.4/test/store-gae/server-test
new file mode 100755
index 0000000000..c656cb33c2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/server-test
@@ -0,0 +1,41 @@
+#!/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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start 2>/dev/null
+sleep 2
+
+# Test HTTP GET
+mkdir -p tmp
+$curl_prefix/bin/curl http://localhost:8090/store.html 2>/dev/null >tmp/store.html
+diff tmp/store.html htdocs/store.html
+rc=$?
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/shopping-cart.py b/sca-cpp/branches/gcc-4.4/test/store-gae/shopping-cart.py
new file mode 100644
index 0000000000..c520da4303
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/shopping-cart.py
@@ -0,0 +1,77 @@
+# 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.
+
+# Shopping cart implementation
+import uuid
+import sys
+
+cartId = "1234"
+
+# Get the shopping cart from the cache
+# Return an empty cart if not found
+def getcart(id, cache):
+ cart = cache("get", (id,))
+ if cart is None:
+ return ()
+ return cart
+
+# Post a new item to the cart, create a new cart if necessary
+def post(collection, item, cache):
+ id = str(uuid.uuid1())
+ cart = ((item[0], id, item[2]),) + getcart(cartId, cache)
+ cache("put", (cartId,), cart)
+ return (id,)
+
+# Find an item in the cart
+def find(id, cart):
+ if cart == ():
+ return ("Item", "0", ())
+ elif id == cart[0][1]:
+ return cart[0]
+ else:
+ return find(id, cart[1:])
+
+# Get items from the cart
+def get(id, cache):
+ if id == ():
+ return ("Your Cart", cartId) + getcart(cartId, cache)
+ return find(id[0], getcart(cartId, cache))
+
+# Delete items from the cart
+def delete(id, cache):
+ if id == ():
+ return cache("delete", (cartId,))
+ return True
+
+# Return the price of an item
+def price(item):
+ return float(filter(lambda x: x[0] == "'price", item[2])[0][1])
+
+# Sum the prices of a list of items
+def sum(items):
+ if items == ():
+ return 0
+ return price(items[0]) + sum(items[1:])
+
+# Return the total price of the items in the cart
+def gettotal(cache):
+ cart = getcart(cartId, cache)
+ return sum(cart)
+
+# TODO remove these JSON-RPC specific functions
+def listMethods(cache):
+ return ("Service.gettotal",)
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/start b/sca-cpp/branches/gcc-4.4/test/store-gae/start
new file mode 100755
index 0000000000..3c9644e656
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/start
@@ -0,0 +1,21 @@
+#!/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/wsgi/gae-start target 8090
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/stop b/sca-cpp/branches/gcc-4.4/test/store-gae/stop
new file mode 100755
index 0000000000..7c8a7e5551
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/stop
@@ -0,0 +1,21 @@
+#!/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/wsgi/gae-stop target 8090
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-gae/store.py b/sca-cpp/branches/gcc-4.4/test/store-gae/store.py
new file mode 100644
index 0000000000..35c0f5b2aa
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-gae/store.py
@@ -0,0 +1,44 @@
+# 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.
+
+# Store implementation
+
+def post(item, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart("post", item)
+
+def getall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart("getall")
+
+def get(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart("get", id)
+
+def getcatalog(catalog, shoppingCart, shoppingTotal):
+ return catalog("get")
+
+def gettotal(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart("gettotal")
+
+def deleteall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart("deleteall")
+
+def delete(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart("delete", id)
+
+# TODO remove these JSON-RPC specific functions
+def listMethods(catalog, shoppingCart, shoppingTotal):
+ return ("Service.get", "Service.gettotal")
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-java/Makefile.am b/sca-cpp/branches/gcc-4.4/test/store-java/Makefile.am
new file mode 100644
index 0000000000..80972a0acc
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-java/Makefile.am
@@ -0,0 +1,30 @@
+# 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.
+
+JAVAROOT = ${top_builddir}/test/store-java
+
+if WANT_JAVA
+
+AM_JAVACFLAGS = -cp ${top_builddir}/modules/java/libmod-tuscany-java-${PACKAGE_VERSION}.jar:${JAVAROOT}
+
+noinst_JAVA = store/*.java
+
+CLEANFILES = store/*.class
+
+TESTS = server-test
+
+endif
diff --git a/sca-cpp/branches/gcc-4.4/test/store-java/htdocs/.htaccess b/sca-cpp/branches/gcc-4.4/test/store-java/htdocs/.htaccess
new file mode 100644
index 0000000000..e2e343b6b2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-java/htdocs/.htaccess
@@ -0,0 +1,19 @@
+#
+# 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.
+
+DirectoryIndex store.html
diff --git a/sca-cpp/branches/gcc-4.4/test/store-java/htdocs/store.html b/sca-cpp/branches/gcc-4.4/test/store-java/htdocs/store.html
new file mode 100644
index 0000000000..21eabca7a7
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-java/htdocs/store.html
@@ -0,0 +1,169 @@
+<!--
+ * 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>Store</title>
+
+<script type="text/javascript" src="store.js"></script>
+
+<script language="JavaScript">
+
+ //@Reference
+ var catalog = new tuscany.sca.Reference("catalog");
+
+ //@Reference
+ var shoppingCart = new tuscany.sca.Reference("shoppingCart");
+
+ //@Reference
+ var shoppingTotal = new tuscany.sca.Reference("shoppingTotal");
+
+ var catalogItems;
+
+ function catalog_getResponse(items,exception) {
+ if(exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+ // TEMP
+ shoppingTotal.gettotal(shoppingTotal_getTotalResponse);
+ }
+
+ function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ if (entries.length != 0) {
+ try {
+ shoppingTotal.gettotal(shoppingTotal_getTotalResponse);
+ }
+ catch(e){
+ alert(e);
+ }
+ }
+ }
+ }
+
+ function shoppingTotal_getTotalResponse(total,exception) {
+ if(exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+ }
+
+ function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+ }
+
+ function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<javaClass>' + catalogItems[i].javaClass + '</javaClass>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+ }
+ function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+ }
+ function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+ }
+
+ function init() {
+
+ try {
+ catalog.get(catalog_getResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ }
+ catch(e){
+ alert(e);
+ }
+ }
+
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Store</h1>
+ <div id="store">
+ <h2>Catalog</h2>
+ <form name="catalogForm">
+ <div id="catalog" ></div>
+ <br>
+ <input type="button" onClick="addToCart()" value="Add to Cart">
+ </form>
+
+ <br>
+
+ <h2>Your Shopping Cart</h2>
+ <form name="shoppingCartForm">
+ <div id="shoppingCart"></div>
+ <br>
+ <div id="total"></div>
+ <br>
+ <input type="button" onClick="checkoutCart()" value="Checkout">
+ <input type="button" onClick="deleteCart()" value="Empty">
+ <a href="../shoppingCart/">(feed)</a>
+ </form>
+ </div>
+</body>
+</html>
diff --git a/sca-cpp/branches/gcc-4.4/test/store-java/htdocs/store.js b/sca-cpp/branches/gcc-4.4/test/store-java/htdocs/store.js
new file mode 100644
index 0000000000..9cd8eb526d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-java/htdocs/store.js
@@ -0,0 +1,661 @@
+
+/* Apache Tuscany SCA Widget header */
+
+/*
+ * JSON-RPC JavaScript client
+ *
+ * $Id: jsonrpc.js,v 1.36.2.3 2006/03/08 15:09:37 mclark Exp $
+ *
+ * Copyright (c) 2003-2004 Jan-Klaas Kollhof
+ * Copyright (c) 2005 Michael Clark, Metaparadigm Pte Ltd
+ *
+ * This code is based on Jan-Klaas' JavaScript o lait library (jsolait).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * Modifications for Apache Tuscany:
+ * - JSONRpcClient_createMethod changed so callback is last arg
+ */
+
+/* escape a character */
+
+escapeJSONChar =
+function escapeJSONChar(c)
+{
+ if(c == "\"" || c == "\\") return "\\" + c;
+ else if (c == "\b") return "\\b";
+ else if (c == "\f") return "\\f";
+ else if (c == "\n") return "\\n";
+ else if (c == "\r") return "\\r";
+ else if (c == "\t") return "\\t";
+ var hex = c.charCodeAt(0).toString(16);
+ if(hex.length == 1) return "\\u000" + hex;
+ else if(hex.length == 2) return "\\u00" + hex;
+ else if(hex.length == 3) return "\\u0" + hex;
+ else return "\\u" + hex;
+};
+
+
+/* encode a string into JSON format */
+
+escapeJSONString =
+function escapeJSONString(s)
+{
+ /* The following should suffice but Safari's regex is b0rken
+ (doesn't support callback substitutions)
+ return "\"" + s.replace(/([^\u0020-\u007f]|[\\\"])/g,
+ escapeJSONChar) + "\"";
+ */
+
+ /* Rather inefficient way to do it */
+ var parts = s.split("");
+ for(var i=0; i < parts.length; i++) {
+ var c =parts[i];
+ if(c == '"' ||
+ c == '\\' ||
+ c.charCodeAt(0) < 32 ||
+ c.charCodeAt(0) >= 128)
+ parts[i] = escapeJSONChar(parts[i]);
+ }
+ return "\"" + parts.join("") + "\"";
+};
+
+
+/* Marshall objects to JSON format */
+
+toJSON = function toJSON(o)
+{
+ if(o == null) {
+ return "null";
+ } else if(o.constructor == String) {
+ return escapeJSONString(o);
+ } else if(o.constructor == Number) {
+ return o.toString();
+ } else if(o.constructor == Boolean) {
+ return o.toString();
+ } else if(o.constructor == Date) {
+ return '{javaClass: "java.util.Date", time: ' + o.valueOf() +'}';
+ } else if(o.constructor == Array) {
+ var v = [];
+ for(var i = 0; i < o.length; i++) v.push(toJSON(o[i]));
+ return "[" + v.join(", ") + "]";
+ } else {
+ var v = [];
+ for(attr in o) {
+ if(o[attr] == null) v.push("\"" + attr + "\": null");
+ else if(typeof o[attr] == "function"); /* skip */
+ else v.push(escapeJSONString(attr) + ": " + toJSON(o[attr]));
+ }
+ return "{" + v.join(", ") + "}";
+ }
+};
+
+
+/* JSONRpcClient constructor */
+
+JSONRpcClient =
+function JSONRpcClient_ctor(serverURL, user, pass, objectID)
+{
+ this.serverURL = serverURL;
+ this.user = user;
+ this.pass = pass;
+ this.objectID = objectID;
+
+ /* Add standard methods */
+ if(this.objectID) {
+ this._addMethods(["listMethods"]);
+ var req = this._makeRequest("listMethods", []);
+ } else {
+ this._addMethods(["system.listMethods"]);
+ var req = this._makeRequest("system.listMethods", []);
+ }
+ var m = this._sendRequest(req);
+ this._addMethods(m);
+};
+
+
+/* JSONRpcCLient.Exception */
+
+JSONRpcClient.Exception =
+function JSONRpcClient_Exception_ctor(code, message, javaStack)
+{
+ this.code = code;
+ var name;
+ if(javaStack) {
+ this.javaStack = javaStack;
+ var m = javaStack.match(/^([^:]*)/);
+ if(m) name = m[0];
+ }
+ if(name) this.name = name;
+ else this.name = "JSONRpcClientException";
+ this.message = message;
+};
+
+JSONRpcClient.Exception.CODE_REMOTE_EXCEPTION = 490;
+JSONRpcClient.Exception.CODE_ERR_CLIENT = 550;
+JSONRpcClient.Exception.CODE_ERR_PARSE = 590;
+JSONRpcClient.Exception.CODE_ERR_NOMETHOD = 591;
+JSONRpcClient.Exception.CODE_ERR_UNMARSHALL = 592;
+JSONRpcClient.Exception.CODE_ERR_MARSHALL = 593;
+
+JSONRpcClient.Exception.prototype = new Error();
+
+JSONRpcClient.Exception.prototype.toString =
+function JSONRpcClient_Exception_toString(code, msg)
+{
+ return this.name + ": " + this.message;
+};
+
+
+/* Default top level exception handler */
+
+JSONRpcClient.default_ex_handler =
+function JSONRpcClient_default_ex_handler(e) { alert(e); };
+
+
+/* Client settable variables */
+
+JSONRpcClient.toplevel_ex_handler = JSONRpcClient.default_ex_handler;
+JSONRpcClient.profile_async = false;
+JSONRpcClient.max_req_active = 1;
+JSONRpcClient.requestId = 1;
+
+
+/* JSONRpcClient implementation */
+
+JSONRpcClient.prototype._createMethod =
+function JSONRpcClient_createMethod(methodName)
+{
+ var fn=function()
+ {
+ var args = [];
+ var callback = null;
+ for(var i=0;i<arguments.length;i++) args.push(arguments[i]);
+
+/* TUSCANY change callback to be last arg instead of first to match binding.ajax
+ if(typeof args[0] == "function") callback = args.shift();
+*/
+ if(typeof args[arguments.length-1] == "function") callback = args.pop();
+
+ var req = fn.client._makeRequest.call(fn.client, fn.methodName,
+ args, callback);
+ if(callback == null) {
+ return fn.client._sendRequest.call(fn.client, req);
+ } else {
+ JSONRpcClient.async_requests.push(req);
+ JSONRpcClient.kick_async();
+ return req.requestId;
+ }
+ };
+ fn.client = this;
+ fn.methodName = methodName;
+ return fn;
+};
+
+JSONRpcClient.prototype._addMethods =
+function JSONRpcClient_addMethods(methodNames)
+{
+ for(var i=0; i<methodNames.length; i++) {
+ var obj = this;
+ var names = methodNames[i].split(".");
+ for(var n=0; n<names.length-1; n++) {
+ var name = names[n];
+ if(obj[name]) {
+ obj = obj[name];
+ } else {
+ obj[name] = new Object();
+ obj = obj[name];
+ }
+ }
+ var name = names[names.length-1];
+ if(!obj[name]) {
+ var method = this._createMethod(methodNames[i]);
+ obj[name] = method;
+ }
+ }
+};
+
+JSONRpcClient._getCharsetFromHeaders =
+function JSONRpcClient_getCharsetFromHeaders(http)
+{
+ try {
+ var contentType = http.getResponseHeader("Content-type");
+ var parts = contentType.split(/\s*;\s*/);
+ for(var i =0; i < parts.length; i++) {
+ if(parts[i].substring(0, 8) == "charset=")
+ return parts[i].substring(8, parts[i].length);
+ }
+ } catch (e) {}
+ return "UTF-8"; /* default */
+};
+
+/* Async queue globals */
+JSONRpcClient.async_requests = [];
+JSONRpcClient.async_inflight = {};
+JSONRpcClient.async_responses = [];
+JSONRpcClient.async_timeout = null;
+JSONRpcClient.num_req_active = 0;
+
+JSONRpcClient._async_handler =
+function JSONRpcClient_async_handler()
+{
+ JSONRpcClient.async_timeout = null;
+
+ while(JSONRpcClient.async_responses.length > 0) {
+ var res = JSONRpcClient.async_responses.shift();
+ if(res.canceled) continue;
+ if(res.profile) res.profile.dispatch = new Date();
+ try {
+ res.cb(res.result, res.ex, res.profile);
+ } catch(e) {
+ JSONRpcClient.toplevel_ex_handler(e);
+ }
+ }
+
+ while(JSONRpcClient.async_requests.length > 0 &&
+ JSONRpcClient.num_req_active < JSONRpcClient.max_req_active) {
+ var req = JSONRpcClient.async_requests.shift();
+ if(req.canceled) continue;
+ req.client._sendRequest.call(req.client, req);
+ }
+};
+
+JSONRpcClient.kick_async =
+function JSONRpcClient_kick_async()
+{
+ if(JSONRpcClient.async_timeout == null)
+ JSONRpcClient.async_timeout =
+ setTimeout(JSONRpcClient._async_handler, 0);
+};
+
+JSONRpcClient.cancelRequest =
+function JSONRpcClient_cancelRequest(requestId)
+{
+ /* If it is in flight then mark it as canceled in the inflight map
+ and the XMLHttpRequest callback will discard the reply. */
+ if(JSONRpcClient.async_inflight[requestId]) {
+ JSONRpcClient.async_inflight[requestId].canceled = true;
+ return true;
+ }
+
+ /* If its not in flight yet then we can just mark it as canceled in
+ the the request queue and it will get discarded before being sent. */
+ for(var i in JSONRpcClient.async_requests) {
+ if(JSONRpcClient.async_requests[i].requestId == requestId) {
+ JSONRpcClient.async_requests[i].canceled = true;
+ return true;
+ }
+ }
+
+ /* It may have returned from the network and be waiting for its callback
+ to be dispatched, so mark it as canceled in the response queue
+ and the response will get discarded before calling the callback. */
+ for(var i in JSONRpcClient.async_responses) {
+ if(JSONRpcClient.async_responses[i].requestId == requestId) {
+ JSONRpcClient.async_responses[i].canceled = true;
+ return true;
+ }
+ }
+
+ return false;
+};
+
+JSONRpcClient.prototype._makeRequest =
+function JSONRpcClient_makeRequest(methodName, args, cb)
+{
+ var req = {};
+ req.client = this;
+ req.requestId = JSONRpcClient.requestId++;
+
+ var obj = {};
+ obj.id = req.requestId;
+ if (this.objectID)
+ obj.method = ".obj#" + this.objectID + "." + methodName;
+ else
+ obj.method = methodName;
+ obj.params = args;
+
+ if (cb) req.cb = cb;
+ if (JSONRpcClient.profile_async)
+ req.profile = { "submit": new Date() };
+ req.data = toJSON(obj);
+
+ return req;
+};
+
+JSONRpcClient.prototype._sendRequest =
+function JSONRpcClient_sendRequest(req)
+{
+ if(req.profile) req.profile.start = new Date();
+
+ /* Get free http object from the pool */
+ var http = JSONRpcClient.poolGetHTTPRequest();
+ JSONRpcClient.num_req_active++;
+
+ /* Send the request */
+ if (typeof(this.user) == "undefined") {
+ http.open("POST", this.serverURL, (req.cb != null));
+ } else {
+ http.open("POST", this.serverURL, (req.cb != null), this.user, this.pass);
+ }
+
+ /* setRequestHeader is missing in Opera 8 Beta */
+ try { http.setRequestHeader("Content-type", "text/plain"); } catch(e) {}
+
+ /* Construct call back if we have one */
+ if(req.cb) {
+ var self = this;
+ http.onreadystatechange = function() {
+ if(http.readyState == 4) {
+ http.onreadystatechange = function () {};
+ var res = { "cb": req.cb, "result": null, "ex": null};
+ if (req.profile) {
+ res.profile = req.profile;
+ res.profile.end = new Date();
+ }
+ try { res.result = self._handleResponse(http); }
+ catch(e) { res.ex = e; }
+ if(!JSONRpcClient.async_inflight[req.requestId].canceled)
+ JSONRpcClient.async_responses.push(res);
+ delete JSONRpcClient.async_inflight[req.requestId];
+ JSONRpcClient.kick_async();
+ }
+ };
+ } else {
+ http.onreadystatechange = function() {};
+ }
+
+ JSONRpcClient.async_inflight[req.requestId] = req;
+
+ try {
+ http.send(req.data);
+ } catch(e) {
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+ throw new JSONRpcClient.Exception
+ (JSONRpcClient.Exception.CODE_ERR_CLIENT, "Connection failed");
+ }
+
+ if(!req.cb) return this._handleResponse(http);
+};
+
+JSONRpcClient.prototype._handleResponse =
+function JSONRpcClient_handleResponse(http)
+{
+ /* Get the charset */
+ if(!this.charset) {
+ this.charset = JSONRpcClient._getCharsetFromHeaders(http);
+ }
+
+ /* Get request results */
+ var status, statusText, data;
+ try {
+ status = http.status;
+ statusText = http.statusText;
+ data = http.responseText;
+ } catch(e) {
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+ JSONRpcClient.kick_async();
+ throw new JSONRpcClient.Exception
+ (JSONRpcClient.Exception.CODE_ERR_CLIENT, "Connection failed");
+ }
+
+ /* Return http object to the pool; */
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+
+ /* Unmarshall the response */
+ if(status != 200) {
+ throw new JSONRpcClient.Exception(status, statusText);
+ }
+ var obj;
+ try {
+ eval("obj = " + data);
+ } catch(e) {
+ throw new JSONRpcClient.Exception(550, "error parsing result");
+ }
+ if(obj.error)
+ throw new JSONRpcClient.Exception(obj.error.code, obj.error.msg,
+ obj.error.trace);
+ var res = obj.result;
+
+ /* Handle CallableProxy */
+ if(res && res.objectID && res.JSONRPCType == "CallableReference")
+ return new JSONRpcClient(this.serverURL, this.user,
+ this.pass, res.objectID);
+
+ return res;
+};
+
+
+/* XMLHttpRequest wrapper code */
+
+/* XMLHttpRequest pool globals */
+JSONRpcClient.http_spare = [];
+JSONRpcClient.http_max_spare = 8;
+
+JSONRpcClient.poolGetHTTPRequest =
+function JSONRpcClient_pool_getHTTPRequest()
+{
+ if(JSONRpcClient.http_spare.length > 0) {
+ return JSONRpcClient.http_spare.pop();
+ }
+ return JSONRpcClient.getHTTPRequest();
+};
+
+JSONRpcClient.poolReturnHTTPRequest =
+function JSONRpcClient_poolReturnHTTPRequest(http)
+{
+ if(JSONRpcClient.http_spare.length >= JSONRpcClient.http_max_spare)
+ delete http;
+ else
+ JSONRpcClient.http_spare.push(http);
+};
+
+JSONRpcClient.msxmlNames = [ "MSXML2.XMLHTTP.5.0",
+ "MSXML2.XMLHTTP.4.0",
+ "MSXML2.XMLHTTP.3.0",
+ "MSXML2.XMLHTTP",
+ "Microsoft.XMLHTTP" ];
+
+JSONRpcClient.getHTTPRequest =
+function JSONRpcClient_getHTTPRequest()
+{
+ /* Mozilla XMLHttpRequest */
+ try {
+ JSONRpcClient.httpObjectName = "XMLHttpRequest";
+ return new XMLHttpRequest();
+ } catch(e) {}
+
+ /* Microsoft MSXML ActiveX */
+ for (var i=0;i < JSONRpcClient.msxmlNames.length; i++) {
+ try {
+ JSONRpcClient.httpObjectName = JSONRpcClient.msxmlNames[i];
+ return new ActiveXObject(JSONRpcClient.msxmlNames[i]);
+ } catch (e) {}
+ }
+
+ /* None found */
+ JSONRpcClient.httpObjectName = null;
+ throw new JSONRpcClient.Exception(0, "Can't create XMLHttpRequest object");
+};
+
+
+/*
+ * 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.
+ */
+
+function AtomClient(uri) {
+
+ this.msxmlNames = [ "MSXML2.XMLHTTP.5.0",
+ "MSXML2.XMLHTTP.4.0",
+ "MSXML2.XMLHTTP.3.0",
+ "MSXML2.XMLHTTP",
+ "Microsoft.XMLHTTP" ];
+
+ this.uri=uri;
+
+ this.get = function(id, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("get - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("GET", uri + '/' + id, true);
+ xhr.send(null);
+ }
+
+ this.post = function (entry, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 201) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("post - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("POST", uri, true);
+ xhr.setRequestHeader("Content-Type", "application/atom+xml");
+ xhr.send(entry);
+ }
+
+ this.put = function (id, entry, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("put - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("PUT", uri + '/' + id, true);
+ xhr.setRequestHeader("Content-Type", "application/atom+xml");
+ xhr.send(entry);
+ }
+
+ this.del = function (id, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ if (responseFunction != null) responseFunction();
+ } else {
+ alert("delete - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("DELETE", uri + '/' + id, true);
+ xhr.send(null);
+ }
+ this.createXMLHttpRequest = function () {
+ /* Mozilla XMLHttpRequest */
+ try {return new XMLHttpRequest();} catch(e) {}
+
+ /* Microsoft MSXML ActiveX */
+ for (var i=0;i < this.msxmlNames.length; i++) {
+ try {return new ActiveXObject(this.msxmlNames[i]);} catch (e) {}
+ }
+ alert("XML http request not supported");
+ return null;
+ }
+ if (typeof DOMParser == "undefined") {
+ DOMParser = function () {}
+
+ DOMParser.prototype.parseFromString = function (str, contentType) {
+ if (typeof ActiveXObject != "undefined") {
+ var d = new ActiveXObject("MSXML.DomDocument");
+ d.loadXML(str);
+ return d;
+ } else if (typeof XMLHttpRequest != "undefined") {
+ var req = new XMLHttpRequest;
+ req.open("GET", "data:" + (contentType || "application/xml") +
+ ";charset=utf-8," + encodeURIComponent(str), false);
+ if (req.overrideMimeType) {
+ req.overrideMimeType(contentType);
+ }
+ req.send(null);
+ return req.responseXML;
+ }
+ }
+ }
+}
+
+
+
+/* Tuscany Reference/Property injection code */
+
+if (!tuscany) {
+var tuscany = {};
+}
+if (!tuscany.sca) {
+tuscany.sca = {};
+}
+
+tuscany.sca.propertyMap = new String();
+tuscany.sca.Property = function (name) {
+ return tuscany.sca.propertyMap[name];
+}
+
+tuscany.sca.referenceMap = new Object();
+tuscany.sca.referenceMap.catalog = new JSONRpcClient("/catalog").Service;
+tuscany.sca.referenceMap.shoppingCart = new AtomClient("/shoppingCart");
+tuscany.sca.referenceMap.shoppingTotal = new JSONRpcClient("/total").Service;
+tuscany.sca.Reference = function (name) {
+ return tuscany.sca.referenceMap[name];
+}
+
+/** End of Apache Tuscany SCA Widget */
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-java/server-test b/sca-cpp/branches/gcc-4.4/test/store-java/server-test
new file mode 100755
index 0000000000..d2013f6892
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-java/server-test
@@ -0,0 +1,40 @@
+#!/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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/store.html 2>/dev/null >tmp/store.html
+diff tmp/store.html htdocs/store.html
+rc=$?
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/test/store-java/ssl-start b/sca-cpp/branches/gcc-4.4/test/store-java/ssl-start
new file mode 100755
index 0000000000..ec44ba1ac0
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-java/ssl-start
@@ -0,0 +1,36 @@
+#!/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-ca-conf tmp localhost
+../../modules/http/httpd-cert-conf tmp localhost
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/http/httpd-ssl-conf tmp localhost 8453 htdocs
+../../modules/server/server-conf tmp
+../../modules/java/java-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+export CLASSPATH=`pwd`/../../modules/java/libmod-tuscany-java-1.0.jar:`pwd`
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sca-cpp/branches/gcc-4.4/test/store-java/start b/sca-cpp/branches/gcc-4.4/test/store-java/start
new file mode 100755
index 0000000000..c8146e9e46
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-java/start
@@ -0,0 +1,33 @@
+#!/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-conf tmp localhost 8090 htdocs
+../../modules/server/server-conf tmp
+../../modules/java/java-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+export CLASSPATH=`pwd`/../../modules/java/libmod-tuscany-java-1.0.jar:`pwd`
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sca-cpp/branches/gcc-4.4/test/store-java/stop b/sca-cpp/branches/gcc-4.4/test/store-java/stop
new file mode 100755
index 0000000000..79d914e937
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-java/stop
@@ -0,0 +1,23 @@
+#!/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.
+
+export CLASSPATH=`pwd`/../../modules/java/libmod-tuscany-java-1.0.jar:`pwd`
+
+../../modules/http/httpd-stop tmp
+../../components/cache/memcached-stop
diff --git a/sca-cpp/branches/gcc-4.4/test/store-java/store.composite b/sca-cpp/branches/gcc-4.4/test/store-java/store.composite
new file mode 100644
index 0000000000..8d733db134
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-java/store.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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Catalog">
+ <implementation.java class="store.FruitsCatalogImpl"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <implementation.java class="store.ShoppingCartImpl"/>
+ <service name="ShoppingCart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <implementation.java class="store.CurrencyConverterImpl"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+ <component name="Cache">
+ <implementation.cpp path="../../components/cache/.libs" library="libmemcache"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/test/store-java/store/CurrencyConverter.java b/sca-cpp/branches/gcc-4.4/test/store-java/store/CurrencyConverter.java
new file mode 100644
index 0000000000..1ed15a670a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-java/store/CurrencyConverter.java
@@ -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.
+ */
+
+package store;
+
+public interface CurrencyConverter {
+
+ Double convert(String from, String to, Double amount);
+
+ String symbol(String currency);
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/test/store-java/store/CurrencyConverterImpl.java b/sca-cpp/branches/gcc-4.4/test/store-java/store/CurrencyConverterImpl.java
new file mode 100644
index 0000000000..a6d0fd00b3
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-java/store/CurrencyConverterImpl.java
@@ -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.
+ */
+
+package store;
+
+/**
+ * Currency converter component implementation.
+ */
+public class CurrencyConverterImpl {
+
+ /**
+ * Convert an amount from USD to a currency.
+ */
+ public Double convert(String from, String to, Double amount) {
+ if ("EUR".equals(to))
+ return amount * 0.70;
+ return amount;
+ }
+
+ /**
+ * Return a currency symbol.
+ */
+ public String symbol(String currency) {
+ if ("EUR".equals(currency))
+ return "E";
+ return "$";
+ }
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/test/store-java/store/FruitsCatalogImpl.java b/sca-cpp/branches/gcc-4.4/test/store-java/store/FruitsCatalogImpl.java
new file mode 100644
index 0000000000..2904bbd8a1
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-java/store/FruitsCatalogImpl.java
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+package store;
+
+import static org.apache.tuscany.IterableUtil.*;
+
+import org.apache.tuscany.Service;
+
+/**
+ * Catalog component implementation.
+ */
+public class FruitsCatalogImpl {
+
+ /**
+ * Returns the catalog.
+ */
+ public Iterable<?> get(final CurrencyConverter converter, final Service currencyCode) {
+ final String code = currencyCode.eval();
+
+ class Converter {
+ Double convert(final Double price) {
+ return converter.convert(code, "USD", price);
+ }
+ }
+
+ final Converter c = new Converter();
+ final String symbol = converter.symbol(code);
+
+ return list(list(list("'javaClass", "services.Item"), list("'name", "Apple"), list("'currencyCode", code), list("'currencySymbol", symbol), list("'price", c.convert(2.99))),
+ list(list("'javaClass", "services.Item"), list("'name", "Orange"), list("'currencyCode", code), list("'currencySymbol", symbol), list("'price", c.convert(3.55))),
+ list(list("'javaClass", "services.Item"), list("'name", "Pear"), list("'currencyCode", code), list("'currencySymbol", symbol), list("'price", c.convert(1.55))));
+ }
+
+ /**
+ * TODO remove this JSON-RPC specific function.
+ */
+ public Iterable<?> listMethods(final CurrencyConverter converter, final Service currencyCode) {
+ return list("Service.get");
+ }
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/test/store-java/store/ShoppingCartImpl.java b/sca-cpp/branches/gcc-4.4/test/store-java/store/ShoppingCartImpl.java
new file mode 100644
index 0000000000..878e0cff49
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-java/store/ShoppingCartImpl.java
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+package store;
+
+import static org.apache.tuscany.IterableUtil.*;
+import static org.apache.tuscany.UUIDUtil.*;
+
+import org.apache.tuscany.Service;
+
+/**
+ * Shopping cart component implementation.
+ */
+public class ShoppingCartImpl {
+
+ static String cartId = "1234";
+
+ /**
+ * Get the shopping cart from the cache. Return an empty cart if not found.
+ */
+ public Iterable<?> getcart(final String id, final Service cache) {
+ final Iterable<String> iid = list(id);
+ final Iterable<?> cart = cache.get(iid);
+ if(cart == null)
+ return list();
+ return cart;
+ }
+
+ /**
+ * Post a new item to the cart. Create a new cart if necessary.
+ */
+ public Iterable<String> post(final Iterable<String> collection, final Iterable<?> item, final Service cache) {
+ final String id = uuid();
+ final Iterable<?> newItem = list(car(item), id, caddr(item));
+ final Iterable<?> cart = cons(newItem, this.getcart(cartId, cache));
+ final Iterable<String> iid = list(cartId);
+ cache.put(iid, cart);
+ return list(id);
+ }
+
+ /**
+ * Find an item in the cart.
+ */
+ Iterable<?> find(final String id, final Iterable<?> cart) {
+ if(isNil(cart))
+ return cons("Item", list("0", list()));
+ if(id.equals(cadr(car(cart))))
+ return car(cart);
+ return this.find(id, cdr(cart));
+ }
+
+ /**
+ * Return items from the cart.
+ */
+ public Iterable<?> get(final Iterable<String> id, final Service cache) {
+ if(isNil(id))
+ return cons("Your Cart", cons(cartId, this.getcart(cartId, cache)));
+ return this.find((String)car(id), this.getcart(cartId, cache));
+ }
+
+ /**
+ * Delete items from the cart.
+ */
+ public Boolean delete(final Iterable<String> id, final Service cache) {
+ if(isNil(id)) {
+ final Iterable<String> iid = list(cartId);
+ return cache.delete(iid);
+ }
+ return true;
+ }
+
+ /**
+ * Return the price of an item.
+ */
+ Double price(final Iterable<?> item) {
+ return Double.valueOf((String)cadr(assoc("'price", caddr(item))));
+ }
+
+ /**
+ * Sum the prices of a list of items.
+ */
+ Double sum(final Iterable<?> items) {
+ if(isNil(items))
+ return 0.0;
+ return this.price((Iterable<?>)car(items)) + this.sum(cdr(items));
+ }
+
+ /**
+ * Return the total price of the items in the cart.
+ */
+ public Double gettotal(final Service cache) {
+ final Iterable<?> cart = this.getcart(cartId, cache);
+ return this.sum(cart);
+ }
+
+ /**
+ * TODO remove this JSON-RPC specific function.
+ */
+ public Iterable<?> listMethods(final Service cache) {
+ return list("Service.gettotal");
+ }
+
+}
diff --git a/sca-cpp/branches/gcc-4.4/test/store-python/Makefile.am b/sca-cpp/branches/gcc-4.4/test/store-python/Makefile.am
new file mode 100644
index 0000000000..2bdd776e10
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-python/Makefile.am
@@ -0,0 +1,22 @@
+# 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
+
+TESTS = server-test
+
+endif
diff --git a/sca-cpp/branches/gcc-4.4/test/store-python/currency-converter.py b/sca-cpp/branches/gcc-4.4/test/store-python/currency-converter.py
new file mode 100644
index 0000000000..2fded8f616
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-python/currency-converter.py
@@ -0,0 +1,29 @@
+# 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.
+
+# Currency converter implementation
+
+def convert(fr, to, amount):
+ if to == "EUR":
+ return amount * 0.70
+ return amount
+
+def symbol(currency):
+ if currency == "EUR":
+ return "E"
+ return "$"
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-python/fruits-catalog.py b/sca-cpp/branches/gcc-4.4/test/store-python/fruits-catalog.py
new file mode 100644
index 0000000000..75c18f5f99
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-python/fruits-catalog.py
@@ -0,0 +1,34 @@
+# 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.
+
+# Catalog implementation
+
+def get(converter, currencyCode):
+ code = currencyCode()
+ def convert(price):
+ return converter("convert", "USD", code, price)
+ symbol = converter("symbol", code)
+ return (
+ (("'javaClass", "services.Item"), ("'name", "Apple"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(2.99))),
+ (("'javaClass", "services.Item"), ("'name", "Orange"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(3.55))),
+ (("'javaClass", "services.Item"), ("'name", "Pear"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(1.55)))
+ )
+
+# TODO remove these JSON-RPC specific functions
+def listMethods(converter, currencyCode):
+ return ("Service.get",)
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-python/htdocs/.htaccess b/sca-cpp/branches/gcc-4.4/test/store-python/htdocs/.htaccess
new file mode 100644
index 0000000000..e2e343b6b2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-python/htdocs/.htaccess
@@ -0,0 +1,19 @@
+#
+# 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.
+
+DirectoryIndex store.html
diff --git a/sca-cpp/branches/gcc-4.4/test/store-python/htdocs/store.html b/sca-cpp/branches/gcc-4.4/test/store-python/htdocs/store.html
new file mode 100644
index 0000000000..21eabca7a7
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-python/htdocs/store.html
@@ -0,0 +1,169 @@
+<!--
+ * 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>Store</title>
+
+<script type="text/javascript" src="store.js"></script>
+
+<script language="JavaScript">
+
+ //@Reference
+ var catalog = new tuscany.sca.Reference("catalog");
+
+ //@Reference
+ var shoppingCart = new tuscany.sca.Reference("shoppingCart");
+
+ //@Reference
+ var shoppingTotal = new tuscany.sca.Reference("shoppingTotal");
+
+ var catalogItems;
+
+ function catalog_getResponse(items,exception) {
+ if(exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+ // TEMP
+ shoppingTotal.gettotal(shoppingTotal_getTotalResponse);
+ }
+
+ function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ if (entries.length != 0) {
+ try {
+ shoppingTotal.gettotal(shoppingTotal_getTotalResponse);
+ }
+ catch(e){
+ alert(e);
+ }
+ }
+ }
+ }
+
+ function shoppingTotal_getTotalResponse(total,exception) {
+ if(exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+ }
+
+ function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+ }
+
+ function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<javaClass>' + catalogItems[i].javaClass + '</javaClass>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+ }
+ function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+ }
+ function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+ }
+
+ function init() {
+
+ try {
+ catalog.get(catalog_getResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ }
+ catch(e){
+ alert(e);
+ }
+ }
+
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Store</h1>
+ <div id="store">
+ <h2>Catalog</h2>
+ <form name="catalogForm">
+ <div id="catalog" ></div>
+ <br>
+ <input type="button" onClick="addToCart()" value="Add to Cart">
+ </form>
+
+ <br>
+
+ <h2>Your Shopping Cart</h2>
+ <form name="shoppingCartForm">
+ <div id="shoppingCart"></div>
+ <br>
+ <div id="total"></div>
+ <br>
+ <input type="button" onClick="checkoutCart()" value="Checkout">
+ <input type="button" onClick="deleteCart()" value="Empty">
+ <a href="../shoppingCart/">(feed)</a>
+ </form>
+ </div>
+</body>
+</html>
diff --git a/sca-cpp/branches/gcc-4.4/test/store-python/htdocs/store.js b/sca-cpp/branches/gcc-4.4/test/store-python/htdocs/store.js
new file mode 100644
index 0000000000..9cd8eb526d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-python/htdocs/store.js
@@ -0,0 +1,661 @@
+
+/* Apache Tuscany SCA Widget header */
+
+/*
+ * JSON-RPC JavaScript client
+ *
+ * $Id: jsonrpc.js,v 1.36.2.3 2006/03/08 15:09:37 mclark Exp $
+ *
+ * Copyright (c) 2003-2004 Jan-Klaas Kollhof
+ * Copyright (c) 2005 Michael Clark, Metaparadigm Pte Ltd
+ *
+ * This code is based on Jan-Klaas' JavaScript o lait library (jsolait).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * Modifications for Apache Tuscany:
+ * - JSONRpcClient_createMethod changed so callback is last arg
+ */
+
+/* escape a character */
+
+escapeJSONChar =
+function escapeJSONChar(c)
+{
+ if(c == "\"" || c == "\\") return "\\" + c;
+ else if (c == "\b") return "\\b";
+ else if (c == "\f") return "\\f";
+ else if (c == "\n") return "\\n";
+ else if (c == "\r") return "\\r";
+ else if (c == "\t") return "\\t";
+ var hex = c.charCodeAt(0).toString(16);
+ if(hex.length == 1) return "\\u000" + hex;
+ else if(hex.length == 2) return "\\u00" + hex;
+ else if(hex.length == 3) return "\\u0" + hex;
+ else return "\\u" + hex;
+};
+
+
+/* encode a string into JSON format */
+
+escapeJSONString =
+function escapeJSONString(s)
+{
+ /* The following should suffice but Safari's regex is b0rken
+ (doesn't support callback substitutions)
+ return "\"" + s.replace(/([^\u0020-\u007f]|[\\\"])/g,
+ escapeJSONChar) + "\"";
+ */
+
+ /* Rather inefficient way to do it */
+ var parts = s.split("");
+ for(var i=0; i < parts.length; i++) {
+ var c =parts[i];
+ if(c == '"' ||
+ c == '\\' ||
+ c.charCodeAt(0) < 32 ||
+ c.charCodeAt(0) >= 128)
+ parts[i] = escapeJSONChar(parts[i]);
+ }
+ return "\"" + parts.join("") + "\"";
+};
+
+
+/* Marshall objects to JSON format */
+
+toJSON = function toJSON(o)
+{
+ if(o == null) {
+ return "null";
+ } else if(o.constructor == String) {
+ return escapeJSONString(o);
+ } else if(o.constructor == Number) {
+ return o.toString();
+ } else if(o.constructor == Boolean) {
+ return o.toString();
+ } else if(o.constructor == Date) {
+ return '{javaClass: "java.util.Date", time: ' + o.valueOf() +'}';
+ } else if(o.constructor == Array) {
+ var v = [];
+ for(var i = 0; i < o.length; i++) v.push(toJSON(o[i]));
+ return "[" + v.join(", ") + "]";
+ } else {
+ var v = [];
+ for(attr in o) {
+ if(o[attr] == null) v.push("\"" + attr + "\": null");
+ else if(typeof o[attr] == "function"); /* skip */
+ else v.push(escapeJSONString(attr) + ": " + toJSON(o[attr]));
+ }
+ return "{" + v.join(", ") + "}";
+ }
+};
+
+
+/* JSONRpcClient constructor */
+
+JSONRpcClient =
+function JSONRpcClient_ctor(serverURL, user, pass, objectID)
+{
+ this.serverURL = serverURL;
+ this.user = user;
+ this.pass = pass;
+ this.objectID = objectID;
+
+ /* Add standard methods */
+ if(this.objectID) {
+ this._addMethods(["listMethods"]);
+ var req = this._makeRequest("listMethods", []);
+ } else {
+ this._addMethods(["system.listMethods"]);
+ var req = this._makeRequest("system.listMethods", []);
+ }
+ var m = this._sendRequest(req);
+ this._addMethods(m);
+};
+
+
+/* JSONRpcCLient.Exception */
+
+JSONRpcClient.Exception =
+function JSONRpcClient_Exception_ctor(code, message, javaStack)
+{
+ this.code = code;
+ var name;
+ if(javaStack) {
+ this.javaStack = javaStack;
+ var m = javaStack.match(/^([^:]*)/);
+ if(m) name = m[0];
+ }
+ if(name) this.name = name;
+ else this.name = "JSONRpcClientException";
+ this.message = message;
+};
+
+JSONRpcClient.Exception.CODE_REMOTE_EXCEPTION = 490;
+JSONRpcClient.Exception.CODE_ERR_CLIENT = 550;
+JSONRpcClient.Exception.CODE_ERR_PARSE = 590;
+JSONRpcClient.Exception.CODE_ERR_NOMETHOD = 591;
+JSONRpcClient.Exception.CODE_ERR_UNMARSHALL = 592;
+JSONRpcClient.Exception.CODE_ERR_MARSHALL = 593;
+
+JSONRpcClient.Exception.prototype = new Error();
+
+JSONRpcClient.Exception.prototype.toString =
+function JSONRpcClient_Exception_toString(code, msg)
+{
+ return this.name + ": " + this.message;
+};
+
+
+/* Default top level exception handler */
+
+JSONRpcClient.default_ex_handler =
+function JSONRpcClient_default_ex_handler(e) { alert(e); };
+
+
+/* Client settable variables */
+
+JSONRpcClient.toplevel_ex_handler = JSONRpcClient.default_ex_handler;
+JSONRpcClient.profile_async = false;
+JSONRpcClient.max_req_active = 1;
+JSONRpcClient.requestId = 1;
+
+
+/* JSONRpcClient implementation */
+
+JSONRpcClient.prototype._createMethod =
+function JSONRpcClient_createMethod(methodName)
+{
+ var fn=function()
+ {
+ var args = [];
+ var callback = null;
+ for(var i=0;i<arguments.length;i++) args.push(arguments[i]);
+
+/* TUSCANY change callback to be last arg instead of first to match binding.ajax
+ if(typeof args[0] == "function") callback = args.shift();
+*/
+ if(typeof args[arguments.length-1] == "function") callback = args.pop();
+
+ var req = fn.client._makeRequest.call(fn.client, fn.methodName,
+ args, callback);
+ if(callback == null) {
+ return fn.client._sendRequest.call(fn.client, req);
+ } else {
+ JSONRpcClient.async_requests.push(req);
+ JSONRpcClient.kick_async();
+ return req.requestId;
+ }
+ };
+ fn.client = this;
+ fn.methodName = methodName;
+ return fn;
+};
+
+JSONRpcClient.prototype._addMethods =
+function JSONRpcClient_addMethods(methodNames)
+{
+ for(var i=0; i<methodNames.length; i++) {
+ var obj = this;
+ var names = methodNames[i].split(".");
+ for(var n=0; n<names.length-1; n++) {
+ var name = names[n];
+ if(obj[name]) {
+ obj = obj[name];
+ } else {
+ obj[name] = new Object();
+ obj = obj[name];
+ }
+ }
+ var name = names[names.length-1];
+ if(!obj[name]) {
+ var method = this._createMethod(methodNames[i]);
+ obj[name] = method;
+ }
+ }
+};
+
+JSONRpcClient._getCharsetFromHeaders =
+function JSONRpcClient_getCharsetFromHeaders(http)
+{
+ try {
+ var contentType = http.getResponseHeader("Content-type");
+ var parts = contentType.split(/\s*;\s*/);
+ for(var i =0; i < parts.length; i++) {
+ if(parts[i].substring(0, 8) == "charset=")
+ return parts[i].substring(8, parts[i].length);
+ }
+ } catch (e) {}
+ return "UTF-8"; /* default */
+};
+
+/* Async queue globals */
+JSONRpcClient.async_requests = [];
+JSONRpcClient.async_inflight = {};
+JSONRpcClient.async_responses = [];
+JSONRpcClient.async_timeout = null;
+JSONRpcClient.num_req_active = 0;
+
+JSONRpcClient._async_handler =
+function JSONRpcClient_async_handler()
+{
+ JSONRpcClient.async_timeout = null;
+
+ while(JSONRpcClient.async_responses.length > 0) {
+ var res = JSONRpcClient.async_responses.shift();
+ if(res.canceled) continue;
+ if(res.profile) res.profile.dispatch = new Date();
+ try {
+ res.cb(res.result, res.ex, res.profile);
+ } catch(e) {
+ JSONRpcClient.toplevel_ex_handler(e);
+ }
+ }
+
+ while(JSONRpcClient.async_requests.length > 0 &&
+ JSONRpcClient.num_req_active < JSONRpcClient.max_req_active) {
+ var req = JSONRpcClient.async_requests.shift();
+ if(req.canceled) continue;
+ req.client._sendRequest.call(req.client, req);
+ }
+};
+
+JSONRpcClient.kick_async =
+function JSONRpcClient_kick_async()
+{
+ if(JSONRpcClient.async_timeout == null)
+ JSONRpcClient.async_timeout =
+ setTimeout(JSONRpcClient._async_handler, 0);
+};
+
+JSONRpcClient.cancelRequest =
+function JSONRpcClient_cancelRequest(requestId)
+{
+ /* If it is in flight then mark it as canceled in the inflight map
+ and the XMLHttpRequest callback will discard the reply. */
+ if(JSONRpcClient.async_inflight[requestId]) {
+ JSONRpcClient.async_inflight[requestId].canceled = true;
+ return true;
+ }
+
+ /* If its not in flight yet then we can just mark it as canceled in
+ the the request queue and it will get discarded before being sent. */
+ for(var i in JSONRpcClient.async_requests) {
+ if(JSONRpcClient.async_requests[i].requestId == requestId) {
+ JSONRpcClient.async_requests[i].canceled = true;
+ return true;
+ }
+ }
+
+ /* It may have returned from the network and be waiting for its callback
+ to be dispatched, so mark it as canceled in the response queue
+ and the response will get discarded before calling the callback. */
+ for(var i in JSONRpcClient.async_responses) {
+ if(JSONRpcClient.async_responses[i].requestId == requestId) {
+ JSONRpcClient.async_responses[i].canceled = true;
+ return true;
+ }
+ }
+
+ return false;
+};
+
+JSONRpcClient.prototype._makeRequest =
+function JSONRpcClient_makeRequest(methodName, args, cb)
+{
+ var req = {};
+ req.client = this;
+ req.requestId = JSONRpcClient.requestId++;
+
+ var obj = {};
+ obj.id = req.requestId;
+ if (this.objectID)
+ obj.method = ".obj#" + this.objectID + "." + methodName;
+ else
+ obj.method = methodName;
+ obj.params = args;
+
+ if (cb) req.cb = cb;
+ if (JSONRpcClient.profile_async)
+ req.profile = { "submit": new Date() };
+ req.data = toJSON(obj);
+
+ return req;
+};
+
+JSONRpcClient.prototype._sendRequest =
+function JSONRpcClient_sendRequest(req)
+{
+ if(req.profile) req.profile.start = new Date();
+
+ /* Get free http object from the pool */
+ var http = JSONRpcClient.poolGetHTTPRequest();
+ JSONRpcClient.num_req_active++;
+
+ /* Send the request */
+ if (typeof(this.user) == "undefined") {
+ http.open("POST", this.serverURL, (req.cb != null));
+ } else {
+ http.open("POST", this.serverURL, (req.cb != null), this.user, this.pass);
+ }
+
+ /* setRequestHeader is missing in Opera 8 Beta */
+ try { http.setRequestHeader("Content-type", "text/plain"); } catch(e) {}
+
+ /* Construct call back if we have one */
+ if(req.cb) {
+ var self = this;
+ http.onreadystatechange = function() {
+ if(http.readyState == 4) {
+ http.onreadystatechange = function () {};
+ var res = { "cb": req.cb, "result": null, "ex": null};
+ if (req.profile) {
+ res.profile = req.profile;
+ res.profile.end = new Date();
+ }
+ try { res.result = self._handleResponse(http); }
+ catch(e) { res.ex = e; }
+ if(!JSONRpcClient.async_inflight[req.requestId].canceled)
+ JSONRpcClient.async_responses.push(res);
+ delete JSONRpcClient.async_inflight[req.requestId];
+ JSONRpcClient.kick_async();
+ }
+ };
+ } else {
+ http.onreadystatechange = function() {};
+ }
+
+ JSONRpcClient.async_inflight[req.requestId] = req;
+
+ try {
+ http.send(req.data);
+ } catch(e) {
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+ throw new JSONRpcClient.Exception
+ (JSONRpcClient.Exception.CODE_ERR_CLIENT, "Connection failed");
+ }
+
+ if(!req.cb) return this._handleResponse(http);
+};
+
+JSONRpcClient.prototype._handleResponse =
+function JSONRpcClient_handleResponse(http)
+{
+ /* Get the charset */
+ if(!this.charset) {
+ this.charset = JSONRpcClient._getCharsetFromHeaders(http);
+ }
+
+ /* Get request results */
+ var status, statusText, data;
+ try {
+ status = http.status;
+ statusText = http.statusText;
+ data = http.responseText;
+ } catch(e) {
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+ JSONRpcClient.kick_async();
+ throw new JSONRpcClient.Exception
+ (JSONRpcClient.Exception.CODE_ERR_CLIENT, "Connection failed");
+ }
+
+ /* Return http object to the pool; */
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+
+ /* Unmarshall the response */
+ if(status != 200) {
+ throw new JSONRpcClient.Exception(status, statusText);
+ }
+ var obj;
+ try {
+ eval("obj = " + data);
+ } catch(e) {
+ throw new JSONRpcClient.Exception(550, "error parsing result");
+ }
+ if(obj.error)
+ throw new JSONRpcClient.Exception(obj.error.code, obj.error.msg,
+ obj.error.trace);
+ var res = obj.result;
+
+ /* Handle CallableProxy */
+ if(res && res.objectID && res.JSONRPCType == "CallableReference")
+ return new JSONRpcClient(this.serverURL, this.user,
+ this.pass, res.objectID);
+
+ return res;
+};
+
+
+/* XMLHttpRequest wrapper code */
+
+/* XMLHttpRequest pool globals */
+JSONRpcClient.http_spare = [];
+JSONRpcClient.http_max_spare = 8;
+
+JSONRpcClient.poolGetHTTPRequest =
+function JSONRpcClient_pool_getHTTPRequest()
+{
+ if(JSONRpcClient.http_spare.length > 0) {
+ return JSONRpcClient.http_spare.pop();
+ }
+ return JSONRpcClient.getHTTPRequest();
+};
+
+JSONRpcClient.poolReturnHTTPRequest =
+function JSONRpcClient_poolReturnHTTPRequest(http)
+{
+ if(JSONRpcClient.http_spare.length >= JSONRpcClient.http_max_spare)
+ delete http;
+ else
+ JSONRpcClient.http_spare.push(http);
+};
+
+JSONRpcClient.msxmlNames = [ "MSXML2.XMLHTTP.5.0",
+ "MSXML2.XMLHTTP.4.0",
+ "MSXML2.XMLHTTP.3.0",
+ "MSXML2.XMLHTTP",
+ "Microsoft.XMLHTTP" ];
+
+JSONRpcClient.getHTTPRequest =
+function JSONRpcClient_getHTTPRequest()
+{
+ /* Mozilla XMLHttpRequest */
+ try {
+ JSONRpcClient.httpObjectName = "XMLHttpRequest";
+ return new XMLHttpRequest();
+ } catch(e) {}
+
+ /* Microsoft MSXML ActiveX */
+ for (var i=0;i < JSONRpcClient.msxmlNames.length; i++) {
+ try {
+ JSONRpcClient.httpObjectName = JSONRpcClient.msxmlNames[i];
+ return new ActiveXObject(JSONRpcClient.msxmlNames[i]);
+ } catch (e) {}
+ }
+
+ /* None found */
+ JSONRpcClient.httpObjectName = null;
+ throw new JSONRpcClient.Exception(0, "Can't create XMLHttpRequest object");
+};
+
+
+/*
+ * 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.
+ */
+
+function AtomClient(uri) {
+
+ this.msxmlNames = [ "MSXML2.XMLHTTP.5.0",
+ "MSXML2.XMLHTTP.4.0",
+ "MSXML2.XMLHTTP.3.0",
+ "MSXML2.XMLHTTP",
+ "Microsoft.XMLHTTP" ];
+
+ this.uri=uri;
+
+ this.get = function(id, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("get - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("GET", uri + '/' + id, true);
+ xhr.send(null);
+ }
+
+ this.post = function (entry, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 201) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("post - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("POST", uri, true);
+ xhr.setRequestHeader("Content-Type", "application/atom+xml");
+ xhr.send(entry);
+ }
+
+ this.put = function (id, entry, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("put - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("PUT", uri + '/' + id, true);
+ xhr.setRequestHeader("Content-Type", "application/atom+xml");
+ xhr.send(entry);
+ }
+
+ this.del = function (id, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ if (responseFunction != null) responseFunction();
+ } else {
+ alert("delete - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("DELETE", uri + '/' + id, true);
+ xhr.send(null);
+ }
+ this.createXMLHttpRequest = function () {
+ /* Mozilla XMLHttpRequest */
+ try {return new XMLHttpRequest();} catch(e) {}
+
+ /* Microsoft MSXML ActiveX */
+ for (var i=0;i < this.msxmlNames.length; i++) {
+ try {return new ActiveXObject(this.msxmlNames[i]);} catch (e) {}
+ }
+ alert("XML http request not supported");
+ return null;
+ }
+ if (typeof DOMParser == "undefined") {
+ DOMParser = function () {}
+
+ DOMParser.prototype.parseFromString = function (str, contentType) {
+ if (typeof ActiveXObject != "undefined") {
+ var d = new ActiveXObject("MSXML.DomDocument");
+ d.loadXML(str);
+ return d;
+ } else if (typeof XMLHttpRequest != "undefined") {
+ var req = new XMLHttpRequest;
+ req.open("GET", "data:" + (contentType || "application/xml") +
+ ";charset=utf-8," + encodeURIComponent(str), false);
+ if (req.overrideMimeType) {
+ req.overrideMimeType(contentType);
+ }
+ req.send(null);
+ return req.responseXML;
+ }
+ }
+ }
+}
+
+
+
+/* Tuscany Reference/Property injection code */
+
+if (!tuscany) {
+var tuscany = {};
+}
+if (!tuscany.sca) {
+tuscany.sca = {};
+}
+
+tuscany.sca.propertyMap = new String();
+tuscany.sca.Property = function (name) {
+ return tuscany.sca.propertyMap[name];
+}
+
+tuscany.sca.referenceMap = new Object();
+tuscany.sca.referenceMap.catalog = new JSONRpcClient("/catalog").Service;
+tuscany.sca.referenceMap.shoppingCart = new AtomClient("/shoppingCart");
+tuscany.sca.referenceMap.shoppingTotal = new JSONRpcClient("/total").Service;
+tuscany.sca.Reference = function (name) {
+ return tuscany.sca.referenceMap[name];
+}
+
+/** End of Apache Tuscany SCA Widget */
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-python/server-test b/sca-cpp/branches/gcc-4.4/test/store-python/server-test
new file mode 100755
index 0000000000..d2013f6892
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-python/server-test
@@ -0,0 +1,40 @@
+#!/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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/store.html 2>/dev/null >tmp/store.html
+diff tmp/store.html htdocs/store.html
+rc=$?
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/test/store-python/shopping-cart.py b/sca-cpp/branches/gcc-4.4/test/store-python/shopping-cart.py
new file mode 100644
index 0000000000..2cb6da140a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-python/shopping-cart.py
@@ -0,0 +1,78 @@
+# 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.
+
+# Shopping cart implementation
+import uuid
+import sys
+
+cartId = "1234"
+
+# Get the shopping cart from the cache
+# Return an empty cart if not found
+def getcart(id, cache):
+ cart = cache("get", (id,))
+ if cart is None:
+ return ()
+ return cart
+
+# Post a new item to the cart, create a new cart if necessary
+def post(collection, item, cache):
+ id = str(uuid.uuid1())
+ cart = ((item[0], id, item[2]),) + getcart(cartId, cache)
+ cache("put", (cartId,), cart)
+ return (id,)
+
+
+# Find an item in the cart
+def find(id, cart):
+ if cart == ():
+ return ("Item", "0", ())
+ elif id == cart[0][1]:
+ return cart[0]
+ else:
+ return find(id, cart[1:])
+
+# Get items from the cart
+def get(id, cache):
+ if id == ():
+ return ("Your Cart", cartId) + getcart(cartId, cache)
+ return find(id[0], getcart(cartId, cache))
+
+# Delete items from the cart
+def delete(id, cache):
+ if id == ():
+ return cache("delete", (cartId,))
+ return True
+
+# Return the price of an item
+def price(item):
+ return float(filter(lambda x: x[0] == "'price", item[2])[0][1])
+
+# Sum the prices of a list of items
+def sum(items):
+ if items == ():
+ return 0
+ return price(items[0]) + sum(items[1:])
+
+# Return the total price of the items in the cart
+def gettotal(cache):
+ cart = getcart(cartId, cache)
+ return sum(cart)
+
+# TODO remove these JSON-RPC specific functions
+def listMethods(cache):
+ return ("Service.gettotal",)
diff --git a/sca-cpp/branches/gcc-4.4/test/store-python/ssl-start b/sca-cpp/branches/gcc-4.4/test/store-python/ssl-start
new file mode 100755
index 0000000000..1e70d6edfb
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-python/ssl-start
@@ -0,0 +1,34 @@
+#!/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-ca-conf tmp localhost
+../../modules/http/httpd-cert-conf tmp localhost
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/http/httpd-ssl-conf tmp localhost 8453 htdocs
+../../modules/server/server-conf tmp
+../../modules/python/python-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sca-cpp/branches/gcc-4.4/test/store-python/start b/sca-cpp/branches/gcc-4.4/test/store-python/start
new file mode 100755
index 0000000000..8df7875634
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-python/start
@@ -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.
+
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/server/server-conf tmp
+../../modules/python/python-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sca-cpp/branches/gcc-4.4/test/store-python/stop b/sca-cpp/branches/gcc-4.4/test/store-python/stop
new file mode 100755
index 0000000000..a59273b8ed
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-python/stop
@@ -0,0 +1,21 @@
+#!/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
+../../components/cache/memcached-stop
diff --git a/sca-cpp/branches/gcc-4.4/test/store-python/store.composite b/sca-cpp/branches/gcc-4.4/test/store-python/store.composite
new file mode 100644
index 0000000000..889f514624
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-python/store.composite
@@ -0,0 +1,69 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.python script="store.py"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.python script="fruits-catalog.py"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.python script="shopping-cart.py"/>
+ <service name="ShoppingCart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.python script="currency-converter.py"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+ <component name="Cache">
+ <implementation.cpp path="../../components/cache/.libs" library="libmemcache"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/test/store-python/store.py b/sca-cpp/branches/gcc-4.4/test/store-python/store.py
new file mode 100644
index 0000000000..35c0f5b2aa
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-python/store.py
@@ -0,0 +1,44 @@
+# 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.
+
+# Store implementation
+
+def post(item, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart("post", item)
+
+def getall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart("getall")
+
+def get(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart("get", id)
+
+def getcatalog(catalog, shoppingCart, shoppingTotal):
+ return catalog("get")
+
+def gettotal(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart("gettotal")
+
+def deleteall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart("deleteall")
+
+def delete(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart("delete", id)
+
+# TODO remove these JSON-RPC specific functions
+def listMethods(catalog, shoppingCart, shoppingTotal):
+ return ("Service.get", "Service.gettotal")
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-scheme/Makefile.am b/sca-cpp/branches/gcc-4.4/test/store-scheme/Makefile.am
new file mode 100644
index 0000000000..77cceb8352
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-scheme/Makefile.am
@@ -0,0 +1,23 @@
+# 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.
+
+noinst_PROGRAMS = script-test
+
+script_test_SOURCES = script-test.cpp
+script_test_LDFLAGS = -lxml2 -lmozjs
+
+TESTS = script-test server-test
diff --git a/sca-cpp/branches/gcc-4.4/test/store-scheme/currency-converter.scm b/sca-cpp/branches/gcc-4.4/test/store-scheme/currency-converter.scm
new file mode 100644
index 0000000000..fc506c3d73
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-scheme/currency-converter.scm
@@ -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.
+
+; Currency converter implementation
+
+(define (convert from to amount)
+ (if (equal? to "EUR") (* amount 0.70) amount)
+)
+
+(define (symbol currency)
+ (if (equal? currency "EUR") "E" "$")
+)
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-scheme/fruits-catalog.scm b/sca-cpp/branches/gcc-4.4/test/store-scheme/fruits-catalog.scm
new file mode 100644
index 0000000000..d79ff1b677
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-scheme/fruits-catalog.scm
@@ -0,0 +1,33 @@
+; 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.
+
+; Catalog implementation
+
+(define (get converter currencyCode)
+ (define code (currencyCode))
+ (define (convert price) (converter "convert" "USD" code price))
+ (define symbol (converter "symbol" code))
+ (list
+ (list (list 'javaClass "services.Item") (list 'name "Apple") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price (convert 2.99)))
+ (list (list 'javaClass "services.Item") (list 'name "Orange") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price (convert 3.55)))
+ (list (list 'javaClass "services.Item") (list 'name "Pear") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price (convert 1.55)))
+ )
+)
+
+; TODO remove these JSON-RPC specific functions
+(define (listMethods converter currencyCode) (list "Service.get"))
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-scheme/htdocs/.htaccess b/sca-cpp/branches/gcc-4.4/test/store-scheme/htdocs/.htaccess
new file mode 100644
index 0000000000..e2e343b6b2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-scheme/htdocs/.htaccess
@@ -0,0 +1,19 @@
+#
+# 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.
+
+DirectoryIndex store.html
diff --git a/sca-cpp/branches/gcc-4.4/test/store-scheme/htdocs/store.html b/sca-cpp/branches/gcc-4.4/test/store-scheme/htdocs/store.html
new file mode 100644
index 0000000000..21eabca7a7
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-scheme/htdocs/store.html
@@ -0,0 +1,169 @@
+<!--
+ * 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>Store</title>
+
+<script type="text/javascript" src="store.js"></script>
+
+<script language="JavaScript">
+
+ //@Reference
+ var catalog = new tuscany.sca.Reference("catalog");
+
+ //@Reference
+ var shoppingCart = new tuscany.sca.Reference("shoppingCart");
+
+ //@Reference
+ var shoppingTotal = new tuscany.sca.Reference("shoppingTotal");
+
+ var catalogItems;
+
+ function catalog_getResponse(items,exception) {
+ if(exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+ // TEMP
+ shoppingTotal.gettotal(shoppingTotal_getTotalResponse);
+ }
+
+ function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ if (entries.length != 0) {
+ try {
+ shoppingTotal.gettotal(shoppingTotal_getTotalResponse);
+ }
+ catch(e){
+ alert(e);
+ }
+ }
+ }
+ }
+
+ function shoppingTotal_getTotalResponse(total,exception) {
+ if(exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+ }
+
+ function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+ }
+
+ function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<javaClass>' + catalogItems[i].javaClass + '</javaClass>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+ }
+ function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+ }
+ function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+ }
+
+ function init() {
+
+ try {
+ catalog.get(catalog_getResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ }
+ catch(e){
+ alert(e);
+ }
+ }
+
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Store</h1>
+ <div id="store">
+ <h2>Catalog</h2>
+ <form name="catalogForm">
+ <div id="catalog" ></div>
+ <br>
+ <input type="button" onClick="addToCart()" value="Add to Cart">
+ </form>
+
+ <br>
+
+ <h2>Your Shopping Cart</h2>
+ <form name="shoppingCartForm">
+ <div id="shoppingCart"></div>
+ <br>
+ <div id="total"></div>
+ <br>
+ <input type="button" onClick="checkoutCart()" value="Checkout">
+ <input type="button" onClick="deleteCart()" value="Empty">
+ <a href="../shoppingCart/">(feed)</a>
+ </form>
+ </div>
+</body>
+</html>
diff --git a/sca-cpp/branches/gcc-4.4/test/store-scheme/htdocs/store.js b/sca-cpp/branches/gcc-4.4/test/store-scheme/htdocs/store.js
new file mode 100644
index 0000000000..9cd8eb526d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-scheme/htdocs/store.js
@@ -0,0 +1,661 @@
+
+/* Apache Tuscany SCA Widget header */
+
+/*
+ * JSON-RPC JavaScript client
+ *
+ * $Id: jsonrpc.js,v 1.36.2.3 2006/03/08 15:09:37 mclark Exp $
+ *
+ * Copyright (c) 2003-2004 Jan-Klaas Kollhof
+ * Copyright (c) 2005 Michael Clark, Metaparadigm Pte Ltd
+ *
+ * This code is based on Jan-Klaas' JavaScript o lait library (jsolait).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * Modifications for Apache Tuscany:
+ * - JSONRpcClient_createMethod changed so callback is last arg
+ */
+
+/* escape a character */
+
+escapeJSONChar =
+function escapeJSONChar(c)
+{
+ if(c == "\"" || c == "\\") return "\\" + c;
+ else if (c == "\b") return "\\b";
+ else if (c == "\f") return "\\f";
+ else if (c == "\n") return "\\n";
+ else if (c == "\r") return "\\r";
+ else if (c == "\t") return "\\t";
+ var hex = c.charCodeAt(0).toString(16);
+ if(hex.length == 1) return "\\u000" + hex;
+ else if(hex.length == 2) return "\\u00" + hex;
+ else if(hex.length == 3) return "\\u0" + hex;
+ else return "\\u" + hex;
+};
+
+
+/* encode a string into JSON format */
+
+escapeJSONString =
+function escapeJSONString(s)
+{
+ /* The following should suffice but Safari's regex is b0rken
+ (doesn't support callback substitutions)
+ return "\"" + s.replace(/([^\u0020-\u007f]|[\\\"])/g,
+ escapeJSONChar) + "\"";
+ */
+
+ /* Rather inefficient way to do it */
+ var parts = s.split("");
+ for(var i=0; i < parts.length; i++) {
+ var c =parts[i];
+ if(c == '"' ||
+ c == '\\' ||
+ c.charCodeAt(0) < 32 ||
+ c.charCodeAt(0) >= 128)
+ parts[i] = escapeJSONChar(parts[i]);
+ }
+ return "\"" + parts.join("") + "\"";
+};
+
+
+/* Marshall objects to JSON format */
+
+toJSON = function toJSON(o)
+{
+ if(o == null) {
+ return "null";
+ } else if(o.constructor == String) {
+ return escapeJSONString(o);
+ } else if(o.constructor == Number) {
+ return o.toString();
+ } else if(o.constructor == Boolean) {
+ return o.toString();
+ } else if(o.constructor == Date) {
+ return '{javaClass: "java.util.Date", time: ' + o.valueOf() +'}';
+ } else if(o.constructor == Array) {
+ var v = [];
+ for(var i = 0; i < o.length; i++) v.push(toJSON(o[i]));
+ return "[" + v.join(", ") + "]";
+ } else {
+ var v = [];
+ for(attr in o) {
+ if(o[attr] == null) v.push("\"" + attr + "\": null");
+ else if(typeof o[attr] == "function"); /* skip */
+ else v.push(escapeJSONString(attr) + ": " + toJSON(o[attr]));
+ }
+ return "{" + v.join(", ") + "}";
+ }
+};
+
+
+/* JSONRpcClient constructor */
+
+JSONRpcClient =
+function JSONRpcClient_ctor(serverURL, user, pass, objectID)
+{
+ this.serverURL = serverURL;
+ this.user = user;
+ this.pass = pass;
+ this.objectID = objectID;
+
+ /* Add standard methods */
+ if(this.objectID) {
+ this._addMethods(["listMethods"]);
+ var req = this._makeRequest("listMethods", []);
+ } else {
+ this._addMethods(["system.listMethods"]);
+ var req = this._makeRequest("system.listMethods", []);
+ }
+ var m = this._sendRequest(req);
+ this._addMethods(m);
+};
+
+
+/* JSONRpcCLient.Exception */
+
+JSONRpcClient.Exception =
+function JSONRpcClient_Exception_ctor(code, message, javaStack)
+{
+ this.code = code;
+ var name;
+ if(javaStack) {
+ this.javaStack = javaStack;
+ var m = javaStack.match(/^([^:]*)/);
+ if(m) name = m[0];
+ }
+ if(name) this.name = name;
+ else this.name = "JSONRpcClientException";
+ this.message = message;
+};
+
+JSONRpcClient.Exception.CODE_REMOTE_EXCEPTION = 490;
+JSONRpcClient.Exception.CODE_ERR_CLIENT = 550;
+JSONRpcClient.Exception.CODE_ERR_PARSE = 590;
+JSONRpcClient.Exception.CODE_ERR_NOMETHOD = 591;
+JSONRpcClient.Exception.CODE_ERR_UNMARSHALL = 592;
+JSONRpcClient.Exception.CODE_ERR_MARSHALL = 593;
+
+JSONRpcClient.Exception.prototype = new Error();
+
+JSONRpcClient.Exception.prototype.toString =
+function JSONRpcClient_Exception_toString(code, msg)
+{
+ return this.name + ": " + this.message;
+};
+
+
+/* Default top level exception handler */
+
+JSONRpcClient.default_ex_handler =
+function JSONRpcClient_default_ex_handler(e) { alert(e); };
+
+
+/* Client settable variables */
+
+JSONRpcClient.toplevel_ex_handler = JSONRpcClient.default_ex_handler;
+JSONRpcClient.profile_async = false;
+JSONRpcClient.max_req_active = 1;
+JSONRpcClient.requestId = 1;
+
+
+/* JSONRpcClient implementation */
+
+JSONRpcClient.prototype._createMethod =
+function JSONRpcClient_createMethod(methodName)
+{
+ var fn=function()
+ {
+ var args = [];
+ var callback = null;
+ for(var i=0;i<arguments.length;i++) args.push(arguments[i]);
+
+/* TUSCANY change callback to be last arg instead of first to match binding.ajax
+ if(typeof args[0] == "function") callback = args.shift();
+*/
+ if(typeof args[arguments.length-1] == "function") callback = args.pop();
+
+ var req = fn.client._makeRequest.call(fn.client, fn.methodName,
+ args, callback);
+ if(callback == null) {
+ return fn.client._sendRequest.call(fn.client, req);
+ } else {
+ JSONRpcClient.async_requests.push(req);
+ JSONRpcClient.kick_async();
+ return req.requestId;
+ }
+ };
+ fn.client = this;
+ fn.methodName = methodName;
+ return fn;
+};
+
+JSONRpcClient.prototype._addMethods =
+function JSONRpcClient_addMethods(methodNames)
+{
+ for(var i=0; i<methodNames.length; i++) {
+ var obj = this;
+ var names = methodNames[i].split(".");
+ for(var n=0; n<names.length-1; n++) {
+ var name = names[n];
+ if(obj[name]) {
+ obj = obj[name];
+ } else {
+ obj[name] = new Object();
+ obj = obj[name];
+ }
+ }
+ var name = names[names.length-1];
+ if(!obj[name]) {
+ var method = this._createMethod(methodNames[i]);
+ obj[name] = method;
+ }
+ }
+};
+
+JSONRpcClient._getCharsetFromHeaders =
+function JSONRpcClient_getCharsetFromHeaders(http)
+{
+ try {
+ var contentType = http.getResponseHeader("Content-type");
+ var parts = contentType.split(/\s*;\s*/);
+ for(var i =0; i < parts.length; i++) {
+ if(parts[i].substring(0, 8) == "charset=")
+ return parts[i].substring(8, parts[i].length);
+ }
+ } catch (e) {}
+ return "UTF-8"; /* default */
+};
+
+/* Async queue globals */
+JSONRpcClient.async_requests = [];
+JSONRpcClient.async_inflight = {};
+JSONRpcClient.async_responses = [];
+JSONRpcClient.async_timeout = null;
+JSONRpcClient.num_req_active = 0;
+
+JSONRpcClient._async_handler =
+function JSONRpcClient_async_handler()
+{
+ JSONRpcClient.async_timeout = null;
+
+ while(JSONRpcClient.async_responses.length > 0) {
+ var res = JSONRpcClient.async_responses.shift();
+ if(res.canceled) continue;
+ if(res.profile) res.profile.dispatch = new Date();
+ try {
+ res.cb(res.result, res.ex, res.profile);
+ } catch(e) {
+ JSONRpcClient.toplevel_ex_handler(e);
+ }
+ }
+
+ while(JSONRpcClient.async_requests.length > 0 &&
+ JSONRpcClient.num_req_active < JSONRpcClient.max_req_active) {
+ var req = JSONRpcClient.async_requests.shift();
+ if(req.canceled) continue;
+ req.client._sendRequest.call(req.client, req);
+ }
+};
+
+JSONRpcClient.kick_async =
+function JSONRpcClient_kick_async()
+{
+ if(JSONRpcClient.async_timeout == null)
+ JSONRpcClient.async_timeout =
+ setTimeout(JSONRpcClient._async_handler, 0);
+};
+
+JSONRpcClient.cancelRequest =
+function JSONRpcClient_cancelRequest(requestId)
+{
+ /* If it is in flight then mark it as canceled in the inflight map
+ and the XMLHttpRequest callback will discard the reply. */
+ if(JSONRpcClient.async_inflight[requestId]) {
+ JSONRpcClient.async_inflight[requestId].canceled = true;
+ return true;
+ }
+
+ /* If its not in flight yet then we can just mark it as canceled in
+ the the request queue and it will get discarded before being sent. */
+ for(var i in JSONRpcClient.async_requests) {
+ if(JSONRpcClient.async_requests[i].requestId == requestId) {
+ JSONRpcClient.async_requests[i].canceled = true;
+ return true;
+ }
+ }
+
+ /* It may have returned from the network and be waiting for its callback
+ to be dispatched, so mark it as canceled in the response queue
+ and the response will get discarded before calling the callback. */
+ for(var i in JSONRpcClient.async_responses) {
+ if(JSONRpcClient.async_responses[i].requestId == requestId) {
+ JSONRpcClient.async_responses[i].canceled = true;
+ return true;
+ }
+ }
+
+ return false;
+};
+
+JSONRpcClient.prototype._makeRequest =
+function JSONRpcClient_makeRequest(methodName, args, cb)
+{
+ var req = {};
+ req.client = this;
+ req.requestId = JSONRpcClient.requestId++;
+
+ var obj = {};
+ obj.id = req.requestId;
+ if (this.objectID)
+ obj.method = ".obj#" + this.objectID + "." + methodName;
+ else
+ obj.method = methodName;
+ obj.params = args;
+
+ if (cb) req.cb = cb;
+ if (JSONRpcClient.profile_async)
+ req.profile = { "submit": new Date() };
+ req.data = toJSON(obj);
+
+ return req;
+};
+
+JSONRpcClient.prototype._sendRequest =
+function JSONRpcClient_sendRequest(req)
+{
+ if(req.profile) req.profile.start = new Date();
+
+ /* Get free http object from the pool */
+ var http = JSONRpcClient.poolGetHTTPRequest();
+ JSONRpcClient.num_req_active++;
+
+ /* Send the request */
+ if (typeof(this.user) == "undefined") {
+ http.open("POST", this.serverURL, (req.cb != null));
+ } else {
+ http.open("POST", this.serverURL, (req.cb != null), this.user, this.pass);
+ }
+
+ /* setRequestHeader is missing in Opera 8 Beta */
+ try { http.setRequestHeader("Content-type", "text/plain"); } catch(e) {}
+
+ /* Construct call back if we have one */
+ if(req.cb) {
+ var self = this;
+ http.onreadystatechange = function() {
+ if(http.readyState == 4) {
+ http.onreadystatechange = function () {};
+ var res = { "cb": req.cb, "result": null, "ex": null};
+ if (req.profile) {
+ res.profile = req.profile;
+ res.profile.end = new Date();
+ }
+ try { res.result = self._handleResponse(http); }
+ catch(e) { res.ex = e; }
+ if(!JSONRpcClient.async_inflight[req.requestId].canceled)
+ JSONRpcClient.async_responses.push(res);
+ delete JSONRpcClient.async_inflight[req.requestId];
+ JSONRpcClient.kick_async();
+ }
+ };
+ } else {
+ http.onreadystatechange = function() {};
+ }
+
+ JSONRpcClient.async_inflight[req.requestId] = req;
+
+ try {
+ http.send(req.data);
+ } catch(e) {
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+ throw new JSONRpcClient.Exception
+ (JSONRpcClient.Exception.CODE_ERR_CLIENT, "Connection failed");
+ }
+
+ if(!req.cb) return this._handleResponse(http);
+};
+
+JSONRpcClient.prototype._handleResponse =
+function JSONRpcClient_handleResponse(http)
+{
+ /* Get the charset */
+ if(!this.charset) {
+ this.charset = JSONRpcClient._getCharsetFromHeaders(http);
+ }
+
+ /* Get request results */
+ var status, statusText, data;
+ try {
+ status = http.status;
+ statusText = http.statusText;
+ data = http.responseText;
+ } catch(e) {
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+ JSONRpcClient.kick_async();
+ throw new JSONRpcClient.Exception
+ (JSONRpcClient.Exception.CODE_ERR_CLIENT, "Connection failed");
+ }
+
+ /* Return http object to the pool; */
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+
+ /* Unmarshall the response */
+ if(status != 200) {
+ throw new JSONRpcClient.Exception(status, statusText);
+ }
+ var obj;
+ try {
+ eval("obj = " + data);
+ } catch(e) {
+ throw new JSONRpcClient.Exception(550, "error parsing result");
+ }
+ if(obj.error)
+ throw new JSONRpcClient.Exception(obj.error.code, obj.error.msg,
+ obj.error.trace);
+ var res = obj.result;
+
+ /* Handle CallableProxy */
+ if(res && res.objectID && res.JSONRPCType == "CallableReference")
+ return new JSONRpcClient(this.serverURL, this.user,
+ this.pass, res.objectID);
+
+ return res;
+};
+
+
+/* XMLHttpRequest wrapper code */
+
+/* XMLHttpRequest pool globals */
+JSONRpcClient.http_spare = [];
+JSONRpcClient.http_max_spare = 8;
+
+JSONRpcClient.poolGetHTTPRequest =
+function JSONRpcClient_pool_getHTTPRequest()
+{
+ if(JSONRpcClient.http_spare.length > 0) {
+ return JSONRpcClient.http_spare.pop();
+ }
+ return JSONRpcClient.getHTTPRequest();
+};
+
+JSONRpcClient.poolReturnHTTPRequest =
+function JSONRpcClient_poolReturnHTTPRequest(http)
+{
+ if(JSONRpcClient.http_spare.length >= JSONRpcClient.http_max_spare)
+ delete http;
+ else
+ JSONRpcClient.http_spare.push(http);
+};
+
+JSONRpcClient.msxmlNames = [ "MSXML2.XMLHTTP.5.0",
+ "MSXML2.XMLHTTP.4.0",
+ "MSXML2.XMLHTTP.3.0",
+ "MSXML2.XMLHTTP",
+ "Microsoft.XMLHTTP" ];
+
+JSONRpcClient.getHTTPRequest =
+function JSONRpcClient_getHTTPRequest()
+{
+ /* Mozilla XMLHttpRequest */
+ try {
+ JSONRpcClient.httpObjectName = "XMLHttpRequest";
+ return new XMLHttpRequest();
+ } catch(e) {}
+
+ /* Microsoft MSXML ActiveX */
+ for (var i=0;i < JSONRpcClient.msxmlNames.length; i++) {
+ try {
+ JSONRpcClient.httpObjectName = JSONRpcClient.msxmlNames[i];
+ return new ActiveXObject(JSONRpcClient.msxmlNames[i]);
+ } catch (e) {}
+ }
+
+ /* None found */
+ JSONRpcClient.httpObjectName = null;
+ throw new JSONRpcClient.Exception(0, "Can't create XMLHttpRequest object");
+};
+
+
+/*
+ * 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.
+ */
+
+function AtomClient(uri) {
+
+ this.msxmlNames = [ "MSXML2.XMLHTTP.5.0",
+ "MSXML2.XMLHTTP.4.0",
+ "MSXML2.XMLHTTP.3.0",
+ "MSXML2.XMLHTTP",
+ "Microsoft.XMLHTTP" ];
+
+ this.uri=uri;
+
+ this.get = function(id, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("get - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("GET", uri + '/' + id, true);
+ xhr.send(null);
+ }
+
+ this.post = function (entry, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 201) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("post - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("POST", uri, true);
+ xhr.setRequestHeader("Content-Type", "application/atom+xml");
+ xhr.send(entry);
+ }
+
+ this.put = function (id, entry, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("put - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("PUT", uri + '/' + id, true);
+ xhr.setRequestHeader("Content-Type", "application/atom+xml");
+ xhr.send(entry);
+ }
+
+ this.del = function (id, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ if (responseFunction != null) responseFunction();
+ } else {
+ alert("delete - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("DELETE", uri + '/' + id, true);
+ xhr.send(null);
+ }
+ this.createXMLHttpRequest = function () {
+ /* Mozilla XMLHttpRequest */
+ try {return new XMLHttpRequest();} catch(e) {}
+
+ /* Microsoft MSXML ActiveX */
+ for (var i=0;i < this.msxmlNames.length; i++) {
+ try {return new ActiveXObject(this.msxmlNames[i]);} catch (e) {}
+ }
+ alert("XML http request not supported");
+ return null;
+ }
+ if (typeof DOMParser == "undefined") {
+ DOMParser = function () {}
+
+ DOMParser.prototype.parseFromString = function (str, contentType) {
+ if (typeof ActiveXObject != "undefined") {
+ var d = new ActiveXObject("MSXML.DomDocument");
+ d.loadXML(str);
+ return d;
+ } else if (typeof XMLHttpRequest != "undefined") {
+ var req = new XMLHttpRequest;
+ req.open("GET", "data:" + (contentType || "application/xml") +
+ ";charset=utf-8," + encodeURIComponent(str), false);
+ if (req.overrideMimeType) {
+ req.overrideMimeType(contentType);
+ }
+ req.send(null);
+ return req.responseXML;
+ }
+ }
+ }
+}
+
+
+
+/* Tuscany Reference/Property injection code */
+
+if (!tuscany) {
+var tuscany = {};
+}
+if (!tuscany.sca) {
+tuscany.sca = {};
+}
+
+tuscany.sca.propertyMap = new String();
+tuscany.sca.Property = function (name) {
+ return tuscany.sca.propertyMap[name];
+}
+
+tuscany.sca.referenceMap = new Object();
+tuscany.sca.referenceMap.catalog = new JSONRpcClient("/catalog").Service;
+tuscany.sca.referenceMap.shoppingCart = new AtomClient("/shoppingCart");
+tuscany.sca.referenceMap.shoppingTotal = new JSONRpcClient("/total").Service;
+tuscany.sca.Reference = function (name) {
+ return tuscany.sca.referenceMap[name];
+}
+
+/** End of Apache Tuscany SCA Widget */
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-scheme/script-test.cpp b/sca-cpp/branches/gcc-4.4/test/store-scheme/script-test.cpp
new file mode 100644
index 0000000000..c8eecb65c3
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-scheme/script-test.cpp
@@ -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.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Store Test case.
+ */
+
+#include <assert.h>
+#include <regex.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "list.hpp"
+#include "xml.hpp"
+#include "../../modules/scheme/driver.hpp"
+#include "../../modules/json/json.hpp"
+
+namespace store {
+
+using namespace tuscany;
+
+bool testScript() {
+ gc_scoped_pool pool;
+
+ ifstream is("script-test.scm");
+ ostringstream os;
+ scheme::evalDriverRun(is, os);
+ assert(contains(str(os), "(\"Sample Feed\" \""));
+ assert(contains(str(os), "\" (\"Item\" \""));
+ assert(contains(str(os), "\" ((javaClass \"services.Item\") (name \"Orange\") (currencyCode \"USD\") (currencySymbol \"$\") (price 3.55))) (\"Item\" \""));
+ assert(contains(str(os), "\" ((javaClass \"services.Item\") (name \"Apple\") (currencyCode \"USD\") (currencySymbol \"$\") (price 2.99))))"));
+ return true;
+}
+
+bool testEval() {
+ {
+ gc_scoped_pool pool;
+ ifstream is("script-test.scm");
+ ostringstream os;
+ scheme::setupDisplay(os);
+ scheme::Env globalEnv = scheme::setupEnvironment();
+ const value exp(mklist<value>("storeui_service", string("getcatalog")));
+ const value val = scheme::evalScript(exp, is, globalEnv);
+
+ ostringstream vs;
+ vs << val;
+ assert(contains(str(vs), "(((javaClass \"services.Item\") (name \"Apple\") (currencyCode \"USD\") (currencySymbol \"$\") (price 2.99)) ((javaClass \"services.Item\") (name \"Orange\") (currencyCode \"USD\") (currencySymbol \"$\") (price 3.55)) ((javaClass \"services.Item\") (name \"Pear\") (currencyCode \"USD\") (currencySymbol \"$\") (price 1.55)))"));
+ }
+
+ {
+ gc_scoped_pool pool;
+ ifstream is("script-test.scm");
+ ostringstream os;
+ scheme::setupDisplay(os);
+
+ scheme::Env globalEnv = scheme::setupEnvironment();
+ const value exp(mklist<value>("storeui_service", string("gettotal")));
+ const value res = scheme::evalScript(exp, is, globalEnv);
+
+ ostringstream rs;
+ rs << res;
+ assert(contains(str(rs), "10"));
+ }
+ return true;
+}
+
+}
+
+int main() {
+
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ store::testScript();
+ store::testEval();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/branches/gcc-4.4/test/store-scheme/script-test.scm b/sca-cpp/branches/gcc-4.4/test/store-scheme/script-test.scm
new file mode 100644
index 0000000000..6db3408794
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-scheme/script-test.scm
@@ -0,0 +1,140 @@
+; 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.
+
+; Currency implementation
+
+(define (currency_convert from to amount)
+ (if (equal? to "EUR") (* amount 0.70) amount)
+)
+
+(define (currency_symbol currency)
+ (if (equal? currency "EUR") "E" "$")
+)
+
+(define (currency_impl op args)
+ (cond
+ ((equal? op "convert") (apply currency_convert args))
+ ((equal? op "symbol") (apply currency_symbol args))
+ )
+)
+
+; Currency composite
+
+(define (currency_service op . args) (currency_impl op args))
+
+; Catalog implementation
+
+(define (catalog_get converter)
+ (define (convert price) (converter "convert" "USD" "USD" price))
+
+ (define code "USD")
+ (define symbol (converter "symbol" code))
+
+ (list
+ (list (list 'javaClass "services.Item") (list 'name "Apple") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price 2.99))
+ (list (list 'javaClass "services.Item") (list 'name "Orange") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price 3.55))
+ (list (list 'javaClass "services.Item") (list 'name "Pear") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price 1.55))
+ )
+)
+
+(define (catalog_impl converter op args)
+ (cond
+ ((equal? op "get") (apply catalog_get (cons converter args)))
+ )
+)
+
+; Catalog composite
+
+(define (catalog_service op . args) (catalog_impl currency_service op args))
+
+; Cart implementation
+
+(define (cart_post content item)
+ (cons (cons "Item" (list (uuid) item)) content)
+)
+
+(define (cart_getall content)
+ (cons "Sample Feed" (cons (uuid) content))
+)
+
+(define (cart_getentry id)
+ (define entry (list (list 'name "Apple") (list 'currencyCode "USD") (list 'currencySymbol "$") (list 'price 2.99)))
+ (cons "Item" (list id entry))
+)
+
+(define (cart_gettotal)
+ 10.0
+)
+
+(define (cart_impl op args)
+ (cond
+ ((equal? op "post") (apply cart_post args))
+ ((equal? op "getall") (apply cart_getall args))
+ ((equal? op "getentry") (apply cart_getentry args))
+ ((equal? op "gettotal") (apply cart_gettotal args))
+ )
+)
+
+; Store UI implementation
+
+(define (storeui_post cart content item)
+ (cart "post" content item)
+)
+
+(define (storeui_getcart cart content)
+ (cart "getall" content)
+)
+
+(define (storeui_getentry cart id)
+ (cart "getentry" id)
+)
+
+(define (storeui_getcatalog catalog)
+ (catalog "get")
+)
+
+(define (storeui_gettotal cart)
+ (cart "gettotal")
+)
+
+(define (storeui_impl cart catalog op args)
+ (cond
+ ((equal? op "post") (apply storeui_post (cons cart args)))
+ ((equal? op "getall") (apply storeui_getcart (cons cart args)))
+ ((equal? op "getentry") (apply storeui_getentry (cons cart args)))
+ ((equal? op "getcatalog") (apply storeui_getcatalog (cons catalog args)))
+ ((equal? op "gettotal") (apply storeui_gettotal (cons cart args)))
+ )
+)
+
+; Store UI composite
+
+(define (cart_service op . args) (cart_impl op args))
+
+(define (storeui_service op . args) (storeui_impl cart_service catalog_service op args))
+
+; Store UI test case
+
+(define catalog (storeui_service "getcatalog"))
+(define empty (list))
+(define apple (car catalog))
+(define orange (car (cdr catalog)))
+(define added1 (storeui_service "post" empty apple))
+(define added2 (storeui_service "post" added1 orange))
+(display (storeui_service "getall" added2))
+(display (storeui_service "gettotal"))
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-scheme/server-test b/sca-cpp/branches/gcc-4.4/test/store-scheme/server-test
new file mode 100755
index 0000000000..d2013f6892
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-scheme/server-test
@@ -0,0 +1,40 @@
+#!/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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/store.html 2>/dev/null >tmp/store.html
+diff tmp/store.html htdocs/store.html
+rc=$?
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/test/store-scheme/shopping-cart.scm b/sca-cpp/branches/gcc-4.4/test/store-scheme/shopping-cart.scm
new file mode 100644
index 0000000000..484044d420
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-scheme/shopping-cart.scm
@@ -0,0 +1,84 @@
+; 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.
+
+; Shopping cart implementation
+
+(define cartId "1234")
+
+; Get the shopping cart from the cache
+; Return an empty cart if not found
+(define (getcart id cache)
+ (define cart (cache "get" (list id)))
+ (if (nul cart)
+ (list)
+ cart)
+)
+
+; Post a new item to the cart, create a new cart if necessary
+(define (post collection item cache)
+ (define id (uuid))
+ (define newItem (list (car item) id (caddr item)))
+ (define cart (cons newItem (getcart cartId cache)))
+ (cache "put" (list cartId) cart)
+ (list id)
+)
+
+; Find an item in the cart
+(define (find id cart)
+ (if (nul cart)
+ (cons "Item" (list "0" (list)))
+ (if (= id (cadr (car cart)))
+ (car cart)
+ (find id (cdr cart))))
+)
+
+; Get items from the cart
+(define (get id cache)
+ (if (nul id)
+ (cons "Your Cart" (cons cartId (getcart cartId cache)))
+ (find (car id) (getcart cartId cache))
+ )
+)
+
+; Delete items from the cart
+(define (delete id cache)
+ (if (nul id)
+ (cache "delete" (list cartId))
+ true
+ )
+)
+
+; Return the price of an item
+(define (price item)
+ (cadr (assoc 'price (caddr item)))
+)
+
+; Sum the prices of a list of items
+(define (sum items)
+ (if (nul items)
+ 0
+ (+ (price (car items)) (sum (cdr items))))
+)
+
+; Return the total price of the items in the cart
+(define (gettotal cache)
+ (define cart (getcart cartId cache))
+ (sum cart)
+)
+
+; TODO remove these JSON-RPC specific functions
+(define (listMethods cache) (list "Service.gettotal"))
diff --git a/sca-cpp/branches/gcc-4.4/test/store-scheme/ssl-start b/sca-cpp/branches/gcc-4.4/test/store-scheme/ssl-start
new file mode 100755
index 0000000000..14b85f5342
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-scheme/ssl-start
@@ -0,0 +1,34 @@
+#!/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-ca-conf tmp localhost
+../../modules/http/httpd-cert-conf tmp localhost
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/http/httpd-ssl-conf tmp localhost 8453 htdocs
+../../modules/server/server-conf tmp
+../../modules/server/scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sca-cpp/branches/gcc-4.4/test/store-scheme/start b/sca-cpp/branches/gcc-4.4/test/store-scheme/start
new file mode 100755
index 0000000000..ffd7173ee2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-scheme/start
@@ -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.
+
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/server/server-conf tmp
+../../modules/server/scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sca-cpp/branches/gcc-4.4/test/store-scheme/stop b/sca-cpp/branches/gcc-4.4/test/store-scheme/stop
new file mode 100755
index 0000000000..a59273b8ed
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-scheme/stop
@@ -0,0 +1,21 @@
+#!/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
+../../components/cache/memcached-stop
diff --git a/sca-cpp/branches/gcc-4.4/test/store-scheme/store.composite b/sca-cpp/branches/gcc-4.4/test/store-scheme/store.composite
new file mode 100644
index 0000000000..36b155b595
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-scheme/store.composite
@@ -0,0 +1,69 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.scheme script="store.scm"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.scheme script="fruits-catalog.scm"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.scheme script="shopping-cart.scm"/>
+ <service name="ShoppingCart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.scheme script="currency-converter.scm"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+ <component name="Cache">
+ <implementation.cpp path="../../components/cache/.libs" library="libmemcache"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/test/store-scheme/store.scm b/sca-cpp/branches/gcc-4.4/test/store-scheme/store.scm
new file mode 100644
index 0000000000..d851dc7ed6
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-scheme/store.scm
@@ -0,0 +1,50 @@
+; 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.
+
+; Store implementation
+
+(define (post item catalog shoppingCart shoppingTotal)
+ (shoppingCart "post" item)
+)
+
+(define (getall catalog shoppingCart shoppingTotal)
+ (shoppingCart "getall")
+)
+
+(define (get id catalog shoppingCart shoppingTotal)
+ (shoppingCart "get" id)
+)
+
+(define (getcatalog catalog shoppingCart shoppingTotal)
+ (catalog "get")
+)
+
+(define (gettotal catalog shoppingCart shoppingTotal)
+ (shoppingCart "gettotal")
+)
+
+(define (deleteall catalog shoppingCart shoppingTotal)
+ (shoppingCart "deleteall")
+)
+
+(define (delete id catalog shoppingCart shoppingTotal)
+ (shoppingCart "delete" id)
+)
+
+; TODO remove these JSON-RPC specific functions
+(define (listMethods catalog shoppingCart shoppingTotal) (list "Service.getcatalog" "Service.gettotal"))
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-sql/Makefile.am b/sca-cpp/branches/gcc-4.4/test/store-sql/Makefile.am
new file mode 100644
index 0000000000..345e58d544
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-sql/Makefile.am
@@ -0,0 +1,19 @@
+# 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.
+
+TESTS = server-test
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-sql/currency-converter.scm b/sca-cpp/branches/gcc-4.4/test/store-sql/currency-converter.scm
new file mode 100644
index 0000000000..fc506c3d73
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-sql/currency-converter.scm
@@ -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.
+
+; Currency converter implementation
+
+(define (convert from to amount)
+ (if (equal? to "EUR") (* amount 0.70) amount)
+)
+
+(define (symbol currency)
+ (if (equal? currency "EUR") "E" "$")
+)
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-sql/fruits-catalog.scm b/sca-cpp/branches/gcc-4.4/test/store-sql/fruits-catalog.scm
new file mode 100644
index 0000000000..d79ff1b677
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-sql/fruits-catalog.scm
@@ -0,0 +1,33 @@
+; 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.
+
+; Catalog implementation
+
+(define (get converter currencyCode)
+ (define code (currencyCode))
+ (define (convert price) (converter "convert" "USD" code price))
+ (define symbol (converter "symbol" code))
+ (list
+ (list (list 'javaClass "services.Item") (list 'name "Apple") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price (convert 2.99)))
+ (list (list 'javaClass "services.Item") (list 'name "Orange") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price (convert 3.55)))
+ (list (list 'javaClass "services.Item") (list 'name "Pear") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price (convert 1.55)))
+ )
+)
+
+; TODO remove these JSON-RPC specific functions
+(define (listMethods converter currencyCode) (list "Service.get"))
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-sql/htdocs/.htaccess b/sca-cpp/branches/gcc-4.4/test/store-sql/htdocs/.htaccess
new file mode 100644
index 0000000000..e2e343b6b2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-sql/htdocs/.htaccess
@@ -0,0 +1,19 @@
+#
+# 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.
+
+DirectoryIndex store.html
diff --git a/sca-cpp/branches/gcc-4.4/test/store-sql/htdocs/store.html b/sca-cpp/branches/gcc-4.4/test/store-sql/htdocs/store.html
new file mode 100644
index 0000000000..21eabca7a7
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-sql/htdocs/store.html
@@ -0,0 +1,169 @@
+<!--
+ * 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>Store</title>
+
+<script type="text/javascript" src="store.js"></script>
+
+<script language="JavaScript">
+
+ //@Reference
+ var catalog = new tuscany.sca.Reference("catalog");
+
+ //@Reference
+ var shoppingCart = new tuscany.sca.Reference("shoppingCart");
+
+ //@Reference
+ var shoppingTotal = new tuscany.sca.Reference("shoppingTotal");
+
+ var catalogItems;
+
+ function catalog_getResponse(items,exception) {
+ if(exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+ // TEMP
+ shoppingTotal.gettotal(shoppingTotal_getTotalResponse);
+ }
+
+ function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ if (entries.length != 0) {
+ try {
+ shoppingTotal.gettotal(shoppingTotal_getTotalResponse);
+ }
+ catch(e){
+ alert(e);
+ }
+ }
+ }
+ }
+
+ function shoppingTotal_getTotalResponse(total,exception) {
+ if(exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+ }
+
+ function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+ }
+
+ function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<javaClass>' + catalogItems[i].javaClass + '</javaClass>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+ }
+ function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+ }
+ function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+ }
+
+ function init() {
+
+ try {
+ catalog.get(catalog_getResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ }
+ catch(e){
+ alert(e);
+ }
+ }
+
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Store</h1>
+ <div id="store">
+ <h2>Catalog</h2>
+ <form name="catalogForm">
+ <div id="catalog" ></div>
+ <br>
+ <input type="button" onClick="addToCart()" value="Add to Cart">
+ </form>
+
+ <br>
+
+ <h2>Your Shopping Cart</h2>
+ <form name="shoppingCartForm">
+ <div id="shoppingCart"></div>
+ <br>
+ <div id="total"></div>
+ <br>
+ <input type="button" onClick="checkoutCart()" value="Checkout">
+ <input type="button" onClick="deleteCart()" value="Empty">
+ <a href="../shoppingCart/">(feed)</a>
+ </form>
+ </div>
+</body>
+</html>
diff --git a/sca-cpp/branches/gcc-4.4/test/store-sql/htdocs/store.js b/sca-cpp/branches/gcc-4.4/test/store-sql/htdocs/store.js
new file mode 100644
index 0000000000..9cd8eb526d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-sql/htdocs/store.js
@@ -0,0 +1,661 @@
+
+/* Apache Tuscany SCA Widget header */
+
+/*
+ * JSON-RPC JavaScript client
+ *
+ * $Id: jsonrpc.js,v 1.36.2.3 2006/03/08 15:09:37 mclark Exp $
+ *
+ * Copyright (c) 2003-2004 Jan-Klaas Kollhof
+ * Copyright (c) 2005 Michael Clark, Metaparadigm Pte Ltd
+ *
+ * This code is based on Jan-Klaas' JavaScript o lait library (jsolait).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * Modifications for Apache Tuscany:
+ * - JSONRpcClient_createMethod changed so callback is last arg
+ */
+
+/* escape a character */
+
+escapeJSONChar =
+function escapeJSONChar(c)
+{
+ if(c == "\"" || c == "\\") return "\\" + c;
+ else if (c == "\b") return "\\b";
+ else if (c == "\f") return "\\f";
+ else if (c == "\n") return "\\n";
+ else if (c == "\r") return "\\r";
+ else if (c == "\t") return "\\t";
+ var hex = c.charCodeAt(0).toString(16);
+ if(hex.length == 1) return "\\u000" + hex;
+ else if(hex.length == 2) return "\\u00" + hex;
+ else if(hex.length == 3) return "\\u0" + hex;
+ else return "\\u" + hex;
+};
+
+
+/* encode a string into JSON format */
+
+escapeJSONString =
+function escapeJSONString(s)
+{
+ /* The following should suffice but Safari's regex is b0rken
+ (doesn't support callback substitutions)
+ return "\"" + s.replace(/([^\u0020-\u007f]|[\\\"])/g,
+ escapeJSONChar) + "\"";
+ */
+
+ /* Rather inefficient way to do it */
+ var parts = s.split("");
+ for(var i=0; i < parts.length; i++) {
+ var c =parts[i];
+ if(c == '"' ||
+ c == '\\' ||
+ c.charCodeAt(0) < 32 ||
+ c.charCodeAt(0) >= 128)
+ parts[i] = escapeJSONChar(parts[i]);
+ }
+ return "\"" + parts.join("") + "\"";
+};
+
+
+/* Marshall objects to JSON format */
+
+toJSON = function toJSON(o)
+{
+ if(o == null) {
+ return "null";
+ } else if(o.constructor == String) {
+ return escapeJSONString(o);
+ } else if(o.constructor == Number) {
+ return o.toString();
+ } else if(o.constructor == Boolean) {
+ return o.toString();
+ } else if(o.constructor == Date) {
+ return '{javaClass: "java.util.Date", time: ' + o.valueOf() +'}';
+ } else if(o.constructor == Array) {
+ var v = [];
+ for(var i = 0; i < o.length; i++) v.push(toJSON(o[i]));
+ return "[" + v.join(", ") + "]";
+ } else {
+ var v = [];
+ for(attr in o) {
+ if(o[attr] == null) v.push("\"" + attr + "\": null");
+ else if(typeof o[attr] == "function"); /* skip */
+ else v.push(escapeJSONString(attr) + ": " + toJSON(o[attr]));
+ }
+ return "{" + v.join(", ") + "}";
+ }
+};
+
+
+/* JSONRpcClient constructor */
+
+JSONRpcClient =
+function JSONRpcClient_ctor(serverURL, user, pass, objectID)
+{
+ this.serverURL = serverURL;
+ this.user = user;
+ this.pass = pass;
+ this.objectID = objectID;
+
+ /* Add standard methods */
+ if(this.objectID) {
+ this._addMethods(["listMethods"]);
+ var req = this._makeRequest("listMethods", []);
+ } else {
+ this._addMethods(["system.listMethods"]);
+ var req = this._makeRequest("system.listMethods", []);
+ }
+ var m = this._sendRequest(req);
+ this._addMethods(m);
+};
+
+
+/* JSONRpcCLient.Exception */
+
+JSONRpcClient.Exception =
+function JSONRpcClient_Exception_ctor(code, message, javaStack)
+{
+ this.code = code;
+ var name;
+ if(javaStack) {
+ this.javaStack = javaStack;
+ var m = javaStack.match(/^([^:]*)/);
+ if(m) name = m[0];
+ }
+ if(name) this.name = name;
+ else this.name = "JSONRpcClientException";
+ this.message = message;
+};
+
+JSONRpcClient.Exception.CODE_REMOTE_EXCEPTION = 490;
+JSONRpcClient.Exception.CODE_ERR_CLIENT = 550;
+JSONRpcClient.Exception.CODE_ERR_PARSE = 590;
+JSONRpcClient.Exception.CODE_ERR_NOMETHOD = 591;
+JSONRpcClient.Exception.CODE_ERR_UNMARSHALL = 592;
+JSONRpcClient.Exception.CODE_ERR_MARSHALL = 593;
+
+JSONRpcClient.Exception.prototype = new Error();
+
+JSONRpcClient.Exception.prototype.toString =
+function JSONRpcClient_Exception_toString(code, msg)
+{
+ return this.name + ": " + this.message;
+};
+
+
+/* Default top level exception handler */
+
+JSONRpcClient.default_ex_handler =
+function JSONRpcClient_default_ex_handler(e) { alert(e); };
+
+
+/* Client settable variables */
+
+JSONRpcClient.toplevel_ex_handler = JSONRpcClient.default_ex_handler;
+JSONRpcClient.profile_async = false;
+JSONRpcClient.max_req_active = 1;
+JSONRpcClient.requestId = 1;
+
+
+/* JSONRpcClient implementation */
+
+JSONRpcClient.prototype._createMethod =
+function JSONRpcClient_createMethod(methodName)
+{
+ var fn=function()
+ {
+ var args = [];
+ var callback = null;
+ for(var i=0;i<arguments.length;i++) args.push(arguments[i]);
+
+/* TUSCANY change callback to be last arg instead of first to match binding.ajax
+ if(typeof args[0] == "function") callback = args.shift();
+*/
+ if(typeof args[arguments.length-1] == "function") callback = args.pop();
+
+ var req = fn.client._makeRequest.call(fn.client, fn.methodName,
+ args, callback);
+ if(callback == null) {
+ return fn.client._sendRequest.call(fn.client, req);
+ } else {
+ JSONRpcClient.async_requests.push(req);
+ JSONRpcClient.kick_async();
+ return req.requestId;
+ }
+ };
+ fn.client = this;
+ fn.methodName = methodName;
+ return fn;
+};
+
+JSONRpcClient.prototype._addMethods =
+function JSONRpcClient_addMethods(methodNames)
+{
+ for(var i=0; i<methodNames.length; i++) {
+ var obj = this;
+ var names = methodNames[i].split(".");
+ for(var n=0; n<names.length-1; n++) {
+ var name = names[n];
+ if(obj[name]) {
+ obj = obj[name];
+ } else {
+ obj[name] = new Object();
+ obj = obj[name];
+ }
+ }
+ var name = names[names.length-1];
+ if(!obj[name]) {
+ var method = this._createMethod(methodNames[i]);
+ obj[name] = method;
+ }
+ }
+};
+
+JSONRpcClient._getCharsetFromHeaders =
+function JSONRpcClient_getCharsetFromHeaders(http)
+{
+ try {
+ var contentType = http.getResponseHeader("Content-type");
+ var parts = contentType.split(/\s*;\s*/);
+ for(var i =0; i < parts.length; i++) {
+ if(parts[i].substring(0, 8) == "charset=")
+ return parts[i].substring(8, parts[i].length);
+ }
+ } catch (e) {}
+ return "UTF-8"; /* default */
+};
+
+/* Async queue globals */
+JSONRpcClient.async_requests = [];
+JSONRpcClient.async_inflight = {};
+JSONRpcClient.async_responses = [];
+JSONRpcClient.async_timeout = null;
+JSONRpcClient.num_req_active = 0;
+
+JSONRpcClient._async_handler =
+function JSONRpcClient_async_handler()
+{
+ JSONRpcClient.async_timeout = null;
+
+ while(JSONRpcClient.async_responses.length > 0) {
+ var res = JSONRpcClient.async_responses.shift();
+ if(res.canceled) continue;
+ if(res.profile) res.profile.dispatch = new Date();
+ try {
+ res.cb(res.result, res.ex, res.profile);
+ } catch(e) {
+ JSONRpcClient.toplevel_ex_handler(e);
+ }
+ }
+
+ while(JSONRpcClient.async_requests.length > 0 &&
+ JSONRpcClient.num_req_active < JSONRpcClient.max_req_active) {
+ var req = JSONRpcClient.async_requests.shift();
+ if(req.canceled) continue;
+ req.client._sendRequest.call(req.client, req);
+ }
+};
+
+JSONRpcClient.kick_async =
+function JSONRpcClient_kick_async()
+{
+ if(JSONRpcClient.async_timeout == null)
+ JSONRpcClient.async_timeout =
+ setTimeout(JSONRpcClient._async_handler, 0);
+};
+
+JSONRpcClient.cancelRequest =
+function JSONRpcClient_cancelRequest(requestId)
+{
+ /* If it is in flight then mark it as canceled in the inflight map
+ and the XMLHttpRequest callback will discard the reply. */
+ if(JSONRpcClient.async_inflight[requestId]) {
+ JSONRpcClient.async_inflight[requestId].canceled = true;
+ return true;
+ }
+
+ /* If its not in flight yet then we can just mark it as canceled in
+ the the request queue and it will get discarded before being sent. */
+ for(var i in JSONRpcClient.async_requests) {
+ if(JSONRpcClient.async_requests[i].requestId == requestId) {
+ JSONRpcClient.async_requests[i].canceled = true;
+ return true;
+ }
+ }
+
+ /* It may have returned from the network and be waiting for its callback
+ to be dispatched, so mark it as canceled in the response queue
+ and the response will get discarded before calling the callback. */
+ for(var i in JSONRpcClient.async_responses) {
+ if(JSONRpcClient.async_responses[i].requestId == requestId) {
+ JSONRpcClient.async_responses[i].canceled = true;
+ return true;
+ }
+ }
+
+ return false;
+};
+
+JSONRpcClient.prototype._makeRequest =
+function JSONRpcClient_makeRequest(methodName, args, cb)
+{
+ var req = {};
+ req.client = this;
+ req.requestId = JSONRpcClient.requestId++;
+
+ var obj = {};
+ obj.id = req.requestId;
+ if (this.objectID)
+ obj.method = ".obj#" + this.objectID + "." + methodName;
+ else
+ obj.method = methodName;
+ obj.params = args;
+
+ if (cb) req.cb = cb;
+ if (JSONRpcClient.profile_async)
+ req.profile = { "submit": new Date() };
+ req.data = toJSON(obj);
+
+ return req;
+};
+
+JSONRpcClient.prototype._sendRequest =
+function JSONRpcClient_sendRequest(req)
+{
+ if(req.profile) req.profile.start = new Date();
+
+ /* Get free http object from the pool */
+ var http = JSONRpcClient.poolGetHTTPRequest();
+ JSONRpcClient.num_req_active++;
+
+ /* Send the request */
+ if (typeof(this.user) == "undefined") {
+ http.open("POST", this.serverURL, (req.cb != null));
+ } else {
+ http.open("POST", this.serverURL, (req.cb != null), this.user, this.pass);
+ }
+
+ /* setRequestHeader is missing in Opera 8 Beta */
+ try { http.setRequestHeader("Content-type", "text/plain"); } catch(e) {}
+
+ /* Construct call back if we have one */
+ if(req.cb) {
+ var self = this;
+ http.onreadystatechange = function() {
+ if(http.readyState == 4) {
+ http.onreadystatechange = function () {};
+ var res = { "cb": req.cb, "result": null, "ex": null};
+ if (req.profile) {
+ res.profile = req.profile;
+ res.profile.end = new Date();
+ }
+ try { res.result = self._handleResponse(http); }
+ catch(e) { res.ex = e; }
+ if(!JSONRpcClient.async_inflight[req.requestId].canceled)
+ JSONRpcClient.async_responses.push(res);
+ delete JSONRpcClient.async_inflight[req.requestId];
+ JSONRpcClient.kick_async();
+ }
+ };
+ } else {
+ http.onreadystatechange = function() {};
+ }
+
+ JSONRpcClient.async_inflight[req.requestId] = req;
+
+ try {
+ http.send(req.data);
+ } catch(e) {
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+ throw new JSONRpcClient.Exception
+ (JSONRpcClient.Exception.CODE_ERR_CLIENT, "Connection failed");
+ }
+
+ if(!req.cb) return this._handleResponse(http);
+};
+
+JSONRpcClient.prototype._handleResponse =
+function JSONRpcClient_handleResponse(http)
+{
+ /* Get the charset */
+ if(!this.charset) {
+ this.charset = JSONRpcClient._getCharsetFromHeaders(http);
+ }
+
+ /* Get request results */
+ var status, statusText, data;
+ try {
+ status = http.status;
+ statusText = http.statusText;
+ data = http.responseText;
+ } catch(e) {
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+ JSONRpcClient.kick_async();
+ throw new JSONRpcClient.Exception
+ (JSONRpcClient.Exception.CODE_ERR_CLIENT, "Connection failed");
+ }
+
+ /* Return http object to the pool; */
+ JSONRpcClient.poolReturnHTTPRequest(http);
+ JSONRpcClient.num_req_active--;
+
+ /* Unmarshall the response */
+ if(status != 200) {
+ throw new JSONRpcClient.Exception(status, statusText);
+ }
+ var obj;
+ try {
+ eval("obj = " + data);
+ } catch(e) {
+ throw new JSONRpcClient.Exception(550, "error parsing result");
+ }
+ if(obj.error)
+ throw new JSONRpcClient.Exception(obj.error.code, obj.error.msg,
+ obj.error.trace);
+ var res = obj.result;
+
+ /* Handle CallableProxy */
+ if(res && res.objectID && res.JSONRPCType == "CallableReference")
+ return new JSONRpcClient(this.serverURL, this.user,
+ this.pass, res.objectID);
+
+ return res;
+};
+
+
+/* XMLHttpRequest wrapper code */
+
+/* XMLHttpRequest pool globals */
+JSONRpcClient.http_spare = [];
+JSONRpcClient.http_max_spare = 8;
+
+JSONRpcClient.poolGetHTTPRequest =
+function JSONRpcClient_pool_getHTTPRequest()
+{
+ if(JSONRpcClient.http_spare.length > 0) {
+ return JSONRpcClient.http_spare.pop();
+ }
+ return JSONRpcClient.getHTTPRequest();
+};
+
+JSONRpcClient.poolReturnHTTPRequest =
+function JSONRpcClient_poolReturnHTTPRequest(http)
+{
+ if(JSONRpcClient.http_spare.length >= JSONRpcClient.http_max_spare)
+ delete http;
+ else
+ JSONRpcClient.http_spare.push(http);
+};
+
+JSONRpcClient.msxmlNames = [ "MSXML2.XMLHTTP.5.0",
+ "MSXML2.XMLHTTP.4.0",
+ "MSXML2.XMLHTTP.3.0",
+ "MSXML2.XMLHTTP",
+ "Microsoft.XMLHTTP" ];
+
+JSONRpcClient.getHTTPRequest =
+function JSONRpcClient_getHTTPRequest()
+{
+ /* Mozilla XMLHttpRequest */
+ try {
+ JSONRpcClient.httpObjectName = "XMLHttpRequest";
+ return new XMLHttpRequest();
+ } catch(e) {}
+
+ /* Microsoft MSXML ActiveX */
+ for (var i=0;i < JSONRpcClient.msxmlNames.length; i++) {
+ try {
+ JSONRpcClient.httpObjectName = JSONRpcClient.msxmlNames[i];
+ return new ActiveXObject(JSONRpcClient.msxmlNames[i]);
+ } catch (e) {}
+ }
+
+ /* None found */
+ JSONRpcClient.httpObjectName = null;
+ throw new JSONRpcClient.Exception(0, "Can't create XMLHttpRequest object");
+};
+
+
+/*
+ * 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.
+ */
+
+function AtomClient(uri) {
+
+ this.msxmlNames = [ "MSXML2.XMLHTTP.5.0",
+ "MSXML2.XMLHTTP.4.0",
+ "MSXML2.XMLHTTP.3.0",
+ "MSXML2.XMLHTTP",
+ "Microsoft.XMLHTTP" ];
+
+ this.uri=uri;
+
+ this.get = function(id, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("get - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("GET", uri + '/' + id, true);
+ xhr.send(null);
+ }
+
+ this.post = function (entry, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 201) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("post - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("POST", uri, true);
+ xhr.setRequestHeader("Content-Type", "application/atom+xml");
+ xhr.send(entry);
+ }
+
+ this.put = function (id, entry, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ var strDocument = xhr.responseText;
+ var xmlDocument = xhr.responseXML;
+ if(!xmlDocument || xmlDocument.childNodes.length==0){
+ xmlDocument = (new DOMParser()).parseFromString(strDocument, "text/xml");
+ }
+ if (responseFunction != null) responseFunction(xmlDocument);
+ } else {
+ alert("put - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("PUT", uri + '/' + id, true);
+ xhr.setRequestHeader("Content-Type", "application/atom+xml");
+ xhr.send(entry);
+ }
+
+ this.del = function (id, responseFunction) {
+ var xhr = this.createXMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ if (responseFunction != null) responseFunction();
+ } else {
+ alert("delete - Error getting data from the server");
+ }
+ }
+ }
+ xhr.open("DELETE", uri + '/' + id, true);
+ xhr.send(null);
+ }
+ this.createXMLHttpRequest = function () {
+ /* Mozilla XMLHttpRequest */
+ try {return new XMLHttpRequest();} catch(e) {}
+
+ /* Microsoft MSXML ActiveX */
+ for (var i=0;i < this.msxmlNames.length; i++) {
+ try {return new ActiveXObject(this.msxmlNames[i]);} catch (e) {}
+ }
+ alert("XML http request not supported");
+ return null;
+ }
+ if (typeof DOMParser == "undefined") {
+ DOMParser = function () {}
+
+ DOMParser.prototype.parseFromString = function (str, contentType) {
+ if (typeof ActiveXObject != "undefined") {
+ var d = new ActiveXObject("MSXML.DomDocument");
+ d.loadXML(str);
+ return d;
+ } else if (typeof XMLHttpRequest != "undefined") {
+ var req = new XMLHttpRequest;
+ req.open("GET", "data:" + (contentType || "application/xml") +
+ ";charset=utf-8," + encodeURIComponent(str), false);
+ if (req.overrideMimeType) {
+ req.overrideMimeType(contentType);
+ }
+ req.send(null);
+ return req.responseXML;
+ }
+ }
+ }
+}
+
+
+
+/* Tuscany Reference/Property injection code */
+
+if (!tuscany) {
+var tuscany = {};
+}
+if (!tuscany.sca) {
+tuscany.sca = {};
+}
+
+tuscany.sca.propertyMap = new String();
+tuscany.sca.Property = function (name) {
+ return tuscany.sca.propertyMap[name];
+}
+
+tuscany.sca.referenceMap = new Object();
+tuscany.sca.referenceMap.catalog = new JSONRpcClient("/catalog").Service;
+tuscany.sca.referenceMap.shoppingCart = new AtomClient("/shoppingCart");
+tuscany.sca.referenceMap.shoppingTotal = new JSONRpcClient("/total").Service;
+tuscany.sca.Reference = function (name) {
+ return tuscany.sca.referenceMap[name];
+}
+
+/** End of Apache Tuscany SCA Widget */
+
diff --git a/sca-cpp/branches/gcc-4.4/test/store-sql/server-test b/sca-cpp/branches/gcc-4.4/test/store-sql/server-test
new file mode 100755
index 0000000000..d2013f6892
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-sql/server-test
@@ -0,0 +1,40 @@
+#!/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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/store.html 2>/dev/null >tmp/store.html
+diff tmp/store.html htdocs/store.html
+rc=$?
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sca-cpp/branches/gcc-4.4/test/store-sql/shopping-cart.scm b/sca-cpp/branches/gcc-4.4/test/store-sql/shopping-cart.scm
new file mode 100644
index 0000000000..484044d420
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-sql/shopping-cart.scm
@@ -0,0 +1,84 @@
+; 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.
+
+; Shopping cart implementation
+
+(define cartId "1234")
+
+; Get the shopping cart from the cache
+; Return an empty cart if not found
+(define (getcart id cache)
+ (define cart (cache "get" (list id)))
+ (if (nul cart)
+ (list)
+ cart)
+)
+
+; Post a new item to the cart, create a new cart if necessary
+(define (post collection item cache)
+ (define id (uuid))
+ (define newItem (list (car item) id (caddr item)))
+ (define cart (cons newItem (getcart cartId cache)))
+ (cache "put" (list cartId) cart)
+ (list id)
+)
+
+; Find an item in the cart
+(define (find id cart)
+ (if (nul cart)
+ (cons "Item" (list "0" (list)))
+ (if (= id (cadr (car cart)))
+ (car cart)
+ (find id (cdr cart))))
+)
+
+; Get items from the cart
+(define (get id cache)
+ (if (nul id)
+ (cons "Your Cart" (cons cartId (getcart cartId cache)))
+ (find (car id) (getcart cartId cache))
+ )
+)
+
+; Delete items from the cart
+(define (delete id cache)
+ (if (nul id)
+ (cache "delete" (list cartId))
+ true
+ )
+)
+
+; Return the price of an item
+(define (price item)
+ (cadr (assoc 'price (caddr item)))
+)
+
+; Sum the prices of a list of items
+(define (sum items)
+ (if (nul items)
+ 0
+ (+ (price (car items)) (sum (cdr items))))
+)
+
+; Return the total price of the items in the cart
+(define (gettotal cache)
+ (define cart (getcart cartId cache))
+ (sum cart)
+)
+
+; TODO remove these JSON-RPC specific functions
+(define (listMethods cache) (list "Service.gettotal"))
diff --git a/sca-cpp/branches/gcc-4.4/test/store-sql/ssl-start b/sca-cpp/branches/gcc-4.4/test/store-sql/ssl-start
new file mode 100755
index 0000000000..8e27d31a2e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-sql/ssl-start
@@ -0,0 +1,35 @@
+#!/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-ca-conf tmp localhost
+../../modules/http/httpd-cert-conf tmp localhost
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/http/httpd-ssl-conf tmp localhost 8453 htdocs
+../../modules/server/server-conf tmp
+../../modules/server/scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/sqldb/pgsql-start tmp
+../../components/sqldb/pgsql "create table store(key text, value text);" 1>/dev/null 2>&1
+../../modules/http/httpd-start tmp
diff --git a/sca-cpp/branches/gcc-4.4/test/store-sql/start b/sca-cpp/branches/gcc-4.4/test/store-sql/start
new file mode 100755
index 0000000000..60f5a2d702
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-sql/start
@@ -0,0 +1,32 @@
+#!/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-conf tmp localhost 8090 htdocs
+../../modules/server/server-conf tmp
+../../modules/server/scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/sqldb/pgsql-start tmp
+../../components/sqldb/pgsql "create table store(key text, value text);" 1>/dev/null 2>&1
+../../modules/http/httpd-start tmp
diff --git a/sca-cpp/branches/gcc-4.4/test/store-sql/stop b/sca-cpp/branches/gcc-4.4/test/store-sql/stop
new file mode 100755
index 0000000000..603165ef46
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-sql/stop
@@ -0,0 +1,21 @@
+#!/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
+../../components/sqldb/pgsql-stop tmp
diff --git a/sca-cpp/branches/gcc-4.4/test/store-sql/store.composite b/sca-cpp/branches/gcc-4.4/test/store-sql/store.composite
new file mode 100644
index 0000000000..58c2741a5e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-sql/store.composite
@@ -0,0 +1,71 @@
+<?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"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.scheme script="store.scm"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.scheme script="fruits-catalog.scm"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.scheme script="shopping-cart.scm"/>
+ <service name="ShoppingCart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Sqldb"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.scheme script="currency-converter.scm"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+ <component name="Sqldb">
+ <implementation.cpp path="../../components/sqldb/.libs" library="libsqldb"/>
+ <property name="conninfo">dbname=db</property>
+ <property name="table">store</property>
+ <service name="Sqldb">
+ <t:binding.atom uri="sqldb"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sca-cpp/branches/gcc-4.4/test/store-sql/store.scm b/sca-cpp/branches/gcc-4.4/test/store-sql/store.scm
new file mode 100644
index 0000000000..d851dc7ed6
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/test/store-sql/store.scm
@@ -0,0 +1,50 @@
+; 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.
+
+; Store implementation
+
+(define (post item catalog shoppingCart shoppingTotal)
+ (shoppingCart "post" item)
+)
+
+(define (getall catalog shoppingCart shoppingTotal)
+ (shoppingCart "getall")
+)
+
+(define (get id catalog shoppingCart shoppingTotal)
+ (shoppingCart "get" id)
+)
+
+(define (getcatalog catalog shoppingCart shoppingTotal)
+ (catalog "get")
+)
+
+(define (gettotal catalog shoppingCart shoppingTotal)
+ (shoppingCart "gettotal")
+)
+
+(define (deleteall catalog shoppingCart shoppingTotal)
+ (shoppingCart "deleteall")
+)
+
+(define (delete id catalog shoppingCart shoppingTotal)
+ (shoppingCart "delete" id)
+)
+
+; TODO remove these JSON-RPC specific functions
+(define (listMethods catalog shoppingCart shoppingTotal) (list "Service.getcatalog" "Service.gettotal"))
+
diff --git a/sca-cpp/branches/gcc-4.4/ubuntu/ubuntu-bin-image b/sca-cpp/branches/gcc-4.4/ubuntu/ubuntu-bin-image
new file mode 100755
index 0000000000..9bca168920
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/ubuntu/ubuntu-bin-image
@@ -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.
+
+# Install the required system tools and libraries, the runtime dependencies and
+# the Tuscany SCA runtime on a fresh Ubuntu Server 9.10 image.
+
+# Display commands as they are executed
+set -x
+
+# First update the system
+sudo apt-get update
+
+# Create install directory
+sudo mkdir -p /mnt/tuscany
+sudo chown ubuntu /mnt/tuscany
+sudo chgrp ubuntu /mnt/tuscany
+cd /mnt/tuscany
+
+# Install system tools and libraries
+sudo apt-get -y install wget git-core autoconf automake g++ libtool
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+sudo apt-get -y install libssl-dev
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+sudo apt-get -y install libevent-dev
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+sudo apt-get -y install pkg-config
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+sudo apt-get -y install libboost-dev libboost-program-options-dev libboost-filesystem-dev uuid-dev
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+sudo apt-get -y install check
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+sudo apt-get -y install openjdk-6-jdk
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+
+# Download and install the runtime
+wget http://people.apache.org/~jsdelfino/tuscany/test/tuscany-sca-cpp-1.0.0-SNAPSHOT.tar.gz
+tar xzf tuscany-sca-cpp-1.0.0-SNAPSHOT.tar.gz
+
diff --git a/sca-cpp/branches/gcc-4.4/ubuntu/ubuntu-dev-image b/sca-cpp/branches/gcc-4.4/ubuntu/ubuntu-dev-image
new file mode 100755
index 0000000000..a2b45ece3b
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/ubuntu/ubuntu-dev-image
@@ -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.
+
+# Install the required system tools and libraries, the runtime dependencies and
+# the Tuscany SCA runtime on a fresh Ubuntu Server 9.10 image.
+
+# Display commands as they are executed
+set -x
+
+# First update the system
+sudo apt-get update
+
+# Create install directory
+sudo mkdir -p /mnt/tuscany
+sudo chown ubuntu /mnt/tuscany
+sudo chgrp ubuntu /mnt/tuscany
+cd /mnt/tuscany
+
+# Download and run install script
+sudo apt-get -y install wget
+wget http://svn.apache.org/repos/asf/tuscany/sca-cpp/trunk/ubuntu/ubuntu-install
+chmod +x ./ubuntu-install
+./ubuntu-install
+
diff --git a/sca-cpp/branches/gcc-4.4/ubuntu/ubuntu-gcc-4.5 b/sca-cpp/branches/gcc-4.4/ubuntu/ubuntu-gcc-4.5
new file mode 100755
index 0000000000..e65ecbfae4
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/ubuntu/ubuntu-gcc-4.5
@@ -0,0 +1,52 @@
+# 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.
+
+# Install GCC 4.5
+
+# Display commands as they are executed
+set -x
+
+# First update the system
+sudo apt-get update
+
+# Create install directory
+sudo mkdir -p /mnt/tuscany
+sudo chown ubuntu /mnt/tuscany
+sudo chgrp ubuntu /mnt/tuscany
+cd /mnt/tuscany
+
+# Install GCC 4.5 binaries
+mkdir -p gcc-4.5
+cd gcc-4.5
+wget http://ftp.debian.org/debian/pool/main/g/gcc-4.5/cpp-4.5_4.5.0-1_i386.deb
+wget http://ftp.debian.org/debian/pool/main/g/gcc-4.5/fixincludes_4.5.0-1_i386.deb
+wget http://ftp.debian.org/debian/pool/main/g/gcc-4.5/g++-4.5_4.5.0-1_i386.deb
+wget http://ftp.debian.org/debian/pool/main/g/gcc-4.5/gcc-4.5_4.5.0-1_i386.deb
+wget http://ftp.debian.org/debian/pool/main/g/gcc-4.5/gcc-4.5-base_4.5.0-1_i386.deb
+wget http://ftp.debian.org/debian/pool/main/g/gcc-4.5/lib64gcc1_4.5.0-1_i386.deb
+wget http://ftp.debian.org/debian/pool/main/g/gcc-4.5/lib64gomp1_4.5.0-1_i386.deb
+wget http://ftp.debian.org/debian/pool/main/g/gcc-4.5/lib64mudflap0_4.5.0-1_i386.deb
+wget http://ftp.debian.org/debian/pool/main/g/gcc-4.5/lib64stdc++6_4.5.0-1_i386.deb
+wget http://ftp.debian.org/debian/pool/main/g/gcc-4.5/libgcc1_4.5.0-1_i386.deb
+wget http://ftp.debian.org/debian/pool/main/g/gcc-4.5/libgomp1_4.5.0-1_i386.deb
+wget http://ftp.debian.org/debian/pool/main/g/gcc-4.5/libmudflap0-4.5-dev_4.5.0-1_i386.deb
+wget http://ftp.debian.org/debian/pool/main/g/gcc-4.5/libmudflap0_4.5.0-1_i386.deb
+wget http://ftp.debian.org/debian/pool/main/g/gcc-4.5/libstdc++6_4.5.0-1_i386.deb
+wget http://ftp.debian.org/debian/pool/main/g/gcc-4.5/libstdc++6-4.5-dev_4.5.0-1_i386.deb
+
+sudo dpkg -i cpp-4.5_4.5.0-1_i386.deb fixincludes_4.5.0-1_i386.deb g++-4.5_4.5.0-1_i386.deb gcc-4.5_4.5.0-1_i386.deb gcc-4.5-base_4.5.0-1_i386.deb lib64gcc1_4.5.0-1_i386.deb lib64gomp1_4.5.0-1_i386.deb lib64mudflap0_4.5.0-1_i386.deb lib64stdc++6_4.5.0-1_i386.deb libgcc1_4.5.0-1_i386.deb libgomp1_4.5.0-1_i386.deb libmudflap0-4.5-dev_4.5.0-1_i386.deb libmudflap0_4.5.0-1_i386.deb libstdc++6_4.5.0-1_i386.deb libstdc++6-4.5-dev_4.5.0-1_i386.deb
+
diff --git a/sca-cpp/branches/gcc-4.4/ubuntu/ubuntu-install b/sca-cpp/branches/gcc-4.4/ubuntu/ubuntu-install
new file mode 100755
index 0000000000..4c80c47a5f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/ubuntu/ubuntu-install
@@ -0,0 +1,228 @@
+# 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.
+
+# Install the required system tools and libraries, the runtime dependencies and
+# the Tuscany SCA runtime on a fresh Ubuntu Server 9.10 system.
+
+# Display commands as they are executed
+set -x
+
+# Build and install in the current directory
+build=`pwd`
+
+# Install core dev tools
+sudo apt-get -y install wget git-core autoconf automake g++ libtool
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+
+# Build Apache HTTP server
+sudo apt-get -y install libssl-dev
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+wget http://www.apache.org/dist/httpd/httpd-2.2.15.tar.gz
+tar xzf httpd-2.2.15.tar.gz
+cd httpd-2.2.15
+./configure --enable-ssl --enable-proxy --enable-rewrite --with-included-apr --with-mpm=prefork --prefix=$build/httpd-2.2.15-bin
+make
+make install
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+cd $build
+
+# Build Memcached
+sudo apt-get install libevent-dev
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+wget http://memcached.googlecode.com/files/memcached-1.4.4.tar.gz
+tar xzf memcached-1.4.4.tar.gz
+cd memcached-1.4.4
+./configure --prefix=$build/memcached-1.4.4-bin
+make
+make install
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+cd $build
+
+# Build Tinycdb
+wget http://www.corpit.ru/mjt/tinycdb/tinycdb_0.77.tar.gz
+tar xzf tinycdb_0.77.tar.gz
+cd tinycdb-0.77
+make
+make prefix=$build/tinycdb-0.77-bin install
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+cd $build
+
+# Build Libcurl
+wget http://curl.haxx.se/download/curl-7.19.5.tar.gz
+tar xzf curl-7.19.5.tar.gz
+cd curl-7.19.5
+./configure --prefix=$build/curl-7.19.5-bin
+make
+make install
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+cd $build
+
+# Build Libxml2
+wget ftp://xmlsoft.org/libxml2/libxml2-sources-2.7.7.tar.gz
+tar xzf libxml2-sources-2.7.7.tar.gz
+cd libxml2-2.7.7
+./configure --prefix=$build/libxml2-2.7.7-bin
+make
+make install
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+cd $build
+
+# Build TraceMonkey
+sudo apt-get -y install autoconf2.13
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+wget -O tracemonkey-e4364736e170.tar.gz http://hg.mozilla.org/tracemonkey/archive/e4364736e170.tar.gz
+tar xzf tracemonkey-e4364736e170.tar.gz
+cd tracemonkey-e4364736e170/js/src
+autoconf2.13
+./configure --prefix=$build/tracemonkey-bin
+make
+make install
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+cd $build
+
+# Install Google AppEngine SDK
+wget http://googleappengine.googlecode.com/files/google_appengine_1.3.2.zip
+unzip google_appengine_1.3.2.zip
+
+# Build Apache Axis2/C
+sudo apt-get -y install pkg-config
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+wget http://www.apache.org/dist/ws/axis2-c/1_6_0/axis2c-src-1.6.0.tar.gz
+tar xzf axis2c-src-1.6.0.tar.gz
+cd axis2c-src-1.6.0
+./configure --enable-libxml2 --enable-openssl --with-apache2=$build/httpd-2.2.15-bin/include --prefix=$build/axis2c-1.6.0-bin
+make
+make install
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+export AXIS2C_HOME=$build/axis2c-1.6.0-bin
+cd samples
+./configure --prefix=$build/axis2c-1.6.0-bin --with-axis2=$build/axis2c-1.6.0-bin/include/axis2-1.6.0
+make
+make install
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+cd $build
+
+# Build Apache Qpid/C++
+sudo apt-get -y install libboost-dev libboost-program-options-dev libboost-filesystem-dev uuid-dev
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+sudo -s ln -s /usr/lib/libboost_program_options-mt.so /usr/lib/libboost_program_options.so
+sudo -s ln -s /usr/lib/libboost_filesystem-mt.so /usr/lib/libboost_filesystem.so
+wget http://www.apache.org/dist/qpid/0.6/qpid-cpp-0.6.tar.gz
+tar xzf qpid-cpp-0.6.tar.gz
+cd qpidc-0.6
+./configure --prefix=$build/qpidc-0.6-bin
+make
+make install
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+cd $build
+
+# Build Libstrophe
+sudo apt-get -y install check
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+git clone git://code.stanziq.com/libstrophe
+cd libstrophe
+git submodule init
+git submodule update
+aclocal
+automake --add-missing --foreign --copy
+autoconf
+./configure --prefix=$build/libstrophe-bin
+make
+make install
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+cd $build
+mkdir -p $build/libstrophe-bin/include
+cp $build/libstrophe/*.h $build/libstrophe-bin/include
+cp $build/libstrophe/src/*.h $build/libstrophe-bin/include
+
+# Install Apache Vysper
+sudo apt-get -y install openjdk-6-jdk
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+wget http://www.apache.org/dist/mina/vysper/0.5/vysper-0.5-bin.tar.gz
+tar xzf vysper-0.5-bin.tar.gz
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+
+# Build PostgreSQL
+sudo apt-get -y install libreadline-dev
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+wget http://wwwmaster.postgresql.org/redir/198/f/source/9.0alpha4/postgresql-9.0alpha4.tar.gz
+tar xzf postgresql-9.0alpha4.tar.gz
+cd postgresql-9.0alpha4
+./configure --prefix=$build/postgresql-9.0-bin
+make
+make install
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+cd $build
+
+# Build Tuscany SCA
+git clone git://git.apache.org/tuscany-sca-cpp
+cd tuscany-sca-cpp
+cp etc/git-exclude .git/info/exclude
+./bootstrap
+./configure --prefix=$build/tuscany-sca-cpp-bin --with-curl=$build/curl-7.19.5-bin --with-apr=$build/httpd-2.2.15-bin --with-httpd=$build/httpd-2.2.15-bin --with-memcached=$build/memcached-1.4.4-bin --with-tinycdb=$build/tinycdb-0.77-bin --with-js-include=$build/tracemonkey-bin/include/js --with-js-lib=$build/tracemonkey-bin/lib --enable-threads --enable-python --enable-gae --with-gae=$build/google_appengine --enable-java --with-java=/usr/lib/jvm/java-6-openjdk --enable-webservice --with-libxml2=$build/libxml2-2.7.7-bin --with-axis2c=$build/axis2c-1.6.0-bin --enable-queue --with-qpidc=$build/qpidc-0.6-bin --enable-chat --with-libstrophe=$build/libstrophe-bin --with-vysper=$build/vysper-0.5 --enable-sqldb --with-pgsql=$build/postgresql-9.0-bin
+make
+make install
+if [ "$?" != "0" ]; then
+ exit $?
+fi
+cd $build
+
+# Create bin archive
+tar czf tuscany-sca-cpp-1.0.0-SNAPSHOT.tar.gz tuscany-sca-cpp tuscany-sca-cpp-bin axis2c-1.6.0-bin libxml2-2.7.7-bin curl-7.19.5-bin httpd-2.2.15-bin tracemonkey-bin google_appengine libstrophe-bin memcached-1.4.4-bin tinycdb-0.77-bin qpidc-0.6-bin vysper-0.5 postgresql-9.0-bin
+
diff --git a/sca-cpp/branches/gcc-4.4/ubuntu/uec2-bin-image b/sca-cpp/branches/gcc-4.4/ubuntu/uec2-bin-image
new file mode 100755
index 0000000000..f4d738a050
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/ubuntu/uec2-bin-image
@@ -0,0 +1,23 @@
+# 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.
+
+# Install a Tuscany image on an EC2 instance
+host=$1
+
+# Download and execute Tuscany SCA install script
+ssh -i $HOME/.ec2/ec2-tuscany-keypair.pem ubuntu@$host "wget http://svn.apache.org/repos/asf/tuscany/sca-cpp/trunk/ubuntu/ubuntu-bin-image; chmod 700 ./ubuntu-bin-image; ./ubuntu-bin-image"
+
diff --git a/sca-cpp/branches/gcc-4.4/ubuntu/uec2-conf b/sca-cpp/branches/gcc-4.4/ubuntu/uec2-conf
new file mode 100755
index 0000000000..34ec6f5d49
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/ubuntu/uec2-conf
@@ -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.
+
+# Configure EC2 for use with Tuscany SCA
+here=`readlink -f $0`; here=`dirname $here`
+$here/uec2-setenv
+
+# Display commands as they are executed
+set -x
+
+# Install EC2 tools
+# See https://help.ubuntu.com/community/EC2StartersGuide for more info
+sudo apt-get install ec2-api-tools
+
+# Create an EC2 SSH keypair if necessary
+if [ ! -f $HOME/.ec2/ec2-tuscany-keypair.pem ]; then
+ ec2-add-keypair ec2-tuscany-keypair --region us-west-1 > $HOME/.ec2/ec2-tuscany-keypair.pem
+ chmod 600 $HOME/.ec2/ec2-tuscany-keypair.pem
+fi
+
+# Authorize SSH, HTTP and HTTPS access to EC2 instances
+ec2-authorize default -p 22 --region us-west-1
+ec2-authorize default -p 80 --region us-west-1
+ec2-authorize default -p 443 --region us-west-1
+
diff --git a/sca-cpp/branches/gcc-4.4/ubuntu/uec2-setenv b/sca-cpp/branches/gcc-4.4/ubuntu/uec2-setenv
new file mode 100755
index 0000000000..67d57df83a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/ubuntu/uec2-setenv
@@ -0,0 +1,34 @@
+# 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.
+
+# Configure EC2 environment variables
+export JAVA_HOME=/usr/lib/jvm/java-6-openjdk
+
+# Expect to find your EC2 private key and X.509 certificate in $HOME/.ec2
+key=`ls $HOME/.ec2/pk-*.pem`
+if [ "$key" = "" ]; then
+ echo "Couldn't find EC2 private key $HOME/.ec2/pk-*.pem"
+ exit 1
+fi
+cert=`ls $HOME/.ec2/cert-*.pem`
+if [ "$cert" = "" ]; then
+ echo "Couldn't find EC2 X.509 certificate $HOME/.ec2/pk-*.pem"
+ exit 1
+fi
+export EC2_PRIVATE_KEY=$key
+export EC2_CERT=$cert
+
diff --git a/sca-cpp/branches/gcc-4.4/ubuntu/uec2-start b/sca-cpp/branches/gcc-4.4/ubuntu/uec2-start
new file mode 100755
index 0000000000..86c47a3c36
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/ubuntu/uec2-start
@@ -0,0 +1,29 @@
+# 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.
+
+# Start an Ubuntu 9.10 EC2 instance for use with Tuscany
+
+here=`readlink -f $0`; here=`dirname $here`
+$here/uec2-setenv
+
+# Here are the AMIs you can use in the different EC2 regions:
+# US east 1 - ami-bb709dd2
+# US west 1 - ami-c32e7f86
+# EU west 1 - ami-2fc2e95b
+
+ec2-run-instances "ami-c32e7f86" -k ec2-tuscany-keypair --region us-west-1
+
diff --git a/sca-cpp/branches/gcc-4.4/ubuntu/uec2-status b/sca-cpp/branches/gcc-4.4/ubuntu/uec2-status
new file mode 100755
index 0000000000..46d426b6f1
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/ubuntu/uec2-status
@@ -0,0 +1,23 @@
+# 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.
+
+# Display the status of EC2 instances
+here=`readlink -f $0`; here=`dirname $here`
+$here/uec2-setenv
+
+ec2-describe-instances --region us-west-1
+
diff --git a/sca-cpp/branches/gcc-4.4/ubuntu/uec2-stop b/sca-cpp/branches/gcc-4.4/ubuntu/uec2-stop
new file mode 100755
index 0000000000..0399f2b3f2
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/ubuntu/uec2-stop
@@ -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.
+
+# Terminate an EC2 instance
+instance=$1
+here=`readlink -f $0`; here=`dirname $here`
+$here/uec2-setenv
+
+ec2-terminate-instances $instance --region us-west-1
+
diff --git a/sca-cpp/branches/gcc-4.4/xsd/external/XMLSchema.dtd b/sca-cpp/branches/gcc-4.4/xsd/external/XMLSchema.dtd
new file mode 100644
index 0000000000..e8e8f7625a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/external/XMLSchema.dtd
@@ -0,0 +1,402 @@
+<!-- DTD for XML Schemas: Part 1: Structures
+ Public Identifier: "-//W3C//DTD XMLSCHEMA 200102//EN"
+ Official Location: http://www.w3.org/2001/XMLSchema.dtd -->
+<!-- $Id: XMLSchema.dtd,v 1.31 2001/10/24 15:50:16 ht Exp $ -->
+<!-- Note this DTD is NOT normative, or even definitive. --> <!--d-->
+<!-- prose copy in the structures REC is the definitive version --> <!--d-->
+<!-- (which shouldn't differ from this one except for this --> <!--d-->
+<!-- comment and entity expansions, but just in case) --> <!--d-->
+<!-- With the exception of cases with multiple namespace
+ prefixes for the XML Schema namespace, any XML document which is
+ not valid per this DTD given redefinitions in its internal subset of the
+ 'p' and 's' parameter entities below appropriate to its namespace
+ declaration of the XML Schema namespace is almost certainly not
+ a valid schema. -->
+
+<!-- The simpleType element and its constituent parts
+ are defined in XML Schema: Part 2: Datatypes -->
+<!ENTITY % xs-datatypes PUBLIC 'datatypes' 'datatypes.dtd' >
+
+<!ENTITY % p 'xs:'> <!-- can be overriden in the internal subset of a
+ schema document to establish a different
+ namespace prefix -->
+<!ENTITY % s ':xs'> <!-- if %p is defined (e.g. as foo:) then you must
+ also define %s as the suffix for the appropriate
+ namespace declaration (e.g. :foo) -->
+<!ENTITY % nds 'xmlns%s;'>
+
+<!-- Define all the element names, with optional prefix -->
+<!ENTITY % schema "%p;schema">
+<!ENTITY % complexType "%p;complexType">
+<!ENTITY % complexContent "%p;complexContent">
+<!ENTITY % simpleContent "%p;simpleContent">
+<!ENTITY % extension "%p;extension">
+<!ENTITY % element "%p;element">
+<!ENTITY % unique "%p;unique">
+<!ENTITY % key "%p;key">
+<!ENTITY % keyref "%p;keyref">
+<!ENTITY % selector "%p;selector">
+<!ENTITY % field "%p;field">
+<!ENTITY % group "%p;group">
+<!ENTITY % all "%p;all">
+<!ENTITY % choice "%p;choice">
+<!ENTITY % sequence "%p;sequence">
+<!ENTITY % any "%p;any">
+<!ENTITY % anyAttribute "%p;anyAttribute">
+<!ENTITY % attribute "%p;attribute">
+<!ENTITY % attributeGroup "%p;attributeGroup">
+<!ENTITY % include "%p;include">
+<!ENTITY % import "%p;import">
+<!ENTITY % redefine "%p;redefine">
+<!ENTITY % notation "%p;notation">
+
+<!-- annotation elements -->
+<!ENTITY % annotation "%p;annotation">
+<!ENTITY % appinfo "%p;appinfo">
+<!ENTITY % documentation "%p;documentation">
+
+<!-- Customisation entities for the ATTLIST of each element type.
+ Define one of these if your schema takes advantage of the
+ anyAttribute='##other' in the schema for schemas -->
+
+<!ENTITY % schemaAttrs ''>
+<!ENTITY % complexTypeAttrs ''>
+<!ENTITY % complexContentAttrs ''>
+<!ENTITY % simpleContentAttrs ''>
+<!ENTITY % extensionAttrs ''>
+<!ENTITY % elementAttrs ''>
+<!ENTITY % groupAttrs ''>
+<!ENTITY % allAttrs ''>
+<!ENTITY % choiceAttrs ''>
+<!ENTITY % sequenceAttrs ''>
+<!ENTITY % anyAttrs ''>
+<!ENTITY % anyAttributeAttrs ''>
+<!ENTITY % attributeAttrs ''>
+<!ENTITY % attributeGroupAttrs ''>
+<!ENTITY % uniqueAttrs ''>
+<!ENTITY % keyAttrs ''>
+<!ENTITY % keyrefAttrs ''>
+<!ENTITY % selectorAttrs ''>
+<!ENTITY % fieldAttrs ''>
+<!ENTITY % includeAttrs ''>
+<!ENTITY % importAttrs ''>
+<!ENTITY % redefineAttrs ''>
+<!ENTITY % notationAttrs ''>
+<!ENTITY % annotationAttrs ''>
+<!ENTITY % appinfoAttrs ''>
+<!ENTITY % documentationAttrs ''>
+
+<!ENTITY % complexDerivationSet "CDATA">
+ <!-- #all or space-separated list drawn from derivationChoice -->
+<!ENTITY % blockSet "CDATA">
+ <!-- #all or space-separated list drawn from
+ derivationChoice + 'substitution' -->
+
+<!ENTITY % mgs '%all; | %choice; | %sequence;'>
+<!ENTITY % cs '%choice; | %sequence;'>
+<!ENTITY % formValues '(qualified|unqualified)'>
+
+
+<!ENTITY % attrDecls '((%attribute;| %attributeGroup;)*,(%anyAttribute;)?)'>
+
+<!ENTITY % particleAndAttrs '((%mgs; | %group;)?, %attrDecls;)'>
+
+<!-- This is used in part2 -->
+<!ENTITY % restriction1 '((%mgs; | %group;)?)'>
+
+%xs-datatypes;
+
+<!-- the duplication below is to produce an unambiguous content model
+ which allows annotation everywhere -->
+<!ELEMENT %schema; ((%include; | %import; | %redefine; | %annotation;)*,
+ ((%simpleType; | %complexType;
+ | %element; | %attribute;
+ | %attributeGroup; | %group;
+ | %notation; ),
+ (%annotation;)*)* )>
+<!ATTLIST %schema;
+ targetNamespace %URIref; #IMPLIED
+ version CDATA #IMPLIED
+ %nds; %URIref; #FIXED 'http://www.w3.org/2001/XMLSchema'
+ xmlns CDATA #IMPLIED
+ finalDefault %complexDerivationSet; ''
+ blockDefault %blockSet; ''
+ id ID #IMPLIED
+ elementFormDefault %formValues; 'unqualified'
+ attributeFormDefault %formValues; 'unqualified'
+ xml:lang CDATA #IMPLIED
+ %schemaAttrs;>
+<!-- Note the xmlns declaration is NOT in the Schema for Schemas,
+ because at the Infoset level where schemas operate,
+ xmlns(:prefix) is NOT an attribute! -->
+<!-- The declaration of xmlns is a convenience for schema authors -->
+
+<!-- The id attribute here and below is for use in external references
+ from non-schemas using simple fragment identifiers.
+ It is NOT used for schema-to-schema reference, internal or
+ external. -->
+
+<!-- a type is a named content type specification which allows attribute
+ declarations-->
+<!-- -->
+
+<!ELEMENT %complexType; ((%annotation;)?,
+ (%simpleContent;|%complexContent;|
+ %particleAndAttrs;))>
+
+<!ATTLIST %complexType;
+ name %NCName; #IMPLIED
+ id ID #IMPLIED
+ abstract %boolean; #IMPLIED
+ final %complexDerivationSet; #IMPLIED
+ block %complexDerivationSet; #IMPLIED
+ mixed (true|false) 'false'
+ %complexTypeAttrs;>
+
+<!-- particleAndAttrs is shorthand for a root type -->
+<!-- mixed is disallowed if simpleContent, overriden if complexContent
+ has one too. -->
+
+<!-- If anyAttribute appears in one or more referenced attributeGroups
+ and/or explicitly, the intersection of the permissions is used -->
+
+<!ELEMENT %complexContent; ((%annotation;)?, (%restriction;|%extension;))>
+<!ATTLIST %complexContent;
+ mixed (true|false) #IMPLIED
+ id ID #IMPLIED
+ %complexContentAttrs;>
+
+<!-- restriction should use the branch defined above, not the simple
+ one from part2; extension should use the full model -->
+
+<!ELEMENT %simpleContent; ((%annotation;)?, (%restriction;|%extension;))>
+<!ATTLIST %simpleContent;
+ id ID #IMPLIED
+ %simpleContentAttrs;>
+
+<!-- restriction should use the simple branch from part2, not the
+ one defined above; extension should have no particle -->
+
+<!ELEMENT %extension; ((%annotation;)?, (%particleAndAttrs;))>
+<!ATTLIST %extension;
+ base %QName; #REQUIRED
+ id ID #IMPLIED
+ %extensionAttrs;>
+
+<!-- an element is declared by either:
+ a name and a type (either nested or referenced via the type attribute)
+ or a ref to an existing element declaration -->
+
+<!ELEMENT %element; ((%annotation;)?, (%complexType;| %simpleType;)?,
+ (%unique; | %key; | %keyref;)*)>
+<!-- simpleType or complexType only if no type|ref attribute -->
+<!-- ref not allowed at top level -->
+<!ATTLIST %element;
+ name %NCName; #IMPLIED
+ id ID #IMPLIED
+ ref %QName; #IMPLIED
+ type %QName; #IMPLIED
+ minOccurs %nonNegativeInteger; #IMPLIED
+ maxOccurs CDATA #IMPLIED
+ nillable %boolean; #IMPLIED
+ substitutionGroup %QName; #IMPLIED
+ abstract %boolean; #IMPLIED
+ final %complexDerivationSet; #IMPLIED
+ block %blockSet; #IMPLIED
+ default CDATA #IMPLIED
+ fixed CDATA #IMPLIED
+ form %formValues; #IMPLIED
+ %elementAttrs;>
+<!-- type and ref are mutually exclusive.
+ name and ref are mutually exclusive, one is required -->
+<!-- In the absence of type AND ref, type defaults to type of
+ substitutionGroup, if any, else the ur-type, i.e. unconstrained -->
+<!-- default and fixed are mutually exclusive -->
+
+<!ELEMENT %group; ((%annotation;)?,(%mgs;)?)>
+<!ATTLIST %group;
+ name %NCName; #IMPLIED
+ ref %QName; #IMPLIED
+ minOccurs %nonNegativeInteger; #IMPLIED
+ maxOccurs CDATA #IMPLIED
+ id ID #IMPLIED
+ %groupAttrs;>
+
+<!ELEMENT %all; ((%annotation;)?, (%element;)*)>
+<!ATTLIST %all;
+ minOccurs (1) #IMPLIED
+ maxOccurs (1) #IMPLIED
+ id ID #IMPLIED
+ %allAttrs;>
+
+<!ELEMENT %choice; ((%annotation;)?, (%element;| %group;| %cs; | %any;)*)>
+<!ATTLIST %choice;
+ minOccurs %nonNegativeInteger; #IMPLIED
+ maxOccurs CDATA #IMPLIED
+ id ID #IMPLIED
+ %choiceAttrs;>
+
+<!ELEMENT %sequence; ((%annotation;)?, (%element;| %group;| %cs; | %any;)*)>
+<!ATTLIST %sequence;
+ minOccurs %nonNegativeInteger; #IMPLIED
+ maxOccurs CDATA #IMPLIED
+ id ID #IMPLIED
+ %sequenceAttrs;>
+
+<!-- an anonymous grouping in a model, or
+ a top-level named group definition, or a reference to same -->
+
+<!-- Note that if order is 'all', group is not allowed inside.
+ If order is 'all' THIS group must be alone (or referenced alone) at
+ the top level of a content model -->
+<!-- If order is 'all', minOccurs==maxOccurs==1 on element/any inside -->
+<!-- Should allow minOccurs=0 inside order='all' . . . -->
+
+<!ELEMENT %any; (%annotation;)?>
+<!ATTLIST %any;
+ namespace CDATA '##any'
+ processContents (skip|lax|strict) 'strict'
+ minOccurs %nonNegativeInteger; '1'
+ maxOccurs CDATA '1'
+ id ID #IMPLIED
+ %anyAttrs;>
+
+<!-- namespace is interpreted as follows:
+ ##any - - any non-conflicting WFXML at all
+
+ ##other - - any non-conflicting WFXML from namespace other
+ than targetNamespace
+
+ ##local - - any unqualified non-conflicting WFXML/attribute
+ one or - - any non-conflicting WFXML from
+ more URI the listed namespaces
+ references
+
+ ##targetNamespace ##local may appear in the above list,
+ with the obvious meaning -->
+
+<!ELEMENT %anyAttribute; (%annotation;)?>
+<!ATTLIST %anyAttribute;
+ namespace CDATA '##any'
+ processContents (skip|lax|strict) 'strict'
+ id ID #IMPLIED
+ %anyAttributeAttrs;>
+<!-- namespace is interpreted as for 'any' above -->
+
+<!-- simpleType only if no type|ref attribute -->
+<!-- ref not allowed at top level, name iff at top level -->
+<!ELEMENT %attribute; ((%annotation;)?, (%simpleType;)?)>
+<!ATTLIST %attribute;
+ name %NCName; #IMPLIED
+ id ID #IMPLIED
+ ref %QName; #IMPLIED
+ type %QName; #IMPLIED
+ use (prohibited|optional|required) #IMPLIED
+ default CDATA #IMPLIED
+ fixed CDATA #IMPLIED
+ form %formValues; #IMPLIED
+ %attributeAttrs;>
+<!-- type and ref are mutually exclusive.
+ name and ref are mutually exclusive, one is required -->
+<!-- default for use is optional when nested, none otherwise -->
+<!-- default and fixed are mutually exclusive -->
+<!-- type attr and simpleType content are mutually exclusive -->
+
+<!-- an attributeGroup is a named collection of attribute decls, or a
+ reference thereto -->
+<!ELEMENT %attributeGroup; ((%annotation;)?,
+ (%attribute; | %attributeGroup;)*,
+ (%anyAttribute;)?) >
+<!ATTLIST %attributeGroup;
+ name %NCName; #IMPLIED
+ id ID #IMPLIED
+ ref %QName; #IMPLIED
+ %attributeGroupAttrs;>
+
+<!-- ref iff no content, no name. ref iff not top level -->
+
+<!-- better reference mechanisms -->
+<!ELEMENT %unique; ((%annotation;)?, %selector;, (%field;)+)>
+<!ATTLIST %unique;
+ name %NCName; #REQUIRED
+ id ID #IMPLIED
+ %uniqueAttrs;>
+
+<!ELEMENT %key; ((%annotation;)?, %selector;, (%field;)+)>
+<!ATTLIST %key;
+ name %NCName; #REQUIRED
+ id ID #IMPLIED
+ %keyAttrs;>
+
+<!ELEMENT %keyref; ((%annotation;)?, %selector;, (%field;)+)>
+<!ATTLIST %keyref;
+ name %NCName; #REQUIRED
+ refer %QName; #REQUIRED
+ id ID #IMPLIED
+ %keyrefAttrs;>
+
+<!ELEMENT %selector; ((%annotation;)?)>
+<!ATTLIST %selector;
+ xpath %XPathExpr; #REQUIRED
+ id ID #IMPLIED
+ %selectorAttrs;>
+<!ELEMENT %field; ((%annotation;)?)>
+<!ATTLIST %field;
+ xpath %XPathExpr; #REQUIRED
+ id ID #IMPLIED
+ %fieldAttrs;>
+
+<!-- Schema combination mechanisms -->
+<!ELEMENT %include; (%annotation;)?>
+<!ATTLIST %include;
+ schemaLocation %URIref; #REQUIRED
+ id ID #IMPLIED
+ %includeAttrs;>
+
+<!ELEMENT %import; (%annotation;)?>
+<!ATTLIST %import;
+ namespace %URIref; #IMPLIED
+ schemaLocation %URIref; #IMPLIED
+ id ID #IMPLIED
+ %importAttrs;>
+
+<!ELEMENT %redefine; (%annotation; | %simpleType; | %complexType; |
+ %attributeGroup; | %group;)*>
+<!ATTLIST %redefine;
+ schemaLocation %URIref; #REQUIRED
+ id ID #IMPLIED
+ %redefineAttrs;>
+
+<!ELEMENT %notation; (%annotation;)?>
+<!ATTLIST %notation;
+ name %NCName; #REQUIRED
+ id ID #IMPLIED
+ public CDATA #REQUIRED
+ system %URIref; #IMPLIED
+ %notationAttrs;>
+
+<!-- Annotation is either application information or documentation -->
+<!-- By having these here they are available for datatypes as well
+ as all the structures elements -->
+
+<!ELEMENT %annotation; (%appinfo; | %documentation;)*>
+<!ATTLIST %annotation; %annotationAttrs;>
+
+<!-- User must define annotation elements in internal subset for this
+ to work -->
+<!ELEMENT %appinfo; ANY> <!-- too restrictive -->
+<!ATTLIST %appinfo;
+ source %URIref; #IMPLIED
+ id ID #IMPLIED
+ %appinfoAttrs;>
+<!ELEMENT %documentation; ANY> <!-- too restrictive -->
+<!ATTLIST %documentation;
+ source %URIref; #IMPLIED
+ id ID #IMPLIED
+ xml:lang CDATA #IMPLIED
+ %documentationAttrs;>
+
+<!NOTATION XMLSchemaStructures PUBLIC
+ 'structures' 'http://www.w3.org/2001/XMLSchema.xsd' >
+<!NOTATION XML PUBLIC
+ 'REC-xml-1998-0210' 'http://www.w3.org/TR/1998/REC-xml-19980210' >
diff --git a/sca-cpp/branches/gcc-4.4/xsd/external/datatypes.dtd b/sca-cpp/branches/gcc-4.4/xsd/external/datatypes.dtd
new file mode 100644
index 0000000000..685e89a57e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/external/datatypes.dtd
@@ -0,0 +1,204 @@
+<!--
+ DTD for XML Schemas: Part 2: Datatypes
+ $Id: datatypes.dtd,v 1.23 2001/03/16 17:36:30 ht Exp $
+ Note this DTD is NOT normative, or even definitive. - - the
+ prose copy in the datatypes REC is the definitive version
+ (which shouldn't differ from this one except for this comment
+ and entity expansions, but just in case)
+ -->
+
+<!--
+ This DTD cannot be used on its own, it is intended
+ only for incorporation in XMLSchema.dtd, q.v.
+ -->
+
+<!-- Define all the element names, with optional prefix -->
+<!ENTITY % simpleType "%p;simpleType">
+<!ENTITY % restriction "%p;restriction">
+<!ENTITY % list "%p;list">
+<!ENTITY % union "%p;union">
+<!ENTITY % maxExclusive "%p;maxExclusive">
+<!ENTITY % minExclusive "%p;minExclusive">
+<!ENTITY % maxInclusive "%p;maxInclusive">
+<!ENTITY % minInclusive "%p;minInclusive">
+<!ENTITY % totalDigits "%p;totalDigits">
+<!ENTITY % fractionDigits "%p;fractionDigits">
+<!ENTITY % length "%p;length">
+<!ENTITY % minLength "%p;minLength">
+<!ENTITY % maxLength "%p;maxLength">
+<!ENTITY % enumeration "%p;enumeration">
+<!ENTITY % whiteSpace "%p;whiteSpace">
+<!ENTITY % pattern "%p;pattern">
+
+<!--
+ Customisation entities for the ATTLIST of each element
+ type. Define one of these if your schema takes advantage
+ of the anyAttribute='##other' in the schema for schemas
+ -->
+
+<!ENTITY % simpleTypeAttrs "">
+<!ENTITY % restrictionAttrs "">
+<!ENTITY % listAttrs "">
+<!ENTITY % unionAttrs "">
+<!ENTITY % maxExclusiveAttrs "">
+<!ENTITY % minExclusiveAttrs "">
+<!ENTITY % maxInclusiveAttrs "">
+<!ENTITY % minInclusiveAttrs "">
+<!ENTITY % totalDigitsAttrs "">
+<!ENTITY % fractionDigitsAttrs "">
+<!ENTITY % lengthAttrs "">
+<!ENTITY % minLengthAttrs "">
+<!ENTITY % maxLengthAttrs "">
+<!ENTITY % enumerationAttrs "">
+<!ENTITY % whiteSpaceAttrs "">
+<!ENTITY % patternAttrs "">
+
+<!-- Define some entities for informative use as attribute
+ types -->
+<!ENTITY % URIref "CDATA">
+<!ENTITY % XPathExpr "CDATA">
+<!ENTITY % QName "NMTOKEN">
+<!ENTITY % QNames "NMTOKENS">
+<!ENTITY % NCName "NMTOKEN">
+<!ENTITY % nonNegativeInteger "NMTOKEN">
+<!ENTITY % boolean "(true|false)">
+<!ENTITY % simpleDerivationSet "CDATA">
+<!--
+ #all or space-separated list drawn from derivationChoice
+ -->
+
+<!--
+ Note that the use of 'facet' below is less restrictive
+ than is really intended: There should in fact be no
+ more than one of each of minInclusive, minExclusive,
+ maxInclusive, maxExclusive, totalDigits, fractionDigits,
+ length, maxLength, minLength within datatype,
+ and the min- and max- variants of Inclusive and Exclusive
+ are mutually exclusive. On the other hand, pattern and
+ enumeration may repeat.
+ -->
+<!ENTITY % minBound "(%minInclusive; | %minExclusive;)">
+<!ENTITY % maxBound "(%maxInclusive; | %maxExclusive;)">
+<!ENTITY % bounds "%minBound; | %maxBound;">
+<!ENTITY % numeric "%totalDigits; | %fractionDigits;">
+<!ENTITY % ordered "%bounds; | %numeric;">
+<!ENTITY % unordered
+ "%pattern; | %enumeration; | %whiteSpace; | %length; |
+ %maxLength; | %minLength;">
+<!ENTITY % facet "%ordered; | %unordered;">
+<!ENTITY % facetAttr
+ "value CDATA #REQUIRED
+ id ID #IMPLIED">
+<!ENTITY % fixedAttr "fixed %boolean; #IMPLIED">
+<!ENTITY % facetModel "(%annotation;)?">
+<!ELEMENT %simpleType;
+ ((%annotation;)?, (%restriction; | %list; | %union;))>
+<!ATTLIST %simpleType;
+ name %NCName; #IMPLIED
+ final %simpleDerivationSet; #IMPLIED
+ id ID #IMPLIED
+ %simpleTypeAttrs;>
+<!-- name is required at top level -->
+<!ELEMENT %restriction; ((%annotation;)?,
+ (%restriction1; |
+ ((%simpleType;)?,(%facet;)*)),
+ (%attrDecls;))>
+<!ATTLIST %restriction;
+ base %QName; #IMPLIED
+ id ID #IMPLIED
+ %restrictionAttrs;>
+<!--
+ base and simpleType child are mutually exclusive,
+ one is required.
+
+ restriction is shared between simpleType and
+ simpleContent and complexContent (in XMLSchema.xsd).
+ restriction1 is for the latter cases, when this
+ is restricting a complex type, as is attrDecls.
+ -->
+<!ELEMENT %list; ((%annotation;)?,(%simpleType;)?)>
+<!ATTLIST %list;
+ itemType %QName; #IMPLIED
+ id ID #IMPLIED
+ %listAttrs;>
+<!--
+ itemType and simpleType child are mutually exclusive,
+ one is required
+ -->
+<!ELEMENT %union; ((%annotation;)?,(%simpleType;)*)>
+<!ATTLIST %union;
+ id ID #IMPLIED
+ memberTypes %QNames; #IMPLIED
+ %unionAttrs;>
+<!--
+ At least one item in memberTypes or one simpleType
+ child is required
+ -->
+
+<!ELEMENT %maxExclusive; %facetModel;>
+<!ATTLIST %maxExclusive;
+ %facetAttr;
+ %fixedAttr;
+ %maxExclusiveAttrs;>
+<!ELEMENT %minExclusive; %facetModel;>
+<!ATTLIST %minExclusive;
+ %facetAttr;
+ %fixedAttr;
+ %minExclusiveAttrs;>
+
+<!ELEMENT %maxInclusive; %facetModel;>
+<!ATTLIST %maxInclusive;
+ %facetAttr;
+ %fixedAttr;
+ %maxInclusiveAttrs;>
+<!ELEMENT %minInclusive; %facetModel;>
+<!ATTLIST %minInclusive;
+ %facetAttr;
+ %fixedAttr;
+ %minInclusiveAttrs;>
+
+<!ELEMENT %totalDigits; %facetModel;>
+<!ATTLIST %totalDigits;
+ %facetAttr;
+ %fixedAttr;
+ %totalDigitsAttrs;>
+<!ELEMENT %fractionDigits; %facetModel;>
+<!ATTLIST %fractionDigits;
+ %facetAttr;
+ %fixedAttr;
+ %fractionDigitsAttrs;>
+
+<!ELEMENT %length; %facetModel;>
+<!ATTLIST %length;
+ %facetAttr;
+ %fixedAttr;
+ %lengthAttrs;>
+<!ELEMENT %minLength; %facetModel;>
+<!ATTLIST %minLength;
+ %facetAttr;
+ %fixedAttr;
+ %minLengthAttrs;>
+<!ELEMENT %maxLength; %facetModel;>
+<!ATTLIST %maxLength;
+ %facetAttr;
+ %fixedAttr;
+ %maxLengthAttrs;>
+
+<!-- This one can be repeated -->
+<!ELEMENT %enumeration; %facetModel;>
+<!ATTLIST %enumeration;
+ %facetAttr;
+ %enumerationAttrs;>
+
+<!ELEMENT %whiteSpace; %facetModel;>
+<!ATTLIST %whiteSpace;
+ %facetAttr;
+ %fixedAttr;
+ %whiteSpaceAttrs;>
+
+<!-- This one can be repeated -->
+<!ELEMENT %pattern; %facetModel;>
+<!ATTLIST %pattern;
+ %facetAttr;
+ %patternAttrs;>
+
diff --git a/sca-cpp/branches/gcc-4.4/xsd/external/oasis-200401-wss-wssecurity-secext-1.0.xsd b/sca-cpp/branches/gcc-4.4/xsd/external/oasis-200401-wss-wssecurity-secext-1.0.xsd
new file mode 100644
index 0000000000..641798b17f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/external/oasis-200401-wss-wssecurity-secext-1.0.xsd
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+Copyright © OASIS Open 2002-2004. All Rights Reserved.
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself does not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+This document and the information contained herein is provided on an “AS IS” basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+-->
+<xsd:schema targetNamespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" elementFormDefault="qualified" attributeFormDefault="unqualified" blockDefault="#all" version="0.2">
+ <xsd:import namespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" schemaLocation="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"/>
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+ <xsd:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd"/>
+ <xsd:complexType name="AttributedString">
+ <xsd:annotation>
+ <xsd:documentation>This type represents an element with arbitrary attributes.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute ref="wsu:Id"/>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ <xsd:complexType name="PasswordString">
+ <xsd:annotation>
+ <xsd:documentation>This type is used for password elements per Section 4.1.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleContent>
+ <xsd:extension base="wsse:AttributedString">
+ <xsd:attribute name="Type" type="xsd:anyURI"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ <xsd:complexType name="EncodedString">
+ <xsd:annotation>
+ <xsd:documentation>This type is used for elements containing stringified binary data.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleContent>
+ <xsd:extension base="wsse:AttributedString">
+ <xsd:attribute name="EncodingType" type="xsd:anyURI"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ <xsd:complexType name="UsernameTokenType">
+ <xsd:annotation>
+ <xsd:documentation>This type represents a username token per Section 4.1</xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="Username" type="wsse:AttributedString"/>
+ <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute ref="wsu:Id"/>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:complexType name="BinarySecurityTokenType">
+ <xsd:annotation>
+ <xsd:documentation>A security token that is encoded in binary</xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleContent>
+ <xsd:extension base="wsse:EncodedString">
+ <xsd:attribute name="ValueType" type="xsd:anyURI"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ <xsd:complexType name="KeyIdentifierType">
+ <xsd:annotation>
+ <xsd:documentation>A security token key identifier</xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleContent>
+ <xsd:extension base="wsse:EncodedString">
+ <xsd:attribute name="ValueType" type="xsd:anyURI"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ <xsd:simpleType name="tUsage">
+ <xsd:annotation>
+ <xsd:documentation>Typedef to allow a list of usages (as URIs).</xsd:documentation>
+ </xsd:annotation>
+ <xsd:list itemType="xsd:anyURI"/>
+ </xsd:simpleType>
+ <xsd:attribute name="Usage" type="tUsage">
+ <xsd:annotation>
+ <xsd:documentation>This global attribute is used to indicate the usage of a referenced or indicated token within the containing context</xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:complexType name="ReferenceType">
+ <xsd:annotation>
+ <xsd:documentation>This type represents a reference to an external security token.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="URI" type="xsd:anyURI"/>
+ <xsd:attribute name="ValueType" type="xsd:anyURI"/>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:complexType name="EmbeddedType">
+ <xsd:annotation>
+ <xsd:documentation>This type represents a reference to an embedded security token.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:any processContents="lax"/>
+ </xsd:choice>
+ <xsd:attribute name="ValueType" type="xsd:anyURI"/>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:complexType name="SecurityTokenReferenceType">
+ <xsd:annotation>
+ <xsd:documentation>This type is used reference a security token.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:any processContents="lax"/>
+ </xsd:choice>
+ <xsd:attribute ref="wsu:Id"/>
+ <xsd:attribute ref="wsse:Usage"/>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:complexType name="SecurityHeaderType">
+ <xsd:annotation>
+ <xsd:documentation>This complexType defines header block to use for security-relevant data directed at a specific SOAP actor.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation>The use of "any" is to allow extensibility and different forms of security data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:any>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:complexType name="TransformationParametersType">
+ <xsd:annotation>
+ <xsd:documentation>This complexType defines a container for elements to be specified from any namespace as properties/parameters of a DSIG transformation.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation>The use of "any" is to allow extensibility from any namespace.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:any>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="UsernameToken" type="wsse:UsernameTokenType">
+ <xsd:annotation>
+ <xsd:documentation>This element defines the wsse:UsernameToken element per Section 4.1.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="BinarySecurityToken" type="wsse:BinarySecurityTokenType">
+ <xsd:annotation>
+ <xsd:documentation>This element defines the wsse:BinarySecurityToken element per Section 4.2.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="Reference" type="wsse:ReferenceType">
+ <xsd:annotation>
+ <xsd:documentation>This element defines a security token reference</xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="Embedded" type="wsse:EmbeddedType">
+ <xsd:annotation>
+ <xsd:documentation>This element defines a security token embedded reference</xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="KeyIdentifier" type="wsse:KeyIdentifierType">
+ <xsd:annotation>
+ <xsd:documentation>This element defines a key identifier reference</xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="SecurityTokenReference" type="wsse:SecurityTokenReferenceType">
+ <xsd:annotation>
+ <xsd:documentation>This element defines the wsse:SecurityTokenReference per Section 4.3.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="Security" type="wsse:SecurityHeaderType">
+ <xsd:annotation>
+ <xsd:documentation>This element defines the wsse:Security SOAP header element per Section 4.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="TransformationParameters" type="wsse:TransformationParametersType">
+ <xsd:annotation>
+ <xsd:documentation>This element contains properties for transformations from any namespace, including DSIG.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="Password" type="wsse:PasswordString"/>
+ <xsd:element name="Nonce" type="wsse:EncodedString"/>
+ <xsd:simpleType name="FaultcodeEnum">
+ <xsd:restriction base="xsd:QName">
+ <xsd:enumeration value="wsse:UnsupportedSecurityToken"/>
+ <xsd:enumeration value="wsse:UnsupportedAlgorithm"/>
+ <xsd:enumeration value="wsse:InvalidSecurity"/>
+ <xsd:enumeration value="wsse:InvalidSecurityToken"/>
+ <xsd:enumeration value="wsse:FailedAuthentication"/>
+ <xsd:enumeration value="wsse:FailedCheck"/>
+ <xsd:enumeration value="wsse:SecurityTokenUnavailable"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+</xsd:schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/external/oasis-200401-wss-wssecurity-utility-1.0.xsd b/sca-cpp/branches/gcc-4.4/xsd/external/oasis-200401-wss-wssecurity-utility-1.0.xsd
new file mode 100644
index 0000000000..f8d74e9c6e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/external/oasis-200401-wss-wssecurity-utility-1.0.xsd
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+Copyright © OASIS Open 2002-2004. All Rights Reserved.
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself does not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+This document and the information contained herein is provided on an “AS IS” basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+-->
+<xsd:schema targetNamespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+
+
+
+xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
+elementFormDefault="qualified" attributeFormDefault="unqualified" version="0.1">
+ <!-- // Fault Codes /////////////////////////////////////////// -->
+ <xsd:simpleType name="tTimestampFault">
+ <xsd:annotation>
+ <xsd:documentation>
+This type defines the fault code value for Timestamp message expiration.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:QName">
+ <xsd:enumeration value="wsu:MessageExpired"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!-- // Global attributes //////////////////////////////////// -->
+ <xsd:attribute name="Id" type="xsd:ID">
+ <xsd:annotation>
+ <xsd:documentation>
+This global attribute supports annotating arbitrary elements with an ID.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attributeGroup name="commonAtts">
+ <xsd:annotation>
+ <xsd:documentation>
+Convenience attribute group used to simplify this schema.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute ref="wsu:Id" use="optional"/>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:attributeGroup>
+ <!-- // Utility types //////////////////////////////////////// -->
+ <xsd:complexType name="AttributedDateTime">
+ <xsd:annotation>
+ <xsd:documentation>
+This type is for elements whose [children] is a psuedo-dateTime and can have arbitrary attributes.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attributeGroup ref="wsu:commonAtts"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ <xsd:complexType name="AttributedURI">
+ <xsd:annotation>
+ <xsd:documentation>
+This type is for elements whose [children] is an anyURI and can have arbitrary attributes.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:anyURI">
+ <xsd:attributeGroup ref="wsu:commonAtts"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ <!-- // Timestamp header components /////////////////////////// -->
+ <xsd:complexType name="TimestampType">
+ <xsd:annotation>
+ <xsd:documentation>
+This complex type ties together the timestamp related elements into a composite type.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element ref="wsu:Created" minOccurs="0"/>
+ <xsd:element ref="wsu:Expires" minOccurs="0"/>
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:any namespace="##other" processContents="lax"/>
+ </xsd:choice>
+ </xsd:sequence>
+ <xsd:attributeGroup ref="wsu:commonAtts"/>
+ </xsd:complexType>
+ <xsd:element name="Timestamp" type="wsu:TimestampType">
+ <xsd:annotation>
+ <xsd:documentation>
+This element allows Timestamps to be applied anywhere element wildcards are present,
+including as a SOAP header.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <!-- global element decls to allow individual elements to appear anywhere -->
+ <xsd:element name="Expires" type="wsu:AttributedDateTime">
+ <xsd:annotation>
+ <xsd:documentation>
+This element allows an expiration time to be applied anywhere element wildcards are present.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="Created" type="wsu:AttributedDateTime">
+ <xsd:annotation>
+ <xsd:documentation>
+This element allows a creation time to be applied anywhere element wildcards are present.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+</xsd:schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/external/ws-addr.xsd b/sca-cpp/branches/gcc-4.4/xsd/external/ws-addr.xsd
new file mode 100644
index 0000000000..f6fc9c53b0
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/external/ws-addr.xsd
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ W3C XML Schema defined in the Web Services Addressing 1.0 specification
+ http://www.w3.org/TR/ws-addr-core
+
+ Copyright © 2005 World Wide Web Consortium,
+
+ (Massachusetts Institute of Technology, European Research Consortium for
+ Informatics and Mathematics, Keio University). All Rights Reserved. This
+ work is distributed under the W3C® Software License [1] in the hope that
+ it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+
+ $Id: ws-addr.xsd,v 1.2 2008/07/23 13:38:16 plehegar Exp $
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.w3.org/2005/08/addressing" targetNamespace="http://www.w3.org/2005/08/addressing" blockDefault="#all" elementFormDefault="qualified" finalDefault="" attributeFormDefault="unqualified">
+
+ <!-- Constructs from the WS-Addressing Core -->
+
+ <xs:element name="EndpointReference" type="tns:EndpointReferenceType"/>
+ <xs:complexType name="EndpointReferenceType" mixed="false">
+ <xs:sequence>
+ <xs:element name="Address" type="tns:AttributedURIType"/>
+ <xs:element ref="tns:ReferenceParameters" minOccurs="0"/>
+ <xs:element ref="tns:Metadata" minOccurs="0"/>
+ <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <xs:element name="ReferenceParameters" type="tns:ReferenceParametersType"/>
+ <xs:complexType name="ReferenceParametersType" mixed="false">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <xs:element name="Metadata" type="tns:MetadataType"/>
+ <xs:complexType name="MetadataType" mixed="false">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <xs:element name="MessageID" type="tns:AttributedURIType"/>
+ <xs:element name="RelatesTo" type="tns:RelatesToType"/>
+ <xs:complexType name="RelatesToType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute name="RelationshipType" type="tns:RelationshipTypeOpenEnum" use="optional" default="http://www.w3.org/2005/08/addressing/reply"/>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="RelationshipTypeOpenEnum">
+ <xs:union memberTypes="tns:RelationshipType xs:anyURI"/>
+ </xs:simpleType>
+
+ <xs:simpleType name="RelationshipType">
+ <xs:restriction base="xs:anyURI">
+ <xs:enumeration value="http://www.w3.org/2005/08/addressing/reply"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="ReplyTo" type="tns:EndpointReferenceType"/>
+ <xs:element name="From" type="tns:EndpointReferenceType"/>
+ <xs:element name="FaultTo" type="tns:EndpointReferenceType"/>
+ <xs:element name="To" type="tns:AttributedURIType"/>
+ <xs:element name="Action" type="tns:AttributedURIType"/>
+
+ <xs:complexType name="AttributedURIType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <!-- Constructs from the WS-Addressing SOAP binding -->
+
+ <xs:attribute name="IsReferenceParameter" type="xs:boolean"/>
+
+ <xs:simpleType name="FaultCodesOpenEnumType">
+ <xs:union memberTypes="tns:FaultCodesType xs:QName"/>
+ </xs:simpleType>
+
+ <xs:simpleType name="FaultCodesType">
+ <xs:restriction base="xs:QName">
+ <xs:enumeration value="tns:InvalidAddressingHeader"/>
+ <xs:enumeration value="tns:InvalidAddress"/>
+ <xs:enumeration value="tns:InvalidEPR"/>
+ <xs:enumeration value="tns:InvalidCardinality"/>
+ <xs:enumeration value="tns:MissingAddressInEPR"/>
+ <xs:enumeration value="tns:DuplicateMessageID"/>
+ <xs:enumeration value="tns:ActionMismatch"/>
+ <xs:enumeration value="tns:MessageAddressingHeaderRequired"/>
+ <xs:enumeration value="tns:DestinationUnreachable"/>
+ <xs:enumeration value="tns:ActionNotSupported"/>
+ <xs:enumeration value="tns:EndpointUnavailable"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="RetryAfter" type="tns:AttributedUnsignedLongType"/>
+ <xs:complexType name="AttributedUnsignedLongType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:unsignedLong">
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:element name="ProblemHeaderQName" type="tns:AttributedQNameType"/>
+ <xs:complexType name="AttributedQNameType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:QName">
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:element name="ProblemIRI" type="tns:AttributedURIType"/>
+
+ <xs:element name="ProblemAction" type="tns:ProblemActionType"/>
+ <xs:complexType name="ProblemActionType" mixed="false">
+ <xs:sequence>
+ <xs:element ref="tns:Action" minOccurs="0"/>
+ <xs:element name="SoapAction" minOccurs="0" type="xs:anyURI"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+</xs:schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/external/ws-policy.xsd b/sca-cpp/branches/gcc-4.4/xsd/external/ws-policy.xsd
new file mode 100644
index 0000000000..c43e5814ed
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/external/ws-policy.xsd
@@ -0,0 +1,141 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!--
+
+ W3C XML Schema defined in the Web Services Policy 1.5
+ Framework specification
+
+ http://www.w3.org/TR/ws-policy-framework
+
+ Copyright © 2006 World Wide Web Consortium,
+
+ (Massachusetts Institute of Technology, European Research Consortium for
+ Informatics and Mathematics, Keio University). All Rights Reserved. This
+ work is distributed under the W3C® Software License [1] in the hope that
+ it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+
+ $Id: ws-policy.xsd,v 1.2 2007/02/14 16:38:37 fsasaki Exp $
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:tns="http://www.w3.org/ns/ws-policy"
+ xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
+ xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
+ targetNamespace="http://www.w3.org/ns/ws-policy" blockDefault="#all"
+ elementFormDefault="qualified">
+
+ <xs:import
+ namespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
+ schemaLocation="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" />
+
+ <xs:import
+ namespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
+ schemaLocation="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" />
+
+ <xs:import
+ namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/xml.xsd" />
+
+ <!-- Constructs from the Web Services Policy 1.5 Framework -->
+
+ <xs:element name="Policy" >
+ <xs:complexType>
+
+ <xs:complexContent>
+ <xs:extension base="tns:OperatorContentType" >
+ <xs:attribute name="Name" type="xs:anyURI" />
+ <xs:anyAttribute namespace="##any" processContents="lax" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="All" type="tns:OperatorContentType" />
+ <xs:element name="ExactlyOne" type="tns:OperatorContentType" />
+
+ <xs:complexType name="OperatorContentType" >
+ <xs:sequence>
+ <xs:choice minOccurs="0" maxOccurs="unbounded" >
+ <xs:element ref="tns:Policy" />
+ <xs:element ref="tns:All" />
+ <xs:element ref="tns:ExactlyOne" />
+
+ <xs:element ref="tns:PolicyReference" />
+ <xs:any namespace="##other" processContents="lax" />
+ </xs:choice>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="PolicyReference" >
+ <xs:complexType>
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="URI" type="xs:anyURI" use="required" />
+
+ <xs:attribute name="Digest" type="xs:base64Binary" />
+ <xs:attribute name="DigestAlgorithm"
+ type="xs:anyURI"
+ default="http://www.w3.org/ns/ws-policy/Sha1Exc"
+ />
+ <xs:anyAttribute namespace="##any" processContents="lax" />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:attribute name="Optional" type="xs:boolean" default="false" />
+ <xs:attribute name="Ignorable" type="xs:boolean" default="false" />
+
+ <!-- Constructs from the Web Services Policy 1.5 Attachment -->
+
+ <xs:attribute name="PolicyURIs" >
+ <xs:simpleType>
+ <xs:list itemType="xs:anyURI" />
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:element name="PolicyAttachment" >
+ <xs:complexType>
+ <xs:sequence>
+
+ <xs:element ref="tns:AppliesTo" />
+ <xs:choice maxOccurs="unbounded" >
+ <xs:element ref="tns:Policy" />
+ <xs:element ref="tns:PolicyReference" />
+ </xs:choice>
+ <!-- omitted only because it causes the content model to be non-determistic
+ <xs:element ref="wsse:Security" minOccurs="0" />
+-->
+ <xs:any namespace="##other"
+ processContents="lax"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##any" processContents="lax" />
+
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="AppliesTo" >
+ <xs:complexType>
+ <xs:sequence>
+ <xs:any namespace="##any"
+ processContents="lax"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##any" processContents="lax" />
+
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="URI">
+ <xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:anyAttribute namespace="##any" processContents="lax" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ </xs:element>
+
+</xs:schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/external/wsdli.xsd b/sca-cpp/branches/gcc-4.4/xsd/external/wsdli.xsd
new file mode 100644
index 0000000000..24e0b5a975
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/external/wsdli.xsd
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE xs:schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd">
+<!--
+ W3C XML Schema defined in the Web Services Description (WSDL)
+ Version 2.0 specification
+ http://www.w3.org/TR/wsdl20
+
+ Copyright © 2007 World Wide Web Consortium,
+
+ (Massachusetts Institute of Technology, European Research Consortium for
+ Informatics and Mathematics, Keio University). All Rights Reserved. This
+ work is distributed under the W3C® Software License [1] in the hope that
+ it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+
+ $Id: wsdl20-instance.xsd,v 1.1 2007/06/19 15:59:38 plehegar Exp $
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsdli="http://www.w3.org/ns/wsdl-instance" targetNamespace="http://www.w3.org/ns/wsdl-instance" elementFormDefault="qualified" finalDefault="" blockDefault="" attributeFormDefault="unqualified">
+
+ <xs:attribute name="wsdlLocation">
+ <xs:annotation>
+ <xs:documentation>
+ This attribute can be used to provide some hints on where
+ additional WSDL information for a given namespace can be
+ found in order to help with QName resolution
+ </xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:list itemType="xs:anyURI"/>
+ </xs:simpleType>
+ </xs:attribute>
+
+</xs:schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/external/xml.xsd b/sca-cpp/branches/gcc-4.4/xsd/external/xml.xsd
new file mode 100644
index 0000000000..ac4b0ec8e6
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/external/xml.xsd
@@ -0,0 +1,117 @@
+<?xml version='1.0'?>
+<!DOCTYPE xs:schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "XMLSchema.dtd" >
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en">
+
+ <xs:annotation>
+ <xs:documentation>
+ See http://www.w3.org/XML/1998/namespace.html and
+ http://www.w3.org/TR/REC-xml for information about this namespace.
+
+ This schema document describes the XML namespace, in a form
+ suitable for import by other schema documents.
+
+ Note that local names in this namespace are intended to be defined
+ only by the World Wide Web Consortium or its subgroups. The
+ following names are currently defined in this namespace and should
+ not be used with conflicting semantics by any Working Group,
+ specification, or document instance:
+
+ base (as an attribute name): denotes an attribute whose value
+ provides a URI to be used as the base for interpreting any
+ relative URIs in the scope of the element on which it
+ appears; its value is inherited. This name is reserved
+ by virtue of its definition in the XML Base specification.
+
+ lang (as an attribute name): denotes an attribute whose value
+ is a language code for the natural language of the content of
+ any element; its value is inherited. This name is reserved
+ by virtue of its definition in the XML specification.
+
+ space (as an attribute name): denotes an attribute whose
+ value is a keyword indicating what whitespace processing
+ discipline is intended for the content of the element; its
+ value is inherited. This name is reserved by virtue of its
+ definition in the XML specification.
+
+ Father (in any context at all): denotes Jon Bosak, the chair of
+ the original XML Working Group. This name is reserved by
+ the following decision of the W3C XML Plenary and
+ XML Coordination groups:
+
+ In appreciation for his vision, leadership and dedication
+ the W3C XML Plenary on this 10th day of February, 2000
+ reserves for Jon Bosak in perpetuity the XML name
+ xml:Father
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>This schema defines attributes and an attribute group
+ suitable for use by
+ schemas wishing to allow xml:base, xml:lang or xml:space attributes
+ on elements they define.
+
+ To enable this, such a schema must import this schema
+ for the XML namespace, e.g. as follows:
+ &lt;schema . . .>
+ . . .
+ &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/03/xml.xsd"/>
+
+ Subsequently, qualified reference to any of the attributes
+ or the group defined below will have the desired effect, e.g.
+
+ &lt;type . . .>
+ . . .
+ &lt;attributeGroup ref="xml:specialAttrs"/>
+
+ will define a type which will schema-validate an instance
+ element with any of those attributes</xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>In keeping with the XML Schema WG's standard versioning
+ policy, this schema document will persist at
+ http://www.w3.org/2001/03/xml.xsd.
+ At the date of issue it can also be found at
+ http://www.w3.org/2001/xml.xsd.
+ The schema document at that URI may however change in the future,
+ in order to remain compatible with the latest version of XML Schema
+ itself. In other words, if the XML Schema namespace changes, the version
+ of this document at
+ http://www.w3.org/2001/xml.xsd will change
+ accordingly; the version at
+ http://www.w3.org/2001/03/xml.xsd will not change.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang" type="xs:language">
+ <xs:annotation>
+ <xs:documentation>In due course, we should install the relevant ISO 2- and 3-letter
+ codes as the enumerated possible values . . .</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="space" default="preserve">
+ <xs:simpleType>
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="base" type="xs:anyURI">
+ <xs:annotation>
+ <xs:documentation>See http://www.w3.org/TR/xmlbase/ for
+ information about this attribute.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ </xs:attributeGroup>
+
+</xs:schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/external/xmldsig-core-schema.xsd b/sca-cpp/branches/gcc-4.4/xsd/external/xmldsig-core-schema.xsd
new file mode 100644
index 0000000000..2a767e42ea
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/external/xmldsig-core-schema.xsd
@@ -0,0 +1,318 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE schema
+ PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd"
+ [
+ <!ATTLIST schema
+ xmlns:ds CDATA #FIXED "http://www.w3.org/2000/09/xmldsig#">
+ <!ENTITY dsig 'http://www.w3.org/2000/09/xmldsig#'>
+ <!ENTITY % p ''>
+ <!ENTITY % s ''>
+ ]>
+
+<!-- Schema for XML Signatures
+ http://www.w3.org/2000/09/xmldsig#
+ $Revision: 796166 $ on $Date: 2009-07-21 00:03:47 -0700 (Tue, 21 Jul 2009) $ by $Author: reagle $
+
+ Copyright 2001 The Internet Society and W3C (Massachusetts Institute
+ of Technology, Institut National de Recherche en Informatique et en
+ Automatique, Keio University). All Rights Reserved.
+ http://www.w3.org/Consortium/Legal/
+
+ This document is governed by the W3C Software License [1] as described
+ in the FAQ [2].
+
+ [1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
+ [2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
+-->
+
+
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
+ targetNamespace="http://www.w3.org/2000/09/xmldsig#"
+ version="0.1" elementFormDefault="qualified">
+
+<!-- Basic Types Defined for Signatures -->
+
+<simpleType name="CryptoBinary">
+ <restriction base="base64Binary">
+ </restriction>
+</simpleType>
+
+<!-- Start Signature -->
+
+<element name="Signature" type="ds:SignatureType"/>
+<complexType name="SignatureType">
+ <sequence>
+ <element ref="ds:SignedInfo"/>
+ <element ref="ds:SignatureValue"/>
+ <element ref="ds:KeyInfo" minOccurs="0"/>
+ <element ref="ds:Object" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+ <element name="SignatureValue" type="ds:SignatureValueType"/>
+ <complexType name="SignatureValueType">
+ <simpleContent>
+ <extension base="base64Binary">
+ <attribute name="Id" type="ID" use="optional"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+<!-- Start SignedInfo -->
+
+<element name="SignedInfo" type="ds:SignedInfoType"/>
+<complexType name="SignedInfoType">
+ <sequence>
+ <element ref="ds:CanonicalizationMethod"/>
+ <element ref="ds:SignatureMethod"/>
+ <element ref="ds:Reference" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+ <element name="CanonicalizationMethod" type="ds:CanonicalizationMethodType"/>
+ <complexType name="CanonicalizationMethodType" mixed="true">
+ <sequence>
+ <any namespace="##any" minOccurs="0" maxOccurs="unbounded"/>
+ <!-- (0,unbounded) elements from (1,1) namespace -->
+ </sequence>
+ <attribute name="Algorithm" type="anyURI" use="required"/>
+ </complexType>
+
+ <element name="SignatureMethod" type="ds:SignatureMethodType"/>
+ <complexType name="SignatureMethodType" mixed="true">
+ <sequence>
+ <element name="HMACOutputLength" minOccurs="0" type="ds:HMACOutputLengthType"/>
+ <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
+ <!-- (0,unbounded) elements from (1,1) external namespace -->
+ </sequence>
+ <attribute name="Algorithm" type="anyURI" use="required"/>
+ </complexType>
+
+<!-- Start Reference -->
+
+<element name="Reference" type="ds:ReferenceType"/>
+<complexType name="ReferenceType">
+ <sequence>
+ <element ref="ds:Transforms" minOccurs="0"/>
+ <element ref="ds:DigestMethod"/>
+ <element ref="ds:DigestValue"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+ <attribute name="URI" type="anyURI" use="optional"/>
+ <attribute name="Type" type="anyURI" use="optional"/>
+</complexType>
+
+ <element name="Transforms" type="ds:TransformsType"/>
+ <complexType name="TransformsType">
+ <sequence>
+ <element ref="ds:Transform" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <element name="Transform" type="ds:TransformType"/>
+ <complexType name="TransformType" mixed="true">
+ <choice minOccurs="0" maxOccurs="unbounded">
+ <any namespace="##other" processContents="lax"/>
+ <!-- (1,1) elements from (0,unbounded) namespaces -->
+ <element name="XPath" type="string"/>
+ </choice>
+ <attribute name="Algorithm" type="anyURI" use="required"/>
+ </complexType>
+
+<!-- End Reference -->
+
+<element name="DigestMethod" type="ds:DigestMethodType"/>
+<complexType name="DigestMethodType" mixed="true">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Algorithm" type="anyURI" use="required"/>
+</complexType>
+
+<element name="DigestValue" type="ds:DigestValueType"/>
+<simpleType name="DigestValueType">
+ <restriction base="base64Binary"/>
+</simpleType>
+
+<!-- End SignedInfo -->
+
+<!-- Start KeyInfo -->
+
+<element name="KeyInfo" type="ds:KeyInfoType"/>
+<complexType name="KeyInfoType" mixed="true">
+ <choice maxOccurs="unbounded">
+ <element ref="ds:KeyName"/>
+ <element ref="ds:KeyValue"/>
+ <element ref="ds:RetrievalMethod"/>
+ <element ref="ds:X509Data"/>
+ <element ref="ds:PGPData"/>
+ <element ref="ds:SPKIData"/>
+ <element ref="ds:MgmtData"/>
+ <any processContents="lax" namespace="##other"/>
+ <!-- (1,1) elements from (0,unbounded) namespaces -->
+ </choice>
+ <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+ <element name="KeyName" type="string"/>
+ <element name="MgmtData" type="string"/>
+
+ <element name="KeyValue" type="ds:KeyValueType"/>
+ <complexType name="KeyValueType" mixed="true">
+ <choice>
+ <element ref="ds:DSAKeyValue"/>
+ <element ref="ds:RSAKeyValue"/>
+ <any namespace="##other" processContents="lax"/>
+ </choice>
+ </complexType>
+
+ <element name="RetrievalMethod" type="ds:RetrievalMethodType"/>
+ <complexType name="RetrievalMethodType">
+ <sequence>
+ <element ref="ds:Transforms" minOccurs="0"/>
+ </sequence>
+ <attribute name="URI" type="anyURI"/>
+ <attribute name="Type" type="anyURI" use="optional"/>
+ </complexType>
+
+<!-- Start X509Data -->
+
+<element name="X509Data" type="ds:X509DataType"/>
+<complexType name="X509DataType">
+ <sequence maxOccurs="unbounded">
+ <choice>
+ <element name="X509IssuerSerial" type="ds:X509IssuerSerialType"/>
+ <element name="X509SKI" type="base64Binary"/>
+ <element name="X509SubjectName" type="string"/>
+ <element name="X509Certificate" type="base64Binary"/>
+ <element name="X509CRL" type="base64Binary"/>
+ <any namespace="##other" processContents="lax"/>
+ </choice>
+ </sequence>
+</complexType>
+
+<complexType name="X509IssuerSerialType">
+ <sequence>
+ <element name="X509IssuerName" type="string"/>
+ <element name="X509SerialNumber" type="integer"/>
+ </sequence>
+</complexType>
+
+<!-- End X509Data -->
+
+<!-- Begin PGPData -->
+
+<element name="PGPData" type="ds:PGPDataType"/>
+<complexType name="PGPDataType">
+ <choice>
+ <sequence>
+ <element name="PGPKeyID" type="base64Binary"/>
+ <element name="PGPKeyPacket" type="base64Binary" minOccurs="0"/>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <sequence>
+ <element name="PGPKeyPacket" type="base64Binary"/>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ </choice>
+</complexType>
+
+<!-- End PGPData -->
+
+<!-- Begin SPKIData -->
+
+<element name="SPKIData" type="ds:SPKIDataType"/>
+<complexType name="SPKIDataType">
+ <sequence maxOccurs="unbounded">
+ <element name="SPKISexp" type="base64Binary"/>
+ <any namespace="##other" processContents="lax" minOccurs="0"/>
+ </sequence>
+</complexType>
+
+<!-- End SPKIData -->
+
+<!-- End KeyInfo -->
+
+<!-- Start Object (Manifest, SignatureProperty) -->
+
+<element name="Object" type="ds:ObjectType"/>
+<complexType name="ObjectType" mixed="true">
+ <sequence minOccurs="0" maxOccurs="unbounded">
+ <any namespace="##any" processContents="lax"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+ <attribute name="MimeType" type="string" use="optional"/> <!-- add a grep facet -->
+ <attribute name="Encoding" type="anyURI" use="optional"/>
+</complexType>
+
+<element name="Manifest" type="ds:ManifestType"/>
+<complexType name="ManifestType">
+ <sequence>
+ <element ref="ds:Reference" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+<element name="SignatureProperties" type="ds:SignaturePropertiesType"/>
+<complexType name="SignaturePropertiesType">
+ <sequence>
+ <element ref="ds:SignatureProperty" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+ <element name="SignatureProperty" type="ds:SignaturePropertyType"/>
+ <complexType name="SignaturePropertyType" mixed="true">
+ <choice maxOccurs="unbounded">
+ <any namespace="##other" processContents="lax"/>
+ <!-- (1,1) elements from (1,unbounded) namespaces -->
+ </choice>
+ <attribute name="Target" type="anyURI" use="required"/>
+ <attribute name="Id" type="ID" use="optional"/>
+ </complexType>
+
+<!-- End Object (Manifest, SignatureProperty) -->
+
+<!-- Start Algorithm Parameters -->
+
+<simpleType name="HMACOutputLengthType">
+ <restriction base="integer"/>
+</simpleType>
+
+<!-- Start KeyValue Element-types -->
+
+<element name="DSAKeyValue" type="ds:DSAKeyValueType"/>
+<complexType name="DSAKeyValueType">
+ <sequence>
+ <sequence minOccurs="0">
+ <element name="P" type="ds:CryptoBinary"/>
+ <element name="Q" type="ds:CryptoBinary"/>
+ </sequence>
+ <element name="G" type="ds:CryptoBinary" minOccurs="0"/>
+ <element name="Y" type="ds:CryptoBinary"/>
+ <element name="J" type="ds:CryptoBinary" minOccurs="0"/>
+ <sequence minOccurs="0">
+ <element name="Seed" type="ds:CryptoBinary"/>
+ <element name="PgenCounter" type="ds:CryptoBinary"/>
+ </sequence>
+ </sequence>
+</complexType>
+
+<element name="RSAKeyValue" type="ds:RSAKeyValueType"/>
+<complexType name="RSAKeyValueType">
+ <sequence>
+ <element name="Modulus" type="ds:CryptoBinary"/>
+ <element name="Exponent" type="ds:CryptoBinary"/>
+ </sequence>
+</complexType>
+
+<!-- End KeyValue Element-types -->
+
+<!-- End Signature -->
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-1.1-cd04.xsd
new file mode 100644
index 0000000000..224c1254b3
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-1.1-cd04.xsd
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd"/>
+
+ <include schemaLocation="sca-interface-java-1.1-cd04.xsd"/>
+ <include schemaLocation="sca-interface-wsdl-1.1-cd04.xsd"/>
+ <include schemaLocation="sca-interface-cpp-1.1-cd04.xsd"/>
+ <include schemaLocation="sca-interface-c-1.1-cd04.xsd"/>
+
+ <include schemaLocation="sca-implementation-java-1.1-cd03.xsd"/>
+ <include schemaLocation="sca-implementation-composite-1.1-cd04.xsd"/>
+ <include schemaLocation="sca-implementation-cpp-1.1-cd04.xsd"/>
+ <include schemaLocation="sca-implementation-c-1.1-cd04.xsd"/>
+ <include schemaLocation="sca-implementation-bpel-1.1-cd03.xsd"/>
+ <include schemaLocation="sca-implementation-spring-1.1-cd01.xsd"/>
+
+ <include schemaLocation="sca-binding-ws-1.1-cd04.xsd"/>
+ <include schemaLocation="sca-binding-ws-callback-1.1-cd04.xsd"/> <!-- New -->
+ <include schemaLocation="sca-binding-jms-1.1-cd04.xsd"/>
+ <include schemaLocation="sca-binding-jca-1.1-cd04.xsd"/>
+ <include schemaLocation="sca-binding-sca-1.1-cd04.xsd"/>
+ <include schemaLocation="sca-binding-ejb-1.1-cd01.xsd"/>
+
+ <include schemaLocation="sca-definitions-1.1-cd04.xsd"/>
+ <include schemaLocation="sca-policy-1.1-cd04.xsd"/>
+
+ <include schemaLocation="sca-contribution-1.1-cd04.xsd"/>
+ <include schemaLocation="sca-contribution-cpp-1.1-cd04.xsd"/>
+ <include schemaLocation="sca-contribution-c-1.1-cd04.xsd"/>
+ <include schemaLocation="sca-contribution-java-1.1-cd02.xsd"/>
+
+ <include schemaLocation="sca-jee-1.1-wd03.xsd"/>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-binding-ejb-1.1-cd01.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-binding-ejb-1.1-cd01.xsd
new file mode 100644
index 0000000000..b8556f3632
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-binding-ejb-1.1-cd01.xsd
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved. OASIS trademark,
+ IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd" />
+
+ <element name="binding.ejb" type="sca:EJBSessionBeanBinding"
+ substitutionGroup="sca:binding" />
+
+ <simpleType name="VersionValue">
+ <restriction base="string">
+ <enumeration value="EJB2" />
+ <enumeration value="EJB3" />
+ </restriction>
+ </simpleType>
+
+ <complexType name="EJBSessionBeanBinding">
+ <complexContent>
+ <extension base="sca:Binding">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="homeInterface" type="NCName" use="optional" />
+ <attribute name="ejb-link-name" type="string" use="optional" />
+ <attribute name="ejb-version" type="sca:VersionValue" use="optional"
+ default="EJB3" />
+ </extension>
+ </complexContent>
+ </complexType>
+</schema> \ No newline at end of file
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-binding-jca-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-binding-jca-1.1-cd04.xsd
new file mode 100644
index 0000000000..5fd3f9d687
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-binding-jca-1.1-cd04.xsd
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd"/>
+
+ <complexType name="JCABinding">
+ <complexContent>
+ <extension base="sca:Binding">
+ <sequence>
+ <element name="outboundConnection"
+ type="sca:JCAOutboundConnection" minOccurs="0" />
+ <element name="inboundConnection"
+ type="sca:JCAInboundConnection" minOccurs="0" />
+ <element name="outboundInteraction"
+ type="sca:JCAOutboundInteraction" minOccurs="0" />
+ <element name="inboundInteraction"
+ type="sca:JCAInboundInteraction" minOccurs="0" />
+ <element name="property" type="sca:Property" minOccurs="0"
+ maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="connectionInfo" type="anyURI" use="optional" />
+ <attribute name="initialContextFactory" type="anyURI"
+ use="optional"/>
+ <attribute name="jndiURL" type="anyURI" use="optional"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <simpleType name="JCACreateResource">
+ <restriction base="string">
+ <enumeration value="always" />
+ <enumeration value="never" />
+ <enumeration value="ifNotExist" />
+ </restriction>
+ </simpleType>
+ <simpleType name="ResAuth">
+ <restriction base="string">
+ <enumeration value="container" />
+ <enumeration value="application" />
+ </restriction>
+ </simpleType>
+ <complexType name="JCAOutboundConnection">
+ <sequence>
+ <element name="resourceAdapter" type="sca:ResourceAdapter"
+ minOccurs="0" />
+ <element name="connection" type="sca:Connection" />
+ <element name="resAuth" type="sca:ResAuth" minOccurs="0" />
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="managed" type="boolean" use="optional"
+ default="true" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </complexType>
+ <complexType name="JCAInboundConnection">
+ <sequence>
+ <element name="resourceAdapter" type="sca:ResourceAdapter" />
+ <element name="activationSpec" type="sca:ActivationSpec" />
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <anyAttribute namespace="##other" processContents="lax" />
+ </complexType>
+ <complexType name="JCAOutboundInteraction">
+ <sequence>
+ <element name="connectionSpec" type="sca:ConnectionSpec"
+ minOccurs="0" />
+ <element name="interactionSpec" type="sca:InteractionSpec"
+ minOccurs="0" />
+ <element name="operation" type="sca:Operation" minOccurs="0" />
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <anyAttribute namespace="##other" processContents="lax" />
+ </complexType>
+ <complexType name="JCAInboundInteraction">
+ <sequence>
+ <element name="listener" type="string" minOccurs="0" />
+ <element name="inboundOperation" type="sca:InboundOperation"
+ minOccurs="0" maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <anyAttribute namespace="##other" processContents="lax" />
+ </complexType>
+ <complexType name="ResourceAdapter">
+ <sequence>
+ <element name="property" type="sca:Property" minOccurs="0"
+ maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="name" type="NMTOKEN" use="optional" />
+ <attribute name="type" type="NMTOKEN" use="required" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </complexType>
+ <complexType name="Connection">
+ <sequence>
+ <element name="property" type="sca:Property" minOccurs="0"
+ maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="name" type="NMTOKEN" use="optional" />
+ <attribute name="type" type="NMTOKEN" use="required" />
+ <attribute name="create" type="sca:JCACreateResource" use="optional"
+ default="ifNotExist" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </complexType>
+ <complexType name="ActivationSpec">
+ <sequence>
+ <element name="property" type="sca:Property" minOccurs="0"
+ maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="name" type="NMTOKEN" use="optional" />
+ <attribute name="type" type="NMTOKEN" use="required" />
+ <attribute name="create" type="sca:JCACreateResource" use="optional"
+ default="ifNotExist"/>
+ <anyAttribute namespace="##other" processContents="lax" />
+ </complexType>
+ <complexType name="Operation">
+ <sequence>
+ <element name="interactionSpec" type="sca:InteractionSpec"
+ minOccurs="0" />
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="name" type="NMTOKEN" use="required" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </complexType>
+ <complexType name="InboundOperation">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="name" type="NMTOKEN" use="required" />
+ <attribute name="nativeOperation" type="string" use="required" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </complexType>
+ <complexType name="ConnectionSpec">
+ <sequence>
+ <element name="property" type="sca:Property" minOccurs="0"
+ maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="type" type="NMTOKEN" use="required" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </complexType>
+ <complexType name="InteractionSpec">
+ <sequence>
+ <element name="property" type="sca:Property" minOccurs="0"
+ maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="type" type="NMTOKEN" use="required" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </complexType>
+
+ <element name="binding.jca" type="sca:JCABinding"
+ substitutionGroup="sca:binding" />
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-binding-jms-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-binding-jms-1.1-cd04.xsd
new file mode 100644
index 0000000000..e1838dddf0
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-binding-jms-1.1-cd04.xsd
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd"/>
+
+ <complexType name="JMSBinding">
+ <complexContent>
+ <extension base="sca:Binding">
+ <sequence>
+ <element name="destination" type="sca:JMSDestination"
+ minOccurs="0"/>
+ <choice minOccurs="0" maxOccurs="1">
+ <element name="connectionFactory"
+ type="sca:JMSConnectionFactory"/>
+ <element name="activationSpec" type="sca:JMSActivationSpec"/>
+ </choice>
+ <element name="response" type="sca:JMSResponse" minOccurs="0"/>
+ <element name="headers" type="sca:JMSHeaders" minOccurs="0"/>
+ <element name="messageSelection" type="sca:JMSMessageSelection"
+ minOccurs="0"/>
+ <element name="resourceAdapter" type="sca:JMSResourceAdapter"
+ minOccurs="0"/>
+ <element name="operationProperties"
+ type="sca:JMSOperationProperties"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="correlationScheme" type="QName"
+ default="sca:messageId"/>
+ <attribute name="initialContextFactory" type="anyURI"/>
+ <attribute name="jndiURL" type="anyURI"/>
+ <attribute name="requestConnection" type="QName"/>
+ <attribute name="responseConnection" type="QName"/>
+ <attribute name="operationProperties" type="QName"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <simpleType name="JMSCreateResource">
+ <restriction base="string">
+ <enumeration value="always"/>
+ <enumeration value="never"/>
+ <enumeration value="ifNotExist"/>
+ </restriction>
+ </simpleType>
+
+ <complexType name="JMSDestination">
+ <sequence>
+ <element name="property" type="sca:BindingProperty"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="jndiName" type="anyURI" use="required"/>
+ <attribute name="type" use="optional" default="queue">
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="queue"/>
+ <enumeration value="topic"/>
+ </restriction>
+ </simpleType>
+ </attribute>
+ <attribute name="create" type="sca:JMSCreateResource"
+ use="optional" default="ifNotExist"/>
+ </complexType>
+
+ <complexType name="JMSConnectionFactory">
+ <sequence> <element name="property" type="sca:BindingProperty"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="jndiName" type="anyURI" use="required"/>
+ <attribute name="create" type="sca:JMSCreateResource"
+ use="optional" default="ifNotExist"/>
+ </complexType>
+
+ <complexType name="JMSActivationSpec">
+ <sequence>
+ <element name="property" type="sca:BindingProperty"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="jndiName" type="anyURI" use="required"/>
+ <attribute name="create" type="sca:JMSCreateResource"
+ use="optional" default="ifNotExist"/>
+ </complexType>
+
+ <complexType name="JMSResponse">
+ <sequence>
+ <element name="wireFormat" type="sca:WireFormatType" minOccurs="0"/>
+ <element name="destination" type="sca:JMSDestination" minOccurs="0"/>
+ <choice minOccurs="0">
+ <element name="connectionFactory" type="sca:JMSConnectionFactory"/>
+ <element name="activationSpec" type="sca:JMSActivationSpec"/>
+ </choice>
+
+ <!-- TUSCANY-3297 -->
+ <any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+
+ </sequence>
+ </complexType>
+
+ <complexType name="JMSHeaders">
+ <sequence>
+ <element name="property" type="sca:BindingProperty"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="type" type="string"/>
+ <attribute name="deliveryMode">
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="persistent"/>
+ <enumeration value="nonpersistent"/>
+ </restriction>
+ </simpleType>
+ </attribute>
+ <attribute name="timeToLive" type="long"/>
+ <attribute name="priority">
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="0"/>
+ <enumeration value="1"/>
+ <enumeration value="2"/>
+ <enumeration value="3"/>
+ <enumeration value="4"/>
+ <enumeration value="5"/>
+ <enumeration value="6"/>
+ <enumeration value="7"/>
+ <enumeration value="8"/>
+ <enumeration value="9"/>
+ </restriction>
+ </simpleType>
+ </attribute>
+ </complexType>
+
+ <complexType name="JMSMessageSelection">
+ <sequence>
+ <element name="property" type="sca:BindingProperty"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="selector" type="string"/>
+ </complexType>
+
+ <complexType name="JMSResourceAdapter">
+ <sequence>
+ <element name="property" type="sca:BindingProperty"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="name" type="string" use="required"/>
+ </complexType>
+
+ <complexType name="JMSOperationProperties">
+ <sequence>
+ <element name="property" type="sca:BindingProperty"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <element name="headers" type="sca:JMSHeaders"/>
+ </sequence>
+ <attribute name="name" type="string" use="required"/>
+ <attribute name="nativeOperation" type="string"/>
+ </complexType>
+
+ <complexType name="BindingProperty">
+ <simpleContent>
+ <extension base="string">
+ <attribute name="name" type="NMTOKEN"/>
+ <attribute name="type" type="string" use="optional"
+ default="xs:string"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <element name="binding.jms" type="sca:JMSBinding"
+ substitutionGroup="sca:binding"/>
+
+ <element name="wireFormat.jmsDefault" type="sca:WireFormatType"
+ substitutionGroup="sca:wireFormat"/>
+
+ <element name="operationSelector.jmsDefault" type="sca:OperationSelectorType"
+ substitutionGroup="sca:operationSelector"/>
+</schema> \ No newline at end of file
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-binding-sca-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-binding-sca-1.1-cd04.xsd
new file mode 100644
index 0000000000..d607d8730f
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-binding-sca-1.1-cd04.xsd
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd"/>
+
+ <!-- SCA Binding -->
+ <element name="binding.sca" type="sca:SCABinding"
+ substitutionGroup="sca:binding"/>
+ <complexType name="SCABinding">
+ <complexContent>
+ <extension base="sca:Binding"/>
+ </complexContent>
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-binding-ws-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-binding-ws-1.1-cd04.xsd
new file mode 100644
index 0000000000..8e5a72b493
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-binding-ws-1.1-cd04.xsd
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:wsdli="http://www.w3.org/ns/wsdl-instance"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ elementFormDefault="qualified">
+
+ <import namespace="http://www.w3.org/ns/wsdl-instance"
+ schemaLocation="http://www.w3.org/2007/05/wsdl/wsdl20-instance.xsd"/>
+ <import namespace="http://www.w3.org/2005/08/addressing"
+ schemaLocation="http://www.w3.org/2006/03/addressing/ws-addr.xsd"/>
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd"/>
+
+ <element name="binding.ws" type="sca:WebServiceBinding"
+ substitutionGroup="sca:binding"/>
+
+ <complexType name="WebServiceBinding">
+ <complexContent>
+ <extension base="sca:Binding">
+ <sequence>
+ <element name="endpointReference" type="wsa:EndpointReferenceType"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="wsdlElement" type="anyURI" use="optional"/>
+ <attribute ref="wsdli:wsdlLocation" use="optional"/>
+ </extension>
+ </complexContent>
+ </complexType>
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-binding-ws-callback-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-binding-ws-callback-1.1-cd04.xsd
new file mode 100644
index 0000000000..874e36bab8
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-binding-ws-callback-1.1-cd04.xsd
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- (c) Copyright OASIS 2005, 2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply -->
+
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <element name="WSCallback">
+ <complexType>
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
+ </element>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-contribution-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-contribution-1.1-cd04.xsd
new file mode 100644
index 0000000000..f17675a8b1
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-contribution-1.1-cd04.xsd
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd"/>
+
+ <!-- Contribution -->
+ <element name="contribution" type="sca:ContributionType"/>
+ <complexType name="ContributionType">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <sequence>
+ <element name="deployable" type="sca:DeployableType"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="sca:importBase" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <element ref="sca:exportBase" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Deployable -->
+ <complexType name="DeployableType">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="composite" type="QName" use="required"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Import -->
+ <element name="importBase" type="sca:Import" abstract="true" />
+ <complexType name="Import" abstract="true">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <element name="import" type="sca:ImportType"
+ substitutionGroup="sca:importBase"/>
+ <complexType name="ImportType">
+ <complexContent>
+ <extension base="sca:Import">
+ <attribute name="namespace" type="string" use="required"/>
+ <attribute name="location" type="anyURI" use="optional"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Export -->
+ <element name="exportBase" type="sca:Export" abstract="true" />
+ <complexType name="Export" abstract="true">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <element name="export" type="sca:ExportType"
+ substitutionGroup="sca:exportBase"/>
+ <complexType name="ExportType">
+ <complexContent>
+ <extension base="sca:Export">
+ <attribute name="namespace" type="string" use="required"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-contribution-c-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-contribution-c-1.1-cd04.xsd
new file mode 100644
index 0000000000..f765eaae85
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-contribution-c-1.1-cd04.xsd
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2007,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-contribution-1.1-cd04.xsd" />
+
+ <element name="export.c" type="sca:CExport"
+ substitutionGroup="sca:exportBase" />
+
+ <complexType name="CExport">
+ <complexContent>
+ <extension base="sca:Export">
+ <attribute name="name" type="QName" use="required" />
+ <attribute name="path" type="string" use="optional" />
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <element name="import.c" type="sca:CImport"
+ substitutionGroup="sca:importBase" />
+
+ <complexType name="CImport">
+ <complexContent>
+ <extension base="sca:Import">
+ <attribute name="name" type="QName" use="required" />
+ <attribute name="location" type="string" use="required" />
+ </extension>
+ </complexContent>
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-contribution-cpp-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-contribution-cpp-1.1-cd04.xsd
new file mode 100644
index 0000000000..f98c6dc040
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-contribution-cpp-1.1-cd04.xsd
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2006,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-contribution-1.1-cd04.xsd" />
+
+ <element name="export.cpp" type="sca:CPPExport"
+ substitutionGroup="sca:exportBase" />
+
+ <complexType name="CPPExport">
+ <complexContent>
+ <extension base="sca:Export">
+ <attribute name="name" type="QName" use="required" />
+ <attribute name="path" type="string" use="optional" />
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <element name="import.cpp" type="sca:CPPImport"
+ substitutionGroup="sca:importBase" />
+
+ <complexType name="CPPImport">
+ <complexContent>
+ <extension base="sca:Import">
+ <attribute name="name" type="QName" use="required" />
+ <attribute name="location" type="string" use="required" />
+ </extension>
+ </complexContent>
+ </complexType>
+
+</schema> \ No newline at end of file
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-contribution-java-1.1-cd02.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-contribution-java-1.1-cd02.xsd
new file mode 100644
index 0000000000..7bad3bfc2a
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-contribution-java-1.1-cd02.xsd
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved. OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-contribution-1.1-cd04.xsd"/>
+
+ <!-- Import.java -->
+ <element name="import.java" type="sca:JavaImportType"
+ substitutionGroup="sca:importBase" />
+ <complexType name="JavaImportType">
+ <complexContent>
+ <extension base="sca:Import">
+ <attribute name="package" type="string" use="required"/>
+ <attribute name="location" type="anyURI" use="optional"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Export.java -->
+ <element name="export.java" type="sca:JavaExportType"
+ substitutionGroup="sca:exportBase" />
+ <complexType name="JavaExportType">
+ <complexContent>
+ <extension base="sca:Export">
+ <attribute name="package" type="string" use="required"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-core-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-core-1.1-cd04.xsd
new file mode 100644
index 0000000000..158daff214
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-core-1.1-cd04.xsd
@@ -0,0 +1,534 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+
+ <!-- Common extension base for SCA definitions -->
+ <complexType name="CommonExtensionBase">
+ <sequence>
+ <element ref="sca:documentation" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
+
+ <element name="documentation" type="sca:Documentation"/>
+ <complexType name="Documentation" mixed="true">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute ref="xml:lang"/>
+ </complexType>
+
+ <!-- Component Type -->
+ <element name="componentType" type="sca:ComponentType"/>
+ <complexType name="ComponentType">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <sequence>
+ <!-- Comment out the sca:implementation to workaround http://www.mail-archive.com/dev@tuscany.apache.org/msg08924.html. -->
+ <!--
+ <element ref="sca:implementation" minOccurs="0"/>
+ -->
+ <choice minOccurs="0" maxOccurs="unbounded">
+ <element name="service" type="sca:ComponentService"/>
+ <element name="reference"
+ type="sca:ComponentTypeReference"/>
+ <element name="property" type="sca:Property"/>
+ </choice>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="constrainingType" type="QName" use="optional"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Composite -->
+ <element name="composite" type="sca:Composite"/>
+ <complexType name="Composite">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <sequence>
+ <element ref="sca:include" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <choice minOccurs="0" maxOccurs="unbounded">
+ <element name="service" type="sca:Service"/>
+ <element name="property" type="sca:Property"/>
+ <element name="component" type="sca:Component"/>
+ <element name="reference" type="sca:Reference"/>
+ <element name="wire" type="sca:Wire"/>
+ </choice>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="name" type="NCName" use="required"/>
+ <attribute name="targetNamespace" type="anyURI" use="required"/>
+ <attribute name="local" type="boolean" use="optional"
+ default="false"/>
+ <attribute name="autowire" type="boolean" use="optional"
+ default="false"/>
+ <attribute name="constrainingType" type="QName" use="optional"/>
+ <attribute name="requires" type="sca:listOfQNames"
+ use="optional"/>
+ <attribute name="policySets" type="sca:listOfQNames"
+ use="optional"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Contract base type for Service, Reference -->
+ <complexType name="Contract" abstract="true">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <sequence>
+ <element ref="sca:interface" minOccurs="0" maxOccurs="1" />
+ <element ref="sca:binding" minOccurs="0"
+ maxOccurs="unbounded" />
+ <element ref="sca:callback" minOccurs="0" maxOccurs="1" />
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="name" type="NCName" use="required" />
+ <attribute name="requires" type="sca:listOfQNames"
+ use="optional" />
+ <attribute name="policySets" type="sca:listOfQNames"
+ use="optional"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Service -->
+ <complexType name="Service">
+ <complexContent>
+ <extension base="sca:Contract">
+ <attribute name="promote" type="anyURI" use="required"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Interface -->
+ <element name="interface" type="sca:Interface" abstract="true"/>
+ <complexType name="Interface" abstract="true">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <attribute name="remotable" type="boolean" use="optional"/>
+ <attribute name="requires" type="sca:listOfQNames"
+ use="optional"/>
+ <attribute name="policySets" type="sca:listOfQNames"
+ use="optional"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Reference -->
+ <complexType name="Reference">
+ <complexContent>
+ <extension base="sca:Contract">
+ <attribute name="autowire" type="boolean" use="optional"/>
+ <attribute name="target" type="sca:listOfAnyURIs"
+ use="optional"/>
+ <attribute name="wiredByImpl" type="boolean" use="optional"
+ default="false"/>
+ <attribute name="multiplicity" type="sca:Multiplicity"
+ use="optional" default="1..1"/>
+ <attribute name="promote" type="sca:listOfAnyURIs"
+ use="required"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Property -->
+ <complexType name="SCAPropertyBase" mixed="true">
+ <sequence>
+ <any namespace="##any" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <!-- NOT an extension point; This any exists to accept
+ the element-based or complex type property
+ i.e. no element-based extension point under "sca:property" -->
+ </sequence>
+ <!-- mixed="true" to handle simple type -->
+ <attribute name="requires" type="sca:listOfQNames" use="optional"/>
+ <attribute name="policySets" type="sca:listOfQNames" use="optional"/>
+ </complexType>
+
+ <complexType name="Property" mixed="true">
+ <complexContent mixed="true">
+ <extension base="sca:SCAPropertyBase">
+ <attribute name="name" type="NCName" use="required"/>
+ <attribute name="type" type="QName" use="optional"/>
+ <attribute name="element" type="QName" use="optional"/>
+ <attribute name="many" type="boolean" use="optional"
+ default="false"/>
+ <attribute name="mustSupply" type="boolean" use="optional"
+ default="false"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </extension>
+ <!-- extension defines the place to hold default value -->
+ <!-- an extension point ; attribute-based only -->
+ </complexContent>
+ </complexType>
+
+ <!-- ConstrainingProperty is equivalent to the Property type but removes
+ the capability to contain a value -->
+ <complexType name="ConstrainingProperty" mixed="true">
+ <complexContent mixed="true">
+ <restriction base="sca:Property">
+ <attribute name="name" type="NCName" use="required"/>
+ <attribute name="type" type="QName" use="optional"/>
+ <attribute name="element" type="QName" use="optional"/>
+ <attribute name="many" type="boolean" use="optional"
+ default="false"/>
+ <attribute name="mustSupply" type="boolean" use="optional"
+ default="false"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </restriction>
+ </complexContent>
+ </complexType>
+
+ <complexType name="PropertyValue" mixed="true">
+ <complexContent mixed="true">
+ <extension base="sca:SCAPropertyBase">
+ <attribute name="name" type="NCName" use="required"/>
+ <attribute name="type" type="QName" use="optional"/>
+ <attribute name="element" type="QName" use="optional"/>
+ <attribute name="many" type="boolean" use="optional"
+ default="false"/>
+ <attribute name="source" type="string" use="optional"/>
+ <attribute name="file" type="anyURI" use="optional"/>
+ <attribute name="value" type="string" use="optional"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </extension>
+ <!-- an extension point ; attribute-based only -->
+ </complexContent>
+ </complexType>
+
+ <!-- Binding -->
+ <element name="binding" type="sca:Binding" abstract="true"/>
+ <complexType name="Binding" abstract="true">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <sequence>
+ <element ref="sca:wireFormat" minOccurs="0" maxOccurs="1" />
+ <element ref="sca:operationSelector" minOccurs="0"
+ maxOccurs="1" />
+ </sequence>
+ <attribute name="uri" type="anyURI" use="optional"/>
+ <attribute name="name" type="NCName" use="optional"/>
+ <attribute name="requires" type="sca:listOfQNames"
+ use="optional"/>
+ <attribute name="policySets" type="sca:listOfQNames"
+ use="optional"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Binding Type -->
+ <element name="bindingType" type="sca:BindingType"/>
+ <complexType name="BindingType">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="type" type="QName" use="required"/>
+ <attribute name="alwaysProvides" type="sca:listOfQNames"
+ use="optional"/>
+ <attribute name="mayProvide" type="sca:listOfQNames"
+ use="optional"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- WireFormat Type -->
+ <element name="wireFormat" type="sca:WireFormatType" abstract="true"/>
+ <complexType name="WireFormatType" abstract="true">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
+
+ <!-- OperationSelector Type -->
+ <element name="operationSelector" type="sca:OperationSelectorType" abstract="true"/>
+ <complexType name="OperationSelectorType" abstract="true">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
+
+ <!-- Callback -->
+ <element name="callback" type="sca:Callback"/>
+ <complexType name="Callback">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <choice minOccurs="0" maxOccurs="unbounded">
+ <element ref="sca:binding"/>
+ <any namespace="##other" processContents="lax"/>
+ </choice>
+ <attribute name="requires" type="sca:listOfQNames"
+ use="optional"/>
+ <attribute name="policySets" type="sca:listOfQNames"
+ use="optional"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Component -->
+ <complexType name="Component">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <sequence>
+ <!-- Set minOccurs="1" instead of "0" to workaround http://www.mail-archive.com/dev@tuscany.apache.org/msg08924.html. -->
+ <element ref="sca:implementation" minOccurs="1"/>
+ <choice minOccurs="0" maxOccurs="unbounded">
+ <element name="service" type="sca:ComponentService"/>
+ <element name="reference" type="sca:ComponentReference"/>
+ <element name="property" type="sca:PropertyValue"/>
+ </choice>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="name" type="NCName" use="required"/>
+ <attribute name="autowire" type="boolean" use="optional"/>
+ <attribute name="constrainingType" type="QName" use="optional"/>
+ <attribute name="requires" type="sca:listOfQNames"
+ use="optional"/>
+ <attribute name="policySets" type="sca:listOfQNames"
+ use="optional"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Component Service -->
+ <complexType name="ComponentService">
+ <complexContent>
+ <extension base="sca:Contract">
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Constraining Service -->
+ <complexType name="ConstrainingService">
+ <complexContent>
+ <restriction base="sca:ComponentService">
+ <sequence>
+ <element ref="sca:interface" minOccurs="0" maxOccurs="1" />
+ <element ref="sca:callback" minOccurs="0" maxOccurs="1" />
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="name" type="NCName" use="required" />
+ </restriction>
+ </complexContent>
+ </complexType>
+
+
+ <!-- Component Reference -->
+ <complexType name="ComponentReference">
+ <complexContent>
+ <extension base="sca:Contract">
+ <attribute name="autowire" type="boolean" use="optional"/>
+ <attribute name="target" type="sca:listOfAnyURIs"
+ use="optional"/>
+ <attribute name="wiredByImpl" type="boolean" use="optional"
+ default="false"/>
+ <attribute name="multiplicity" type="sca:Multiplicity"
+ use="optional" default="1..1"/>
+ <attribute name="nonOverridable" type="boolean" use="optional"
+ default="false"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Constraining Reference -->
+ <complexType name="ConstrainingReference">
+ <complexContent>
+ <restriction base="sca:ComponentReference">
+ <sequence>
+ <element ref="sca:interface" minOccurs="0" maxOccurs="1" />
+ <element ref="sca:callback" minOccurs="0" maxOccurs="1" />
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="name" type="NCName" use="required" />
+ <attribute name="autowire" type="boolean" use="optional"/>
+ <attribute name="wiredByImpl" type="boolean" use="optional"
+ default="false"/>
+ <attribute name="multiplicity" type="sca:Multiplicity"
+ use="optional" default="1..1"/>
+ </restriction>
+ </complexContent>
+ </complexType>
+
+ <!-- Component Type Reference -->
+ <complexType name="ComponentTypeReference">
+ <complexContent>
+ <restriction base="sca:ComponentReference">
+ <sequence>
+ <element ref="sca:documentation" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <element ref="sca:interface" minOccurs="0"/>
+ <element ref="sca:binding" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <element ref="sca:callback" minOccurs="0"/>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="name" type="NCName" use="required"/>
+ <attribute name="autowire" type="boolean" use="optional"/>
+ <attribute name="wiredByImpl" type="boolean" use="optional"
+ default="false"/>
+ <attribute name="multiplicity" type="sca:Multiplicity"
+ use="optional" default="1..1"/>
+ <attribute name="requires" type="sca:listOfQNames"
+ use="optional"/>
+ <attribute name="policySets" type="sca:listOfQNames"
+ use="optional"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </restriction>
+ </complexContent>
+ </complexType>
+
+
+ <!-- Implementation -->
+ <element name="implementation" type="sca:Implementation" abstract="true"/>
+ <complexType name="Implementation" abstract="true">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <attribute name="requires" type="sca:listOfQNames"
+ use="optional"/>
+ <attribute name="policySets" type="sca:listOfQNames"
+ use="optional"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Implementation Type -->
+ <element name="implementationType" type="sca:ImplementationType"/>
+ <complexType name="ImplementationType">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="type" type="QName" use="required"/>
+ <attribute name="alwaysProvides" type="sca:listOfQNames"
+ use="optional"/>
+ <attribute name="mayProvide" type="sca:listOfQNames"
+ use="optional"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Wire -->
+ <complexType name="Wire">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="source" type="anyURI" use="required"/>
+ <attribute name="target" type="anyURI" use="required"/>
+ <attribute name="replace" type="boolean" use="optional"
+ default="false"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Include -->
+ <element name="include" type="sca:Include"/>
+ <complexType name="Include">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <attribute name="name" type="QName"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Constraining Type -->
+ <element name="constrainingType" type="sca:ConstrainingType"/>
+ <complexType name="ConstrainingType">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <sequence>
+ <choice minOccurs="0" maxOccurs="unbounded">
+ <element name="service" type="sca:ConstrainingService"/>
+ <element name="reference"
+ type="sca:ConstrainingReference"/>
+ <element name="property" type="sca:ConstrainingProperty"/>
+ </choice>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="name" type="NCName" use="required"/>
+ <attribute name="targetNamespace" type="anyURI"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Intents within WSDL documents -->
+ <attribute name="requires" type="sca:listOfQNames"/>
+
+ <!-- Global attribute definition for @callback to mark a WSDL port type
+ as having a callback interface defined in terms of a second port
+ type. -->
+ <attribute name="callback" type="anyURI"/>
+
+ <!-- Value type definition for property values -->
+ <element name="value" type="sca:ValueType"/>
+ <complexType name="ValueType" mixed="true">
+ <sequence>
+ <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs='unbounded'/>
+ </sequence>
+ <!-- mixed="true" to handle simple type -->
+ <anyAttribute namespace="##any" processContents="lax"/>
+ </complexType>
+
+ <!-- Miscellaneous simple type definitions -->
+ <simpleType name="Multiplicity">
+ <restriction base="string">
+ <enumeration value="0..1"/>
+ <enumeration value="1..1"/>
+ <enumeration value="0..n"/>
+ <enumeration value="1..n"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="OverrideOptions">
+ <restriction base="string">
+ <enumeration value="no"/>
+ <enumeration value="may"/>
+ <enumeration value="must"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="listOfQNames">
+ <list itemType="QName"/>
+ </simpleType>
+
+ <simpleType name="listOfAnyURIs">
+ <list itemType="anyURI"/>
+ </simpleType>
+
+ <simpleType name="CreateResource">
+ <restriction base="string">
+ <enumeration value="always" />
+ <enumeration value="never" />
+ <enumeration value="ifnotexist" />
+ </restriction>
+ </simpleType>
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-definitions-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-definitions-1.1-cd04.xsd
new file mode 100644
index 0000000000..ef22e1dd3e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-definitions-1.1-cd04.xsd
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd"/>
+ <include schemaLocation="sca-policy-1.1-cd04.xsd"/>
+
+ <!-- Definitions -->
+ <element name="definitions" type="sca:tDefinitions"/>
+ <complexType name="tDefinitions">
+ <complexContent>
+ <extension base="sca:CommonExtensionBase">
+ <choice minOccurs="0" maxOccurs="unbounded">
+ <element ref="sca:intent"/>
+ <element ref="sca:policySet"/>
+ <element ref="sca:binding"/>
+ <element ref="sca:bindingType"/>
+ <element ref="sca:implementationType"/>
+ <any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </choice>
+ <attribute name="targetNamespace" type="anyURI" use="required"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-bpel-1.1-cd03.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-bpel-1.1-cd03.xsd
new file mode 100644
index 0000000000..0d5b747253
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-bpel-1.1-cd03.xsd
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified">
+
+ <!-- SCA-Assembly XML Schema -->
+ <include schemaLocation="sca-core-1.1-cd04.xsd" />
+
+ <!-- SCA-BPEL Component Implementation Type -->
+ <element name="implementation.bpel"
+ type="sca:BPELImplementation" substitutionGroup="sca:implementation" />
+
+ <complexType name="BPELImplementation">
+ <complexContent>
+ <extension base="sca:Implementation">
+ <sequence>
+ <any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="process" type="QName" use="required" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </extension>
+ </complexContent>
+ </complexType>
+
+</schema>
+
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-c-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-c-1.1-cd04.xsd
new file mode 100644
index 0000000000..e408f727f8
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-c-1.1-cd04.xsd
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2007,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd" />
+
+ <element name="implementation.c" type="sca:CImplementation"
+ substitutionGroup="sca:implementation" />
+
+ <complexType name="CImplementation">
+ <complexContent>
+ <extension base="sca:Implementation">
+ <sequence>
+ <element name="operation"
+ type="sca:CImplementationFunction" minOccurs="0"
+ maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="module" type="NCName" use="required" />
+ <attribute name="path" type="string" use="optional" />
+ <attribute name="library" type="boolean" use="optional" />
+ <attribute name="componentType" type="string" use="required" />
+ <attribute name="scope" type="sca:CImplementationScope"
+ use="optional" />
+ <attribute name="eagerInit" type="boolean"
+ use="optional" />
+ <attribute name="init" type="boolean" use="optional" />
+ <attribute name="destoy" type="boolean" use="optional" />
+ <attribute name="allowsPassByReference" type="boolean"
+ use="optional" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <simpleType name="CImplementationScope">
+ <restriction base="string">
+ <enumeration value="stateless" />
+ <enumeration value="composite" />
+ </restriction>
+ </simpleType>
+
+ <complexType name="CImplementationFunction">
+ <attribute name="name" type="NCName" use="required" />
+ <attribute name="allowsPassByReference" type="boolean"
+ use="optional" />
+ <attribute name="init" type="boolean" use="optional" />
+ <attribute name="destoy" type="boolean" use="optional" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-composite-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-composite-1.1-cd04.xsd
new file mode 100644
index 0000000000..c0517b0a32
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-composite-1.1-cd04.xsd
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd"/>
+
+ <!-- Composite Implementation -->
+ <element name="implementation.composite" type="sca:SCAImplementation"
+ substitutionGroup="sca:implementation"/>
+ <complexType name="SCAImplementation">
+ <complexContent>
+ <extension base="sca:Implementation">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="name" type="QName" use="required"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-cpp-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-cpp-1.1-cd04.xsd
new file mode 100644
index 0000000000..b71eda300d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-cpp-1.1-cd04.xsd
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2006,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd" />
+
+ <element name="implementation.cpp" type="sca:CPPImplementation"
+ substitutionGroup="sca:implementation" />
+ <complexType name="CPPImplementation">
+ <complexContent>
+ <extension base="sca:Implementation">
+ <sequence>
+ <element name="function"
+ type="sca:CPPImplementationFunction" minOccurs="0"
+ maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="library" type="NCName" use="required" />
+ <attribute name="header" type="NCName" use="required" />
+ <attribute name="path" type="string" use="optional" />
+ <attribute name="class" type="Name" use="optional" />
+ <attribute name="componentType" type="string"
+ use="optional" />
+ <attribute name="scope"
+ type="sca:CPPImplementationScope" use="optional" />
+ <attribute name="eagerInit" type="boolean"
+ use="optional" />
+ <attribute name="allowsPassByReference" type="boolean"
+ use="optional" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <simpleType name="CPPImplementationScope">
+ <restriction base="string">
+ <enumeration value="stateless" />
+ <enumeration value="composite" />
+ </restriction>
+ </simpleType>
+
+ <complexType name="CPPImplementationFunction">
+ <attribute name="name" type="NCName" use="required" />
+ <attribute name="allowsPassByReference" type="boolean"
+ use="optional" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-java-1.1-cd03.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-java-1.1-cd03.xsd
new file mode 100644
index 0000000000..aac845ff59
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-java-1.1-cd03.xsd
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd"/>
+
+ <!-- Java Implementation -->
+ <element name="implementation.java" type="sca:JavaImplementation"
+ substitutionGroup="sca:implementation"/>
+ <complexType name="JavaImplementation">
+ <complexContent>
+ <extension base="sca:Implementation">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="class" type="NCName" use="required"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-spring-1.1-cd01.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-spring-1.1-cd01.xsd
new file mode 100644
index 0000000000..cce7738dff
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-implementation-spring-1.1-cd01.xsd
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd"/>
+ <element name="implementation.spring" type="sca:SpringImplementation" substitutionGroup="sca:implementation"/>
+ <complexType name="SpringImplementation">
+ <complexContent>
+ <extension base="sca:Implementation">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="location" type="anyURI" use="required"/>
+ </extension>
+ </complexContent>
+ </complexType>
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-interface-c-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-interface-c-1.1-cd04.xsd
new file mode 100644
index 0000000000..d5bff5d542
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-interface-c-1.1-cd04.xsd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2007,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd" />
+
+ <element name="interface.c" type="sca:CInterface"
+ substitutionGroup="sca:interface" />
+
+ <complexType name="CInterface">
+ <complexContent>
+ <extension base="sca:Interface">
+ <sequence>
+ <element name="function" type="sca:CFunction"
+ minOccurs="0" maxOccurs="unbounded" />
+ <element name="callbackFunction"
+ type="sca:CFunction" minOccurs="0" maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="header" type="string" use="required" />
+ <attribute name="callbackHeader" type="string"
+ use="optional" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="CFunction">
+ <attribute name="name" type="NCName" use="required" />
+ <attribute name="requires" type="sca:listOfQNames"
+ use="optional" />
+ <attribute name="oneWay" type="boolean" use="optional" />
+ <attribute name="input" type="NCName" use="optional" />
+ <attribute name="output" type="NCName" use="optional" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-interface-cpp-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-interface-cpp-1.1-cd04.xsd
new file mode 100644
index 0000000000..e3e3c9369e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-interface-cpp-1.1-cd04.xsd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2006,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd" />
+
+ <element name="interface.cpp" type="sca:CPPInterface"
+ substitutionGroup="sca:interface" />
+
+ <complexType name="CPPInterface">
+ <complexContent>
+ <extension base="sca:Interface">
+ <sequence>
+ <element name="function" type="sca:CPPFunction"
+ minOccurs="0" maxOccurs="unbounded" />
+ <element name="callbackFunction"
+ type="sca:CPPFunction" minOccurs="0" maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="header" type="string" use="required" />
+ <attribute name="class" type="Name" use="required" />
+ <attribute name="callbackHeader" type="string"
+ use="optional" />
+ <attribute name="callbackClass" type="Name"
+ use="optional" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="CPPFunction">
+ <attribute name="name" type="NCName" use="required" />
+ <attribute name="requires" type="sca:listOfQNames"
+ use="optional" />
+ <attribute name="oneWay" type="boolean" use="optional" />
+ <anyAttribute namespace="##other" processContents="lax" />
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-interface-java-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-interface-java-1.1-cd04.xsd
new file mode 100644
index 0000000000..7d3a536b8c
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-interface-java-1.1-cd04.xsd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd"/>
+
+ <!-- Java Interface -->
+ <element name="interface.java" type="sca:JavaInterface"
+ substitutionGroup="sca:interface"/>
+ <complexType name="JavaInterface">
+ <complexContent>
+ <extension base="sca:Interface">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="interface" type="NCName" use="required"/>
+ <attribute name="callbackInterface" type="NCName"
+ use="optional"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-interface-wsdl-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-interface-wsdl-1.1-cd04.xsd
new file mode 100644
index 0000000000..3f0be7dc6d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-interface-wsdl-1.1-cd04.xsd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd"/>
+
+ <!-- WSDL Interface -->
+ <element name="interface.wsdl" type="sca:WSDLPortType"
+ substitutionGroup="sca:interface"/>
+ <complexType name="WSDLPortType">
+ <complexContent>
+ <extension base="sca:Interface">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="interface" type="anyURI" use="required"/>
+ <attribute name="callbackInterface" type="anyURI"
+ use="optional"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-jee-1.1-wd03.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-jee-1.1-wd03.xsd
new file mode 100644
index 0000000000..18daa8c926
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-jee-1.1-wd03.xsd
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved. OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd"/>
+
+ <element name="implementation.ejb" type="sca:EJBImplementation"
+ substitutionGroup="sca:implementation"/>
+ <complexType name="EJBImplementation">
+ <complexContent>
+ <extension base="sca:Implementation">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="ejb-link" type="string" use="required"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </extension>
+ </complexContent>
+ </complexType>
+ <element name="implementation.web" type="sca:WebImplementation"
+ substitutionGroup="sca:implementation"/>
+ <complexType name="WebImplementation">
+ <complexContent>
+ <extension base="sca:Implementation">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="web-uri" type="string" use="required"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </extension>
+ </complexContent>
+ </complexType>
+ <element name="implementation.jee" type="sca:JEEImplementation"
+ substitutionGroup="sca:implementation"/>
+ <complexType name="JEEImplementation">
+ <complexContent>
+ <extension base="sca:Implementation">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="archive" type="string" use="required"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </extension>
+ </complexContent>
+ </complexType>
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/sca-policy-1.1-cd04.xsd b/sca-cpp/branches/gcc-4.4/xsd/sca-policy-1.1-cd04.xsd
new file mode 100644
index 0000000000..372e8c24b3
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/sca-policy-1.1-cd04.xsd
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2009. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
+ elementFormDefault="qualified">
+
+ <include schemaLocation="sca-core-1.1-cd04.xsd"/>
+ <import namespace="http://www.w3.org/ns/ws-policy"
+ schemaLocation="http://www.w3.org/2007/02/ws-policy.xsd"/>
+
+ <element name="intent" type="sca:Intent"/>
+ <complexType name="Intent">
+ <sequence>
+ <element name="description" type="string" minOccurs="0"
+ maxOccurs="1" />
+ <element name="qualifier" type="sca:IntentQualifier"
+ minOccurs="0" maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="name" type="NCName" use="required"/>
+ <attribute name="constrains" type="sca:listOfQNames"
+ use="optional"/>
+ <attribute name="requires" type="sca:listOfQNames"
+ use="optional"/>
+ <attribute name="excludes" type="sca:listOfQNames"
+ use="optional"/>
+ <attribute name="mutuallyExclusive" type="boolean"
+ use="optional" default="false"/>
+ <attribute name="intentType"
+ type="sca:InteractionOrImplementation"
+ use="optional" default="interaction"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
+
+ <complexType name="IntentQualifier">
+ <sequence>
+ <element name="description" type="string" minOccurs="0"
+ maxOccurs="1" />
+ </sequence>
+ <attribute name="name" type="NCName" use="required"/>
+ <attribute name="default" type="boolean" use="optional"
+ default="false"/>
+ </complexType>
+
+ <element name="policySet" type="sca:PolicySet"/>
+ <complexType name="PolicySet">
+ <choice minOccurs="0" maxOccurs="unbounded">
+ <element name="policySetReference"
+ type="sca:PolicySetReference"/>
+ <element name="intentMap" type="sca:IntentMap"/>
+ <any namespace="##other" processContents="lax"/>
+ </choice>
+ <attribute name="name" type="NCName" use="required"/>
+ <attribute name="provides" type="sca:listOfQNames"/>
+ <attribute name="appliesTo" type="string" use="optional"/>
+ <attribute name="attachTo" type="string" use="optional"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
+
+ <element name="policySetAttachment"
+ type="sca:PolicySetAttachment"/>
+ <complexType name="PolicySetAttachment">
+ <attribute name="name" type="QName" use="required"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
+
+ <complexType name="PolicySetReference">
+ <attribute name="name" type="QName" use="required"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
+
+ <complexType name="IntentMap">
+ <choice minOccurs="1" maxOccurs="unbounded">
+ <element name="qualifier" type="sca:Qualifier"/>
+ <any namespace="##other" processContents="lax"/>
+ </choice>
+ <attribute name="provides" type="QName" use="required"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
+
+ <complexType name="Qualifier">
+ <sequence minOccurs="0" maxOccurs="unbounded">
+ <any namespace="##other" processContents="lax"/>
+ </sequence>
+ <attribute name="name" type="string" use="required"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
+
+ <simpleType name="listOfNCNames">
+ <list itemType="NCName"/>
+ </simpleType>
+
+ <simpleType name="InteractionOrImplementation">
+ <restriction base="string">
+ <enumeration value="interaction"/>
+ <enumeration value="implementation"/>
+ </restriction>
+ </simpleType>
+
+</schema> \ No newline at end of file
diff --git a/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-dwr.xsd b/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-dwr.xsd
new file mode 100644
index 0000000000..a41087d6ec
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-dwr.xsd
@@ -0,0 +1,41 @@
+<?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.
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/1.1"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ elementFormDefault="qualified">
+
+ <import namespace="http://docs.oasis-open.org/ns/opencsa/sca/200912" schemaLocation="sca-1.1-cd04.xsd"/>
+
+ <element name="binding.dwr" type="t:DWRBinding"/>
+
+ <complexType name="DWRBinding">
+ <complexContent>
+ <extension base="sca:Binding">
+ <sequence>
+ <any namespace="##targetNamespace" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <anyAttribute namespace="##any" processContents="lax"/>
+ </extension>
+ </complexContent>
+ </complexType>
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-http.xsd b/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-http.xsd
new file mode 100644
index 0000000000..ff0ecd1414
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-http.xsd
@@ -0,0 +1,41 @@
+<?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.
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/1.1"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ elementFormDefault="qualified">
+
+ <import namespace="http://docs.oasis-open.org/ns/opencsa/sca/200912" schemaLocation="sca-1.1-cd04.xsd"/>
+
+ <element name="binding.http" type="t:HTTPBinding"/>
+
+ <complexType name="HTTPBinding">
+ <complexContent>
+ <extension base="sca:Binding">
+ <sequence>
+ <any namespace="##targetNamespace" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <anyAttribute namespace="##any" processContents="lax"/>
+ </extension>
+ </complexContent>
+ </complexType>
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-jsonrpc.xsd b/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-jsonrpc.xsd
new file mode 100644
index 0000000000..2fb4587862
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-jsonrpc.xsd
@@ -0,0 +1,41 @@
+<?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.
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/1.1"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ elementFormDefault="qualified">
+
+ <import namespace="http://docs.oasis-open.org/ns/opencsa/sca/200912" schemaLocation="sca-1.1-cd04.xsd"/>
+
+ <element name="binding.jsonrpc" type="t:JSONRPCBinding"/>
+
+ <complexType name="JSONRPCBinding">
+ <complexContent>
+ <extension base="sca:Binding">
+ <sequence>
+ <any namespace="##targetNamespace" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <anyAttribute namespace="##any" processContents="lax"/>
+ </extension>
+ </complexContent>
+ </complexType>
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-rmi.xsd b/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-rmi.xsd
new file mode 100644
index 0000000000..a3477c4a34
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-binding-rmi.xsd
@@ -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.
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/1.1"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ elementFormDefault="qualified">
+
+ <import namespace="http://docs.oasis-open.org/ns/opencsa/sca/200912" schemaLocation="sca-1.1-cd04.xsd"/>
+
+ <element name="binding.rmi" type="t:RMIBinding"/>
+
+ <complexType name="RMIBinding">
+ <complexContent>
+ <extension base="sca:Binding">
+ <sequence>
+ <any namespace="##targetNamespace" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-implementation-osgi.xsd b/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-implementation-osgi.xsd
new file mode 100644
index 0000000000..ab445dfe9e
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-implementation-osgi.xsd
@@ -0,0 +1,53 @@
+<?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.
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/1.1"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ elementFormDefault="qualified">
+
+ <import namespace="http://docs.oasis-open.org/ns/opencsa/sca/200912" schemaLocation="sca-1.1-cd04.xsd"/>
+
+ <element name="implementation.osgi" type="t:OSGiImplementation" substitutionGroup="sca:implementation"/>
+
+ <complexType name="OSGiImplementation">
+ <complexContent>
+ <extension base="sca:Implementation">
+ <sequence>
+ <any namespace="##targetNamespace" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="bundleSymbolicName" type="string" use="required"/>
+ <attribute name="bundleVersion" type="string" use="optional"/>
+ <anyAttribute namespace="##any" processContents="lax"/>
+ </extension>
+ </complexContent>
+ </complexType>
+ <element name="osgi.property" type="t:OSGiProperty"/>
+ <complexType name="OSGiProperty">
+ <simpleContent>
+ <extension base="string">
+ <attribute name="name" type="NCName" use="required"/>
+ <attribute name="value" type="string" use="optional"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-implementation-widget.xsd b/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-implementation-widget.xsd
new file mode 100644
index 0000000000..21d6fa377d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1-implementation-widget.xsd
@@ -0,0 +1,42 @@
+<?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.
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/1.1"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ elementFormDefault="qualified">
+
+ <import namespace="http://docs.oasis-open.org/ns/opencsa/sca/200912" schemaLocation="sca-1.1-cd04.xsd"/>
+
+ <element name="implementation.widget" type="t:WidgetImplementation" substitutionGroup="sca:implementation"/>
+
+ <complexType name="WidgetImplementation">
+ <complexContent>
+ <extension base="sca:Implementation">
+ <sequence>
+ <any namespace="##targetNamespace" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="location" type="anyURI" use="required"/>
+ <anyAttribute namespace="##any" processContents="lax"/>
+ </extension>
+ </complexContent>
+ </complexType>
+</schema>
diff --git a/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1.xsd b/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1.xsd
new file mode 100644
index 0000000000..4a1a1e000d
--- /dev/null
+++ b/sca-cpp/branches/gcc-4.4/xsd/tuscany-sca-1.1.xsd
@@ -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.
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/1.1">
+
+<!--
+ <import namespace="http://www.w3.org/ns/wsdl-instance" schemaLocation="wsdli.xsd"/>
+-->
+ <import namespace="http://docs.oasis-open.org/ns/opencsa/sca/200912" schemaLocation="sca-1.1-cd04.xsd"/>
+
+ <include schemaLocation="tuscany-sca-1.1-binding-dwr.xsd"/>
+ <include schemaLocation="tuscany-sca-1.1-binding-http.xsd"/>
+ <include schemaLocation="tuscany-sca-1.1-binding-jsonrpc.xsd"/>
+ <include schemaLocation="tuscany-sca-1.1-binding-rmi.xsd"/>
+
+ <include schemaLocation="tuscany-sca-1.1-implementation-osgi.xsd"/>
+ <include schemaLocation="tuscany-sca-1.1-implementation-widget.xsd"/>
+</schema> \ No newline at end of file