Minor improvements to java component support, use one classloader per component, use Iterables instead of arrays to represent lists, added more tests and a working java version of the store integration test.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@902539 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
aff8757990
commit
1c21d758af
27 changed files with 980 additions and 74 deletions
|
@ -61,6 +61,7 @@ doxygen
|
|||
*.pyc
|
||||
*.class
|
||||
*.stamp
|
||||
*.jar
|
||||
|
||||
# Specific ignores
|
||||
kernel-test
|
||||
|
|
|
@ -38,6 +38,15 @@ java_shell_LDFLAGS = -L${JAVA_LIB} -R${JAVA_LIB} -R${JAVA_LIB}/server -ljava
|
|||
|
||||
noinst_JAVA = org/apache/tuscany/*.java test/*.java
|
||||
|
||||
jarfile = libmod-tuscany-java-${PACKAGE_VERSION}.jar
|
||||
jardir = ${libdir}
|
||||
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
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ const value evalDriverLoop(const JavaRuntime& jr, const JavaClass jc, istream& i
|
|||
|
||||
const bool evalDriverRun(const char* name, istream& in, ostream& out) {
|
||||
scheme::setupDisplay(out);
|
||||
const failable<JavaClass> jc = readClass(javaRuntime, name);
|
||||
const failable<JavaClass> jc = readClass(javaRuntime, ".", name);
|
||||
if (!hasContent(jc))
|
||||
return true;
|
||||
evalDriverLoop(javaRuntime, content(jc), in, out);
|
||||
|
|
|
@ -52,31 +52,45 @@ public:
|
|||
JavaVMInitArgs args;
|
||||
args.version = JNI_VERSION_1_6;
|
||||
args.ignoreUnrecognized = JNI_FALSE;
|
||||
JavaVMOption options[1];
|
||||
options[0].optionString = const_cast<char*>("-Djava.class.path=.");
|
||||
JavaVMOption options[3];
|
||||
args.options = options;
|
||||
args.nOptions = 1;
|
||||
JNI_CreateJavaVM(&jvm, (void**)&env, &args);
|
||||
args.nOptions = 0;
|
||||
|
||||
// Register our native invocation handler function
|
||||
invokerClass = env->FindClass("org/apache/tuscany/InvocationHandler");
|
||||
JNINativeMethod nm;
|
||||
nm.name = const_cast<char*>("invoke");
|
||||
nm.signature = const_cast<char*>("(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
|
||||
nm.fnPtr = (void*)nativeInvoke;
|
||||
env->RegisterNatives(invokerClass, &nm, 1);
|
||||
// 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));
|
||||
|
||||
#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);
|
||||
} 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));
|
||||
}
|
||||
}
|
||||
|
||||
// Create the JVM
|
||||
JNI_CreateJavaVM(&jvm, (void**)&env, &args);
|
||||
|
||||
} else {
|
||||
|
||||
// Just hook to existing JVM
|
||||
// Just point to existing JVM
|
||||
jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
|
||||
invokerClass = env->FindClass("org/apache/tuscany/InvocationHandler");
|
||||
}
|
||||
|
||||
// Capture JVM standard IO
|
||||
setupIO();
|
||||
|
||||
// Lookup the classes and methods we need
|
||||
// Lookup System classes and methods
|
||||
classClass = env->FindClass("java/lang/Class");
|
||||
methodClass = env->FindClass("java/lang/reflect/Method");
|
||||
objectClass = env->FindClass("java/lang/Object");
|
||||
|
@ -84,6 +98,8 @@ public:
|
|||
booleanClass = env->FindClass("java/lang/Boolean");
|
||||
stringClass = env->FindClass("java/lang/String");
|
||||
objectArrayClass = env->FindClass("[Ljava/lang/Object;");
|
||||
iterableClass = env->FindClass("Ljava/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;");
|
||||
|
@ -91,8 +107,27 @@ public:
|
|||
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;");
|
||||
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;");
|
||||
|
||||
// Register our native invocation handler function
|
||||
JNINativeMethod nm;
|
||||
nm.name = const_cast<char*>("invoke");
|
||||
nm.signature = const_cast<char*>("(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
|
||||
nm.fnPtr = (void*)nativeInvoke;
|
||||
env->RegisterNatives(invokerClass, &nm, 1);
|
||||
|
||||
}
|
||||
|
||||
JavaVM* jvm;
|
||||
|
@ -105,6 +140,7 @@ public:
|
|||
jclass booleanClass;
|
||||
jclass stringClass;
|
||||
jclass objectArrayClass;
|
||||
jclass iterableClass;
|
||||
jmethodID doubleValueOf;
|
||||
jmethodID doubleValue;
|
||||
jmethodID booleanValueOf;
|
||||
|
@ -112,10 +148,18 @@ public:
|
|||
jmethodID declaredMethods;
|
||||
jmethodID methodName;
|
||||
jmethodID parameterTypes;
|
||||
|
||||
jmethodID classForName;
|
||||
jclass loaderClass;
|
||||
jmethodID loaderValueOf;
|
||||
jmethodID loaderForName;
|
||||
jclass invokerClass;
|
||||
jmethodID invokerValueOf;
|
||||
jfieldID invokerLambda;
|
||||
jclass iterableUtilClass;
|
||||
jmethodID iterableValueOf;
|
||||
jmethodID iterableCar;
|
||||
jmethodID iterableCdr;
|
||||
jmethodID iterableIsNil;
|
||||
|
||||
} javaRuntime;
|
||||
|
||||
|
@ -137,6 +181,7 @@ const jobject valueToJobject(const JavaRuntime& jr, const value& jtype, const va
|
|||
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.
|
||||
|
@ -204,9 +249,11 @@ jobject JNICALL nativeInvoke(JNIEnv* env, jobject self, unused jobject proxy, jo
|
|||
|
||||
// Build the expression to evaluate
|
||||
const list<value> expr = 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);
|
||||
|
@ -237,13 +284,20 @@ const jobjectArray valuesToJarray(const JavaRuntime& jr, const list<value>& v) {
|
|||
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 valuesToJarray(jr, v);
|
||||
return jarrayToJiterable(jr, valuesToJarray(jr, v));
|
||||
case value::Lambda:
|
||||
return mkJavaLambda(jr, jtype, v);
|
||||
case value::Symbol:
|
||||
|
@ -253,7 +307,7 @@ const jobject valueToJobject(const JavaRuntime& jr, const value& jtype, const va
|
|||
case value::Number:
|
||||
return jr.env->CallStaticObjectMethod(jr.doubleClass, jr.doubleValueOf, (double)v);
|
||||
case value::Bool:
|
||||
return jr.env->CallStaticObjectMethod(jr.booleanClass, jr.booleanValueOf, (double)v);
|
||||
return jr.env->CallStaticObjectMethod(jr.booleanClass, jr.booleanValueOf, (bool)v);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
@ -291,6 +345,23 @@ const list<value> jarrayToValues(const JavaRuntime& jr, jobjectArray o) {
|
|||
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.
|
||||
*/
|
||||
|
@ -330,8 +401,8 @@ const value jobjectToValue(const JavaRuntime& jr, const jobject o) {
|
|||
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->IsSameObject(clazz, jr.objectArrayClass)))
|
||||
return jarrayToValues(jr, (jobjectArray)o);
|
||||
if ((jr.env->IsAssignableFrom(clazz, jr.iterableClass)))
|
||||
return jiterableToValues(jr, o);
|
||||
return lambda<value(const list<value>&)>(javaCallable(jr, o));
|
||||
}
|
||||
|
||||
|
@ -378,12 +449,12 @@ const list<value> methodsToValues(const JavaRuntime& jr, const jclass clazz) {
|
|||
*/
|
||||
class JavaClass {
|
||||
public:
|
||||
JavaClass() : clazz(NULL), obj(NULL) {
|
||||
}
|
||||
|
||||
JavaClass(const jclass clazz, const jobject obj, const list<value> m) : clazz(clazz), obj(obj), m(m) {
|
||||
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;
|
||||
|
@ -392,24 +463,34 @@ public:
|
|||
/**
|
||||
* Read a class.
|
||||
*/
|
||||
const failable<JavaClass> readClass(const JavaRuntime& jr, const string& name) {
|
||||
const string jname = jniClassName(name);
|
||||
const jclass clazz = jr.env->FindClass(c_str(jname));
|
||||
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(clazz, obj, methodsToValues(jr, clazz));
|
||||
|
||||
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);
|
||||
|
@ -426,7 +507,9 @@ const failable<value> evalClass(const JavaRuntime& jr, const value& expr, const
|
|||
return mkfailure<value>(string("Function call failed: ") + car<value>(expr) + " : " + lastException(jr));
|
||||
|
||||
// Convert Java result to a value
|
||||
return jobjectToValue(jr, result);
|
||||
const value v = jobjectToValue(jr, result);
|
||||
debug(v, "java::evalClass::result");
|
||||
return v;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,3 +24,4 @@ root=`readlink -f $1`
|
|||
cat >>$root/conf/httpd.conf <<EOF
|
||||
LoadModule mod_tuscany_eval $here/.libs/libmod_tuscany_java.so
|
||||
EOF
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace java {
|
|||
bool testEvalExpr() {
|
||||
gc_scoped_pool pool;
|
||||
{
|
||||
const failable<JavaClass> obj = readClass(javaRuntime, "test.CalcImpl");
|
||||
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));
|
||||
|
@ -42,13 +42,29 @@ bool testEvalExpr() {
|
|||
assert(content(r) == value(6));
|
||||
}
|
||||
{
|
||||
const failable<JavaClass> obj = readClass(javaRuntime, "test.AdderImpl");
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -61,7 +77,7 @@ const value add(const list<value>& args) {
|
|||
|
||||
bool testEvalLambda() {
|
||||
gc_scoped_pool pool;
|
||||
const failable<JavaClass> obj = readClass(javaRuntime, "test.CalcImpl");
|
||||
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));
|
||||
|
@ -70,14 +86,38 @@ bool testEvalLambda() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool testClassLoader() {
|
||||
gc_scoped_pool pool;
|
||||
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;
|
||||
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::testEvalExpr();
|
||||
tuscany::java::testEvalLambda();
|
||||
tuscany::java::testClassLoader();
|
||||
tuscany::java::testIterableUtil();
|
||||
|
||||
tuscany::cout << "OK" << tuscany::endl;
|
||||
return 0;
|
||||
|
|
|
@ -63,9 +63,9 @@ struct applyImplementation {
|
|||
* Evaluate a Java component implementation and convert it to an applicable
|
||||
* lambda function.
|
||||
*/
|
||||
const failable<lambda<value(const list<value>&)> > evalImplementation(unused const string& path, const value& impl, const list<value>& px) {
|
||||
const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) {
|
||||
const string cn(attributeValue("class", impl));
|
||||
const failable<java::JavaClass> jc = java::readClass(java::javaRuntime, cn);
|
||||
const failable<java::JavaClass> jc = java::readClass(java::javaRuntime, path, cn);
|
||||
if (!hasContent(jc))
|
||||
return mkfailure<lambda<value(const list<value>&)> >(reason(jc));
|
||||
return lambda<value(const list<value>&)>(applyImplementation(content(jc), px));
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
||||
package org.apache.tuscany;
|
||||
|
||||
import static org.apache.tuscany.ClassLoader.Test.*;
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
}
|
|
@ -22,14 +22,21 @@ package org.apache.tuscany;
|
|||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
public class InvocationHandler implements java.lang.reflect.InvocationHandler {
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
public static Object valueOf(final Class<?> iface, final long 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));
|
||||
}
|
||||
|
||||
|
|
379
sca-cpp/trunk/modules/java/org/apache/tuscany/IterableUtil.java
Normal file
379
sca-cpp/trunk/modules/java/org/apache/tuscany/IterableUtil.java
Normal file
|
@ -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.
|
||||
*/
|
||||
|
||||
package org.apache.tuscany;
|
||||
|
||||
import static java.util.Arrays.*;
|
||||
import static org.apache.tuscany.IterableUtil.Test.*;
|
||||
|
||||
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>() {
|
||||
@Override
|
||||
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() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return this.i < ArrayIterable.this.a.length;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T next() {
|
||||
return (T)ArrayIterable.this.a[this.i++];
|
||||
}
|
||||
|
||||
@Override
|
||||
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;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return this.i < ListIterable.this.l.size();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T next() {
|
||||
return (T)ListIterable.this.l.get(this.i++);
|
||||
}
|
||||
|
||||
@Override
|
||||
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();
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if(this.carIterator)
|
||||
return true;
|
||||
return this.cdrIterator.hasNext();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T next() {
|
||||
if(this.carIterator) {
|
||||
this.carIterator = false;
|
||||
return (T)PairIterable.this.car;
|
||||
}
|
||||
return (T)this.cdrIterator.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
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");
|
||||
}
|
||||
|
||||
}
|
|
@ -19,20 +19,45 @@
|
|||
|
||||
package org.apache.tuscany;
|
||||
|
||||
/**
|
||||
* Interface used to represent SCA component references providing both REST
|
||||
* access to a resource and function application.
|
||||
*/
|
||||
public interface Service {
|
||||
|
||||
String post(Object[] item);
|
||||
/**
|
||||
* Post a new item to a resource.
|
||||
*/
|
||||
String post(Iterable<?> item);
|
||||
|
||||
Object[] get(String id);
|
||||
/**
|
||||
* Return an item.
|
||||
*/
|
||||
Iterable<?> get(String id);
|
||||
|
||||
Object[] getall();
|
||||
/**
|
||||
* Return all items in the resource.
|
||||
*/
|
||||
Iterable<?> getall();
|
||||
|
||||
boolean put(String id, Object[] item);
|
||||
/**
|
||||
* Update am item.
|
||||
*/
|
||||
boolean put(String id, Iterable<?> item);
|
||||
|
||||
/**
|
||||
* Delete an item.
|
||||
*/
|
||||
boolean delete(String id);
|
||||
|
||||
/**
|
||||
* Delete all items in the resource.
|
||||
*/
|
||||
boolean deleteall();
|
||||
|
||||
/**
|
||||
* Apply a function.
|
||||
*/
|
||||
<T> T apply(Object... params);
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ SCAComposite domain-test.composite
|
|||
</Location>
|
||||
EOF
|
||||
|
||||
export CLASSPATH="`pwd`/libmod-tuscany-java-1.0.jar:`pwd`"
|
||||
|
||||
apachectl -k start -d `pwd`/tmp
|
||||
sleep 2
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
|
||||
package test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class CalcImpl {
|
||||
|
||||
public Double add(Double x, Double y, Adder adder) {
|
||||
|
@ -29,4 +32,15 @@ public class CalcImpl {
|
|||
return x * y;
|
||||
}
|
||||
|
||||
public Boolean even(Double x) {
|
||||
return (double)(((int)(double)x / 2) * 2) == (double)x;
|
||||
}
|
||||
|
||||
public Iterable<Double> square(Iterable<Double> l) {
|
||||
List r = new ArrayList();
|
||||
for (Double x: l)
|
||||
r.add(x * x);
|
||||
return r;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,13 +23,13 @@ public interface Client {
|
|||
|
||||
String echo(String x);
|
||||
|
||||
Object[] getall();
|
||||
Iterable<?> getall();
|
||||
|
||||
Object[] get(String id);
|
||||
Iterable<?> get(String id);
|
||||
|
||||
String post(Object[] item);
|
||||
String post(Iterable<?> item);
|
||||
|
||||
Boolean put(String id, Object[] entry);
|
||||
Boolean put(String id, Iterable<?> entry);
|
||||
|
||||
Boolean deleteall();
|
||||
|
||||
|
|
|
@ -25,19 +25,19 @@ public class ClientImpl {
|
|||
return server.echo(x);
|
||||
}
|
||||
|
||||
public Object[] getall(Server server) {
|
||||
public Iterable<?> getall(Server server) {
|
||||
return server.getall();
|
||||
}
|
||||
|
||||
public Object[] get(String id, Server server) {
|
||||
public Iterable<?> get(String id, Server server) {
|
||||
return server.get(id);
|
||||
}
|
||||
|
||||
public String post(Object[] item, Server server) {
|
||||
public String post(Iterable<?> item, Server server) {
|
||||
return server.post(item);
|
||||
}
|
||||
|
||||
public Boolean put(String id, Object[] item, Server server) {
|
||||
public Boolean put(String id, Iterable<?> item, Server server) {
|
||||
return server.put(id, item);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,13 +23,13 @@ public interface Server {
|
|||
|
||||
String echo(String x);
|
||||
|
||||
Object[] getall();
|
||||
Iterable<?> getall();
|
||||
|
||||
Object[] get(String id);
|
||||
Iterable<?> get(String id);
|
||||
|
||||
String post(Object[] item);
|
||||
String post(Iterable<?> item);
|
||||
|
||||
Boolean put(String id, Object[] entry);
|
||||
Boolean put(String id, Iterable<?> entry);
|
||||
|
||||
Boolean deleteall();
|
||||
|
||||
|
|
|
@ -19,33 +19,31 @@
|
|||
|
||||
package test;
|
||||
|
||||
import static org.apache.tuscany.IterableUtil.*;
|
||||
|
||||
public class ServerImpl {
|
||||
|
||||
Object[] list(Object... o) {
|
||||
return o;
|
||||
}
|
||||
|
||||
public String echo(String x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
public Object[] getall() {
|
||||
public Iterable<?> getall() {
|
||||
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))));
|
||||
list("Item", "333", list(list("'javaClass", "services.Item"), list("'name", "Pear"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 1.55))));
|
||||
}
|
||||
|
||||
public Object[] get(String id) {
|
||||
Object[] entry = list(list("'javaClass", "services.Item"), list("'name", "Apple"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 2.99));
|
||||
public Iterable<?> get(String id) {
|
||||
Iterable<?> entry = list(list("'javaClass", "services.Item"), list("'name", "Apple"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 2.99));
|
||||
return list("Item", id, entry);
|
||||
}
|
||||
|
||||
public String post(Object[] item) {
|
||||
public String post(Iterable<?> item) {
|
||||
return "123456789";
|
||||
}
|
||||
|
||||
public Boolean put(String id, Object[] entry) {
|
||||
public Boolean put(String id, Iterable<?> entry) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ SCAComposite domain-test.composite
|
|||
</Location>
|
||||
EOF
|
||||
|
||||
export CLASSPATH="`pwd`/libmod-tuscany-java-1.0.jar:`pwd`"
|
||||
|
||||
apachectl -k start -d `pwd`/tmp
|
||||
sleep 2
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace tuscany {
|
|||
namespace store {
|
||||
|
||||
/**
|
||||
* Returns a catalog.
|
||||
* Returns the catalog.
|
||||
*/
|
||||
struct convert {
|
||||
const lambda<value(const list<value>&)> converter;
|
||||
|
@ -61,6 +61,9 @@ const failable<value> get(const lambda<value(const list<value>&)> converter) {
|
|||
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) {
|
||||
return value(mklist<value>(string("Service.get")));
|
||||
}
|
||||
|
|
|
@ -15,6 +15,16 @@
|
|||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
JAVAROOT = ${top_builddir}/test/store-java
|
||||
|
||||
if WANT_JAVA
|
||||
|
||||
AM_JAVACFLAGS = -classpath ${top_builddir}/modules/java/libmod-tuscany-java-${PACKAGE_VERSION}.jar
|
||||
|
||||
noinst_JAVA = store/*.java
|
||||
|
||||
CLEANFILES = store/*.class
|
||||
|
||||
TESTS = server-test
|
||||
|
||||
endif
|
||||
|
|
|
@ -28,6 +28,8 @@ SCAComposite store.composite
|
|||
</Location>
|
||||
EOF
|
||||
|
||||
export CLASSPATH=`pwd`/../../modules/java/libmod-tuscany-java-1.0.jar:`pwd`
|
||||
|
||||
apachectl -k start -d `pwd`/tmp
|
||||
|
||||
mc="memcached -l 127.0.0.1 -m 4 -p 11211"
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
export CLASSPATH=`pwd`/../../modules/java/libmod-tuscany-java-1.0.jar:`pwd`
|
||||
|
||||
apachectl -k stop -d `pwd`/tmp
|
||||
mc="memcached -l 127.0.0.1 -m 4 -p 11211"
|
||||
kill `ps -f | grep -v grep | grep "$mc" | awk '{ print $2 }'`
|
||||
|
|
|
@ -22,16 +22,6 @@
|
|||
targetNamespace="http://store"
|
||||
name="store">
|
||||
|
||||
<component name="Store">
|
||||
<implementation.java class="store.StoreImpl"/>
|
||||
<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">
|
||||
<implementation.java class="store.FruitsCatalogImpl"/>
|
||||
<property name="currencyCode">USD</property>
|
||||
|
|
28
sca-cpp/trunk/test/store-java/store/CurrencyConverter.java
Normal file
28
sca-cpp/trunk/test/store-java/store/CurrencyConverter.java
Normal file
|
@ -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);
|
||||
|
||||
}
|
|
@ -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 "$";
|
||||
}
|
||||
|
||||
}
|
57
sca-cpp/trunk/test/store-java/store/FruitsCatalogImpl.java
Normal file
57
sca-cpp/trunk/test/store-java/store/FruitsCatalogImpl.java
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT 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.list;
|
||||
|
||||
/**
|
||||
* Catalog component implementation.
|
||||
*/
|
||||
public class FruitsCatalogImpl {
|
||||
|
||||
/**
|
||||
* Returns the catalog.
|
||||
*/
|
||||
public Iterable<?> get(final CurrencyConverter converter) {
|
||||
class Converter {
|
||||
Double convert(Double price) {
|
||||
return converter.convert("USD", "USD", price);
|
||||
}
|
||||
};
|
||||
Converter c = new Converter();
|
||||
|
||||
String code = "USD";
|
||||
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) {
|
||||
return list("Service.get");
|
||||
}
|
||||
|
||||
}
|
130
sca-cpp/trunk/test/store-java/store/ShoppingCartImpl.java
Normal file
130
sca-cpp/trunk/test/store-java/store/ShoppingCartImpl.java
Normal file
|
@ -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.
|
||||
*/
|
||||
|
||||
package store;
|
||||
|
||||
import org.apache.tuscany.Service;
|
||||
import java.lang.System;
|
||||
import java.util.UUID;
|
||||
import static org.apache.tuscany.IterableUtil.*;
|
||||
|
||||
/**
|
||||
* 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(String id, Service cache) {
|
||||
Iterable<?> cart = cache.get(id);
|
||||
if (cart == null)
|
||||
return list();
|
||||
return cart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a UUID.
|
||||
*/
|
||||
String uuid() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Post a new item to the cart. Create a new cart if necessary.
|
||||
*/
|
||||
public String post(Iterable<?> item, Service cache) {
|
||||
String id = uuid();
|
||||
Iterable<?> newItem = list(car(item), id, caddr(item));
|
||||
Iterable<?> cart = cons(newItem, getcart(cartId, cache));
|
||||
cache.put(cartId, cart);
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the contents of the cart.
|
||||
*/
|
||||
public Iterable<?> getall(Service cache) {
|
||||
return cons("Your Cart", cons(cartId, getcart(cartId, cache)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an item in the cart.
|
||||
*/
|
||||
public Iterable<?> find(String id, Iterable<?> cart) {
|
||||
if (isNil(cart))
|
||||
return cons("Item", list("0", list()));
|
||||
if (id.equals(cadr(car(cart))))
|
||||
return car(cart);
|
||||
return find(id, cdr(cart));
|
||||
}
|
||||
|
||||
public Iterable<?> get(String id, Service cache) {
|
||||
return find(id, getcart(cartId, cache));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the whole cart.
|
||||
*/
|
||||
public Boolean deleteall(Service cache) {
|
||||
return cache.delete(cartId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an item from the cart.
|
||||
*/
|
||||
public Boolean delete(String id, Service cache) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the price of an item.
|
||||
*/
|
||||
Double price(Iterable<?> item) {
|
||||
return Double.valueOf((String)cadr(assoc("'price", caddr(item))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sum the prices of a list of items.
|
||||
*/
|
||||
Double sum(Iterable<?> items) {
|
||||
if (isNil(items))
|
||||
return 0.0;
|
||||
return price((Iterable<?>)car(items)) + sum(cdr(items));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the total price of the items in the cart.
|
||||
*/
|
||||
public Double gettotal(Service cache) {
|
||||
Iterable<?> cart = getcart(cartId, cache);
|
||||
return sum(cart);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO remove this JSON-RPC specific function.
|
||||
*/
|
||||
public Iterable<?> listMethods(final CurrencyConverter converter) {
|
||||
return list("Service.gettotal");
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue