From 1c21d758af81d880ad6e045d18f8bc62ad8be89e Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Sun, 24 Jan 2010 09:27:44 +0000 Subject: 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 --- .../java/org/apache/tuscany/ClassLoader.java | 78 +++++ .../java/org/apache/tuscany/InvocationHandler.java | 11 +- .../java/org/apache/tuscany/IterableUtil.java | 379 +++++++++++++++++++++ .../modules/java/org/apache/tuscany/Service.java | 41 ++- 4 files changed, 499 insertions(+), 10 deletions(-) create mode 100644 sca-cpp/trunk/modules/java/org/apache/tuscany/ClassLoader.java create mode 100644 sca-cpp/trunk/modules/java/org/apache/tuscany/IterableUtil.java (limited to 'sca-cpp/trunk/modules/java/org') diff --git a/sca-cpp/trunk/modules/java/org/apache/tuscany/ClassLoader.java b/sca-cpp/trunk/modules/java/org/apache/tuscany/ClassLoader.java new file mode 100644 index 0000000000..78b9ec7d90 --- /dev/null +++ b/sca-cpp/trunk/modules/java/org/apache/tuscany/ClassLoader.java @@ -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"); + } + +} diff --git a/sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java b/sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java index 1c159a99d5..5707a07bc7 100644 --- a/sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java +++ b/sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java @@ -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)); } diff --git a/sca-cpp/trunk/modules/java/org/apache/tuscany/IterableUtil.java b/sca-cpp/trunk/modules/java/org/apache/tuscany/IterableUtil.java new file mode 100644 index 0000000000..ef18b856db --- /dev/null +++ b/sca-cpp/trunk/modules/java/org/apache/tuscany/IterableUtil.java @@ -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 Iterable list(final Object... a) { + return new ArrayIterable(a, 0); + } + + /** + * Convert an iterable list to a java.util.Collection. + */ + @SuppressWarnings("unchecked") + public static Collection collection(final Object l) { + final Collection c = new ArrayList(); + for(final Object x : (Iterable)l) + c.add((T)x); + return c; + } + + /** + * Construct a new list from an element and a list. + */ + public static Iterable cons(final Object car, final Iterable cdr) { + return new PairIterable(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 car(final Object l) { + if(l instanceof BasicIterable) + return ((BasicIterable)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 Iterable cdr(final Object l) { + if(l instanceof BasicIterable) + return ((BasicIterable)l).cdr(); + if(l instanceof List) + return new ListIterable((List)l, 1); + if(l instanceof Collection) + return new ArrayIterable(((Collection)l).toArray(), 1); + return new Iterable() { + @Override + public Iterator iterator() { + final Iterator i = ((Iterable)l).iterator(); + i.next(); + return i; + } + }; + } + + /** + * Return the car of the cdr of a list. + */ + @SuppressWarnings("unchecked") + public static T cadr(final Object l) { + return (T)car(cdr(l)); + } + + /** + * Return the cdr of the cdr of a list. + */ + public static Iterable 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 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 Iterable 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 extends AbstractList { + abstract T car(); + + abstract Iterable 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 extends BasicIterable { + 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 cdr() { + return new ArrayIterable(this.a, this.start + 1); + } + + @Override + public Iterator iterator() { + return new Iterator() { + 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 extends BasicIterable { + 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 cdr() { + return new ListIterable(this.l, this.start + 1); + } + + @Override + public Iterator iterator() { + return new Iterator() { + 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 extends BasicIterable { + 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 cdr() { + return (Iterable)this.cdr; + } + + @Override + public Iterator iterator() { + return new Iterator() { + 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 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 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 cl = cons(0, cons(1, new ArrayList(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 jl = new ArrayList(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 n = list(); + assert isNil(n); + assert n.toString().equals("[]"); + + final Iterable cn = cons(0, n); + assert !isNil(cn); + assert isNil(cdr(cn)); + assert cn.toString().equals("[0]"); + + final Iterable al = new ArrayList(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/trunk/modules/java/org/apache/tuscany/Service.java b/sca-cpp/trunk/modules/java/org/apache/tuscany/Service.java index c8152463b4..6150b7d1cd 100644 --- a/sca-cpp/trunk/modules/java/org/apache/tuscany/Service.java +++ b/sca-cpp/trunk/modules/java/org/apache/tuscany/Service.java @@ -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); - - Object[] get(String id); - - Object[] getall(); - - boolean put(String id, Object[] item); - + /** + * Post a new item to a resource. + */ + String post(Iterable item); + + /** + * Return an item. + */ + Iterable get(String id); + + /** + * Return all items in the resource. + */ + Iterable getall(); + + /** + * 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 apply(Object... params); } -- cgit v1.2.3