From 2094a1aa099c8a6614bf3dd27dcca04c87ec1a6c Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Sun, 1 Apr 2007 00:00:07 +0000 Subject: Move Storable code generation support to separate package. --- .../java/com/amazon/carbonado/TestStorables.java | 2 +- .../carbonado/gen/StorableInterceptorFactory.java | 202 ++++++++++++++++++++ .../carbonado/gen/TestStorableSerializer.java | 115 ++++++++++++ .../carbonado/gen/TestWrappedStorableFactory.java | 164 +++++++++++++++++ .../carbonado/info/TestConversionComparator.java | 177 ++++++++++++++++++ .../repo/replicated/TestProxiedStorable.java | 2 +- .../carbonado/repo/toy/ToyStorableGenerator.java | 10 +- .../com/amazon/carbonado/repo/toy/ToyStorage.java | 2 +- .../carbonado/spi/StorableInterceptorFactory.java | 203 --------------------- .../carbonado/spi/TestConversionComparator.java | 179 ------------------ .../carbonado/spi/TestStorableSerializer.java | 115 ------------ .../carbonado/spi/TestWrappedStorableFactory.java | 164 ----------------- 12 files changed, 666 insertions(+), 669 deletions(-) create mode 100644 src/test/java/com/amazon/carbonado/gen/StorableInterceptorFactory.java create mode 100644 src/test/java/com/amazon/carbonado/gen/TestStorableSerializer.java create mode 100644 src/test/java/com/amazon/carbonado/gen/TestWrappedStorableFactory.java create mode 100644 src/test/java/com/amazon/carbonado/info/TestConversionComparator.java delete mode 100644 src/test/java/com/amazon/carbonado/spi/StorableInterceptorFactory.java delete mode 100644 src/test/java/com/amazon/carbonado/spi/TestConversionComparator.java delete mode 100644 src/test/java/com/amazon/carbonado/spi/TestStorableSerializer.java delete mode 100644 src/test/java/com/amazon/carbonado/spi/TestWrappedStorableFactory.java (limited to 'src/test') diff --git a/src/test/java/com/amazon/carbonado/TestStorables.java b/src/test/java/com/amazon/carbonado/TestStorables.java index f03fc0f..747ee23 100644 --- a/src/test/java/com/amazon/carbonado/TestStorables.java +++ b/src/test/java/com/amazon/carbonado/TestStorables.java @@ -47,7 +47,7 @@ import com.amazon.carbonado.UniqueConstraintException; import com.amazon.carbonado.cursor.SortedCursor; import com.amazon.carbonado.spi.RepairExecutor; -import com.amazon.carbonado.spi.WrappedSupport; +import com.amazon.carbonado.gen.WrappedSupport; import com.amazon.carbonado.stored.*; diff --git a/src/test/java/com/amazon/carbonado/gen/StorableInterceptorFactory.java b/src/test/java/com/amazon/carbonado/gen/StorableInterceptorFactory.java new file mode 100644 index 0000000..527ce21 --- /dev/null +++ b/src/test/java/com/amazon/carbonado/gen/StorableInterceptorFactory.java @@ -0,0 +1,202 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * 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. + */ +package com.amazon.carbonado.gen; + +import java.util.Map; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.UndeclaredThrowableException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.ref.Reference; +import java.lang.ref.SoftReference; + +import org.cojen.util.ClassInjector; +import org.cojen.util.WeakIdentityMap; +import org.cojen.classfile.TypeDesc; +import org.cojen.classfile.ClassFile; +import org.cojen.classfile.Modifiers; +import org.cojen.classfile.MethodInfo; +import org.cojen.classfile.CodeBuilder; + +import com.amazon.carbonado.Storable; + +/** + * StorableInterceptorFactory creates instances of Storables that delegate + * calls to a proxy. + * + *

If the base class for the interceptor is abstract and has any methods implemented, those + * methods will be invoked directly and no further action taken. + * + *

Any methods which are not implemented will be delegated to the proxy which is provided to the + * constructor. + * + * @author Don Schneider + */ +public class StorableInterceptorFactory { + + public static final String PROXY = "mProxy$"; + + private static Map> + cCache = new WeakIdentityMap(); + + /** + * @param interceptorType the handler type to be invoked for accessors and + * mutators, which should just be the type of S. + */ + public static StorableInterceptorFactory getInstance( + Class interceptorType, Class userType, boolean shortCircuit) + { + synchronized (cCache) { + StorableInterceptorFactory factory; + String key = interceptorType.getName() + userType.getName() + (shortCircuit?"S":"P"); + Reference ref = cCache.get(key); + if (null != ref) { + factory = ref.get(); + if (factory != null) { + return factory; + } + } + factory = new StorableInterceptorFactory(interceptorType, userType, shortCircuit); + cCache.put(key, new SoftReference(factory)); + return factory; + } + } + + private final Constructor mConstructor; + + private StorableInterceptorFactory(final Class interceptorType, + Class userType, + boolean doShortCircuit) { + Class storableClass = generateStorable(interceptorType, userType, doShortCircuit); + try { + mConstructor = storableClass.getConstructor(userType); + } + catch (NoSuchMethodException e) { + throw new UndeclaredThrowableException(e); + } + } + + private static Class + generateStorable(Class interceptorType, + Class userType, + boolean doShortCircuit) + { + TypeDesc interceptorTypeDesc = TypeDesc.forClass(interceptorType); + TypeDesc userTypeDesc = TypeDesc.forClass(userType); + + ClassInjector ci = ClassInjector.create(interceptorType.getName(), null); + ClassFile cf = CodeBuilderUtil.createStorableClassFile( + ci, + interceptorType, + false, + StorableInterceptorFactory.class.getName()); + + // private final Storable mProxy$; + cf.addField(Modifiers.PRIVATE.toFinal(true), PROXY, userTypeDesc); + + final TypeDesc[] ctorParams = {userTypeDesc}; + // Add public constructor: + { + final int storableHandler = 0; + MethodInfo mi = cf.addConstructor(Modifiers.PUBLIC, ctorParams); + CodeBuilder b = new CodeBuilder(mi); + b.loadThis(); + try { + interceptorType.getConstructor(new Class[] {userType}); + b.loadLocal(b.getParameter(storableHandler)); + b.invokeSuperConstructor(ctorParams); + } + catch (NoSuchMethodException e) { + b.invokeSuperConstructor(null); + } + + + //// this.storableHandler = storableHandler + CodeBuilderUtil.assertParameterNotNull(b, storableHandler); + b.loadThis(); + b.loadLocal(b.getParameter(storableHandler)); + b.storeField(PROXY, userTypeDesc); + + b.returnVoid(); + } + + + // Add delegation for all abstract methods. It is the responsibility of the implementor + // to delegate the non-abstract methods + + for (Method method : interceptorType.getMethods()) { + if (Modifier.isAbstract(method.getModifiers())) { + MethodInfo mi = cf.addMethod(method); + CodeBuilder b = new CodeBuilder(mi); + + // If we're asked to short circuit, we don't bother proxying. This is useful + // for creating a "visitor" -- that is, only implement a few "set" methods + if (!doShortCircuit) { + b.loadThis(); + b.loadField(PROXY, userTypeDesc); + for (int i = 0; i < method.getParameterTypes().length; i++) { + b.loadLocal(b.getParameter(i)); + } + b.invoke(method); + } + + if (void.class == method.getReturnType()) { + b.returnVoid(); + } else { + b.returnValue(TypeDesc.forClass(method.getReturnType())); + } + } + } + + Class result = ci.defineClass(cf); + return (Class) result; + } + + /** + * Create a new proxied storable instance which delegates to the given + * proxies. All methods are fully delegated. + * + * @param storable to use as a proxy + */ + public S create(Storable storable) { + try { + return mConstructor.newInstance(storable); + } + catch (InstantiationException e) { + InternalError error = new InternalError(); + error.initCause(e); + throw error; + } catch (IllegalAccessException e) { + InternalError error = new InternalError(); + error.initCause(e); + throw error; + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } + if (cause instanceof Error) { + throw (Error) cause; + } + InternalError error = new InternalError(); + error.initCause(cause == null ? e : cause); + throw error; + } + } +} diff --git a/src/test/java/com/amazon/carbonado/gen/TestStorableSerializer.java b/src/test/java/com/amazon/carbonado/gen/TestStorableSerializer.java new file mode 100644 index 0000000..2786dce --- /dev/null +++ b/src/test/java/com/amazon/carbonado/gen/TestStorableSerializer.java @@ -0,0 +1,115 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * 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. + */ + +package com.amazon.carbonado.gen; + +import java.io.*; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import com.amazon.carbonado.*; +import com.amazon.carbonado.lob.*; + +import com.amazon.carbonado.repo.toy.ToyRepository; +import com.amazon.carbonado.stored.*; + +/** + * Test case for {@link StorableSerializer}. + * + * @author Brian S O'Neill + */ +public class TestStorableSerializer extends TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + + public static TestSuite suite() { + return new TestSuite(TestStorableSerializer.class); + } + + private Repository mRepository; + + public TestStorableSerializer(String name) { + super(name); + } + + protected void setUp() { + mRepository = new ToyRepository(); + } + + protected void tearDown() { + mRepository.close(); + mRepository = null; + } + + public void testReadAndWrite() throws Exception { + Storage storage = mRepository.storageFor(StorableTestBasic.class); + StorableTestBasic stb = storage.prepare(); + stb.setId(50); + stb.setStringProp("hello"); + stb.setIntProp(100); + stb.setLongProp(999); + stb.setDoubleProp(2.718281828d); + + StorableSerializer serializer = + StorableSerializer.forType(StorableTestBasic.class); + + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + DataOutputStream dout = new DataOutputStream(bout); + + serializer.write(stb, (DataOutput) dout); + dout.flush(); + + byte[] bytes = bout.toByteArray(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bytes); + DataInputStream din = new DataInputStream(bin); + + StorableTestBasic stb2 = serializer.read(storage, (DataInput) din); + + assertEquals(stb, stb2); + } + + /* + public void testReadAndWriteLobs() throws Exception { + Storage storage = mRepository.storageFor(StorableWithLobs.class); + StorableWithLobs s = storage.prepare(); + s.setBlobValue(new ByteArrayBlob("Hello Blob".getBytes())); + s.setClobValue(new StringClob("Hello Clob")); + + StorableSerializer serializer = + StorableSerializer.forType(StorableWithLobs.class); + + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + DataOutputStream dout = new DataOutputStream(bout); + + serializer.write(s, (DataOutput) dout); + dout.flush(); + + byte[] bytes = bout.toByteArray(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bytes); + DataInputStream din = new DataInputStream(bin); + + StorableWithLobs s2 = serializer.read(storage, (DataInput) din); + + assertEquals(s, s2); + } + */ +} diff --git a/src/test/java/com/amazon/carbonado/gen/TestWrappedStorableFactory.java b/src/test/java/com/amazon/carbonado/gen/TestWrappedStorableFactory.java new file mode 100644 index 0000000..40135f1 --- /dev/null +++ b/src/test/java/com/amazon/carbonado/gen/TestWrappedStorableFactory.java @@ -0,0 +1,164 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * 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. + */ + +package com.amazon.carbonado.gen; + +import java.lang.reflect.Method; + +import junit.framework.TestSuite; + +import com.amazon.carbonado.Cursor; +import com.amazon.carbonado.Repository; +import com.amazon.carbonado.Storable; +import com.amazon.carbonado.Storage; +import com.amazon.carbonado.TestStorableBase; +import com.amazon.carbonado.TestStorables; + +import com.amazon.carbonado.stored.StorableTestBasic; +import com.amazon.carbonado.stored.STBContainer; + +/** + * + * + * @author Brian S O'Neill + * @author Don Schneider + */ +public class TestWrappedStorableFactory extends TestStorableBase { + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + + public static TestSuite suite() { + return new TestSuite(TestWrappedStorableFactory.class); + } + + public TestWrappedStorableFactory() { + super(); + } + + /** + * Test setAndGet + */ + public void test_proxiedSetAndGet() throws Exception { + Class wrapperClass = StorableGenerator + .getWrappedClass(StorableTestBasic.class); + + TestStorables.InvocationTracker props = new TestStorables.InvocationTracker("props"); + TestStorables.InvocationTracker handler = new TestStorables.InvocationTracker("handler"); + + StorableTestBasic wrapper = wrapperClass + .getConstructor(WrappedSupport.class, Storable.class) + .newInstance(handler, props); + + setPrimaryKeyProperties(wrapper); + setBasicProperties(wrapper); + + wrapper.getStringProp(); + wrapper.getIntProp(); + wrapper.getLongProp(); + wrapper.getDoubleProp(); + wrapper.getId(); + + for (Method method : Storable.class.getMethods()) { + if (method.getParameterTypes().length > 0) { + if (method.getParameterTypes()[0] != String.class) { + method.invoke(wrapper, wrapper); + } + } else { + method.invoke(wrapper, (Object[]) null); + } + } + + props.assertTrack(TestStorables.ALL_GET_METHODS + | TestStorables.ALL_SET_METHODS + // Copy is called on wrapped storable because wrapped storage is null + | TestStorables.sCopy + | TestStorables.sToStringKeyOnly + | TestStorables.sHasDirtyProperties + | TestStorables.sEqualKeys + | TestStorables.sEqualProperties + | TestStorables.sMarkPropertiesClean + | TestStorables.sMarkAllPropertiesClean + | TestStorables.sMarkPropertiesDirty + | TestStorables.sMarkAllPropertiesDirty + | TestStorables.ALL_COPY_PROP_METHODS); + + handler.assertTrack(TestStorables.sTryLoad + | TestStorables.sLoad + | TestStorables.sInsert + | TestStorables.sTryInsert + | TestStorables.sUpdate + | TestStorables.sTryUpdate + | TestStorables.sDelete + | TestStorables.sTryDelete); + } + + /** + * Verify that storables from joined property are also wrapped. + */ + public void test_wrappedJoin() throws Exception { + Storage stbStorage = + getRepository().storageFor(StorableTestBasic.class); + StorableTestBasic stb = stbStorage.prepare(); + //assertEquals(stbStorage, stb.storage()); + //assertTrue(stb.storage().getClass().getName().indexOf("IndexedStorage") > 0); + + stb.setId(1); + stb.initBasicProperties(); + stb.setStringProp("Hello"); + stb.insert(); + + stb = stbStorage.prepare(); + stb.setId(2); + stb.initBasicProperties(); + stb.setStringProp("Hello"); + stb.insert(); + + stb = stbStorage.prepare(); + stb.setId(3); + stb.initBasicProperties(); + stb.setStringProp("World"); + stb.insert(); + + Storage containerStorage = getRepository().storageFor(STBContainer.class); + + STBContainer container = containerStorage.prepare(); + container.setName("A"); + container.setCategory("Hello"); + container.setCount(2); + container.insert(); + + container = containerStorage.prepare(); + container.setName("B"); + container.setCategory("World"); + container.setCount(1); + container.insert(); + + // Test wrapping of query results + /* + container = containerStorage.prepare(); + container.setName("A"); + container.load(); + Cursor cursor = container.getContained().fetch(); + while (cursor.hasNext()) { + stb = cursor.next(); + assertTrue(stb.storage().getClass().getName().indexOf("IndexedStorage") > 0); + } + */ + } +} diff --git a/src/test/java/com/amazon/carbonado/info/TestConversionComparator.java b/src/test/java/com/amazon/carbonado/info/TestConversionComparator.java new file mode 100644 index 0000000..a4e5614 --- /dev/null +++ b/src/test/java/com/amazon/carbonado/info/TestConversionComparator.java @@ -0,0 +1,177 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * 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. + */ + +package com.amazon.carbonado.info; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Test cases for {@link ConversionComparator}. + * + * @author Brian S O'Neill + */ +public class TestConversionComparator extends TestCase { + private static final int BOOLEAN_CODE = 0; + private static final int BYTE_CODE = 1; + private static final int SHORT_CODE = 2; + private static final int CHAR_CODE = 3; + private static final int INT_CODE = 4; + private static final int FLOAT_CODE = 5; + private static final int LONG_CODE = 6; + private static final int DOUBLE_CODE = 7; + + private static final Class[] PRIMITIVE_CLASSES = { + boolean.class, byte.class, short.class, char.class, + int.class, float.class, long.class, double.class + }; + + private static final Class[] BOXED_PRIMITIVE_CLASSES = { + Boolean.class, Byte.class, Short.class, Character.class, + Integer.class, Float.class, Long.class, Double.class + }; + + // States which primitive conversions are allowed. + private static final boolean[][] PRIMITIVE_MATRIX = { + // from... + // boolean byte short char int float long double + { true, false, false, false, false, false, false, false }, // to boolean + { false, true, false, false, false, false, false, false }, // to byte + { false, true, true, false, false, false, false, false }, // to short + { false, false, false, true, false, false, false, false }, // to char + { false, true, true, false, true, false, false, false }, // to int + { false, true, true, false, false, true, false, false }, // to float + { false, true, true, false, true, false, true, false }, // to long + { false, true, true, false, true, true, false, true }, // to double + }; + + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + + public static TestSuite suite() { + return new TestSuite(TestConversionComparator.class); + } + + public TestConversionComparator(String name) { + super(name); + } + + public void test_isConversionPossible_basics() { + ConversionComparator cc = new ConversionComparator(Object.class); + assertEquals(true, cc.isConversionPossible(Object.class)); + assertEquals(false, cc.isConversionPossible(String.class)); + assertEquals(false, cc.isConversionPossible(boolean.class)); + assertEquals(false, cc.isConversionPossible(Integer.class)); + assertEquals(false, cc.isConversionPossible(int.class)); + + cc = new ConversionComparator(String.class); + assertEquals(true, cc.isConversionPossible(Object.class)); + assertEquals(true, cc.isConversionPossible(String.class)); + assertEquals(false, cc.isConversionPossible(boolean.class)); + assertEquals(false, cc.isConversionPossible(Integer.class)); + assertEquals(false, cc.isConversionPossible(int.class)); + + cc = new ConversionComparator(boolean.class); + assertEquals(true, cc.isConversionPossible(Object.class)); + assertEquals(false, cc.isConversionPossible(String.class)); + assertEquals(true, cc.isConversionPossible(boolean.class)); + assertEquals(false, cc.isConversionPossible(Integer.class)); + assertEquals(false, cc.isConversionPossible(int.class)); + + cc = new ConversionComparator(Integer.class); + assertEquals(true, cc.isConversionPossible(Object.class)); + assertEquals(false, cc.isConversionPossible(String.class)); + assertEquals(false, cc.isConversionPossible(boolean.class)); + assertEquals(true, cc.isConversionPossible(Integer.class)); + assertEquals(true, cc.isConversionPossible(int.class)); + + cc = new ConversionComparator(int.class); + assertEquals(true, cc.isConversionPossible(Object.class)); + assertEquals(false, cc.isConversionPossible(String.class)); + assertEquals(false, cc.isConversionPossible(boolean.class)); + assertEquals(true, cc.isConversionPossible(Integer.class)); + assertEquals(true, cc.isConversionPossible(int.class)); + } + + public void test_isConversionPossible_primitives() { + test_isConversionPossible_primitives(false, false); + test_isConversionPossible_primitives(false, true); + test_isConversionPossible_primitives(true, false); + test_isConversionPossible_primitives(true, true); + } + + private void test_isConversionPossible_primitives(boolean fromBoxed, boolean toBoxed) { + for (int fromCode = BOOLEAN_CODE; fromCode <= DOUBLE_CODE; fromCode++) { + ConversionComparator cc = new ConversionComparator + (fromBoxed ? BOXED_PRIMITIVE_CLASSES[fromCode] : PRIMITIVE_CLASSES[fromCode]); + for (int toCode = BOOLEAN_CODE; toCode <= DOUBLE_CODE; toCode++) { + boolean expected = PRIMITIVE_MATRIX[toCode][fromCode]; + Class toType = toBoxed ? BOXED_PRIMITIVE_CLASSES[toCode] : PRIMITIVE_CLASSES[toCode]; + assertEquals(expected, cc.isConversionPossible(toType)); + } + } + } + + public void test_compare() { + ConversionComparator cc = new ConversionComparator(Object.class); + assertEquals(true, cc.compare(Object.class, String.class) < 0); + assertEquals(true, cc.compare(String.class, Object.class) > 0); + assertEquals(0, cc.compare(Object.class, Object.class)); + assertEquals(0, cc.compare(String.class, String.class)); + assertEquals(0, cc.compare(String.class, String.class)); + assertEquals(0, cc.compare(int.class, Number.class)); + + cc = new ConversionComparator(String.class); + assertEquals(true, cc.compare(String.class, Object.class) < 0); + assertEquals(true, cc.compare(Object.class, String.class) > 0); + assertEquals(0, cc.compare(String.class, String.class)); + assertEquals(true, cc.compare(int.class, String.class) > 0); + + cc = new ConversionComparator(Integer.class); + assertEquals(true, cc.compare(String.class, Object.class) > 0); + assertEquals(true, cc.compare(Object.class, String.class) < 0); + assertEquals(true, cc.compare(Object.class, Number.class) > 0); + assertEquals(true, cc.compare(Integer.class, Number.class) < 0); + assertEquals(true, cc.compare(int.class, Number.class) > 0); + assertEquals(true, cc.compare(long.class, Number.class) > 0); + assertEquals(true, cc.compare(long.class, Long.class) < 0); + + cc = new ConversionComparator(int.class); + assertEquals(true, cc.compare(String.class, Object.class) > 0); + assertEquals(true, cc.compare(Object.class, String.class) < 0); + assertEquals(true, cc.compare(Object.class, Number.class) > 0); + assertEquals(true, cc.compare(Integer.class, Number.class) < 0); + assertEquals(true, cc.compare(int.class, Number.class) < 0); + assertEquals(true, cc.compare(long.class, Number.class) < 0); + assertEquals(true, cc.compare(long.class, Long.class) < 0); + + cc = new ConversionComparator(Byte.class); + assertEquals(true, cc.compare(int.class, Number.class) > 0); + assertEquals(true, cc.compare(long.class, Number.class) > 0); + assertEquals(true, cc.compare(long.class, Integer.class) < 0); + + cc = new ConversionComparator(byte.class); + assertEquals(true, cc.compare(short.class, int.class) < 0); + assertEquals(true, cc.compare(long.class, int.class) > 0); + + cc = new ConversionComparator(java.util.Date.class); + assertEquals(true, cc.compare(Object.class, Comparable.class) > 0); + assertEquals(0, cc.compare(java.io.Serializable.class, Comparable.class)); + } +} diff --git a/src/test/java/com/amazon/carbonado/repo/replicated/TestProxiedStorable.java b/src/test/java/com/amazon/carbonado/repo/replicated/TestProxiedStorable.java index 6de2faf..b94edc9 100644 --- a/src/test/java/com/amazon/carbonado/repo/replicated/TestProxiedStorable.java +++ b/src/test/java/com/amazon/carbonado/repo/replicated/TestProxiedStorable.java @@ -21,7 +21,7 @@ import java.lang.reflect.Method; import junit.framework.TestSuite; import com.amazon.carbonado.TestUtilities; -import com.amazon.carbonado.spi.StorableInterceptorFactory; +import com.amazon.carbonado.gen.StorableInterceptorFactory; import com.amazon.carbonado.stored.StorableTestBasic; import com.amazon.carbonado.stored.StorableTestBasicIdMunger; import com.amazon.carbonado.TestStorables; diff --git a/src/test/java/com/amazon/carbonado/repo/toy/ToyStorableGenerator.java b/src/test/java/com/amazon/carbonado/repo/toy/ToyStorableGenerator.java index a72c7d5..8ab95f6 100644 --- a/src/test/java/com/amazon/carbonado/repo/toy/ToyStorableGenerator.java +++ b/src/test/java/com/amazon/carbonado/repo/toy/ToyStorableGenerator.java @@ -34,11 +34,11 @@ import com.amazon.carbonado.Storable; import com.amazon.carbonado.SupportException; import com.amazon.carbonado.Trigger; -import com.amazon.carbonado.spi.MasterFeature; -import com.amazon.carbonado.spi.MasterStorableGenerator; -import com.amazon.carbonado.spi.MasterSupport; -import com.amazon.carbonado.spi.StorableGenerator; -import com.amazon.carbonado.spi.TriggerSupport; +import com.amazon.carbonado.gen.MasterFeature; +import com.amazon.carbonado.gen.MasterStorableGenerator; +import com.amazon.carbonado.gen.MasterSupport; +import com.amazon.carbonado.gen.StorableGenerator; +import com.amazon.carbonado.gen.TriggerSupport; /** * diff --git a/src/test/java/com/amazon/carbonado/repo/toy/ToyStorage.java b/src/test/java/com/amazon/carbonado/repo/toy/ToyStorage.java index bd73d98..c378dca 100644 --- a/src/test/java/com/amazon/carbonado/repo/toy/ToyStorage.java +++ b/src/test/java/com/amazon/carbonado/repo/toy/ToyStorage.java @@ -39,7 +39,7 @@ import com.amazon.carbonado.Trigger; import com.amazon.carbonado.sequence.SequenceValueProducer; -import com.amazon.carbonado.spi.MasterSupport; +import com.amazon.carbonado.gen.MasterSupport; import com.amazon.carbonado.util.QuickConstructorGenerator; diff --git a/src/test/java/com/amazon/carbonado/spi/StorableInterceptorFactory.java b/src/test/java/com/amazon/carbonado/spi/StorableInterceptorFactory.java deleted file mode 100644 index fd4c715..0000000 --- a/src/test/java/com/amazon/carbonado/spi/StorableInterceptorFactory.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2006 Amazon Technologies, Inc. or its affiliates. - * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks - * of Amazon Technologies, Inc. or its affiliates. All rights reserved. - * - * 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. - */ -package com.amazon.carbonado.spi; - -import java.util.Map; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.UndeclaredThrowableException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.ref.Reference; -import java.lang.ref.SoftReference; - -import org.cojen.util.ClassInjector; -import org.cojen.util.WeakIdentityMap; -import org.cojen.classfile.TypeDesc; -import org.cojen.classfile.ClassFile; -import org.cojen.classfile.Modifiers; -import org.cojen.classfile.MethodInfo; -import org.cojen.classfile.CodeBuilder; - -import com.amazon.carbonado.Storable; -import com.amazon.carbonado.spi.CodeBuilderUtil; - -/** - * StorableInterceptorFactory creates instances of Storables that delegate - * calls to a proxy. - * - *

If the base class for the interceptor is abstract and has any methods implemented, those - * methods will be invoked directly and no further action taken. - * - *

Any methods which are not implemented will be delegated to the proxy which is provided to the - * constructor. - * - * @author Don Schneider - */ -public class StorableInterceptorFactory { - - public static final String PROXY = "mProxy$"; - - private static Map> - cCache = new WeakIdentityMap(); - - /** - * @param interceptorType the handler type to be invoked for accessors and - * mutators, which should just be the type of S. - */ - public static StorableInterceptorFactory getInstance( - Class interceptorType, Class userType, boolean shortCircuit) - { - synchronized (cCache) { - StorableInterceptorFactory factory; - String key = interceptorType.getName() + userType.getName() + (shortCircuit?"S":"P"); - Reference ref = cCache.get(key); - if (null != ref) { - factory = ref.get(); - if (factory != null) { - return factory; - } - } - factory = new StorableInterceptorFactory(interceptorType, userType, shortCircuit); - cCache.put(key, new SoftReference(factory)); - return factory; - } - } - - private final Constructor mConstructor; - - private StorableInterceptorFactory(final Class interceptorType, - Class userType, - boolean doShortCircuit) { - Class storableClass = generateStorable(interceptorType, userType, doShortCircuit); - try { - mConstructor = storableClass.getConstructor(userType); - } - catch (NoSuchMethodException e) { - throw new UndeclaredThrowableException(e); - } - } - - private static Class - generateStorable(Class interceptorType, - Class userType, - boolean doShortCircuit) - { - TypeDesc interceptorTypeDesc = TypeDesc.forClass(interceptorType); - TypeDesc userTypeDesc = TypeDesc.forClass(userType); - - ClassInjector ci = ClassInjector.create(interceptorType.getName(), null); - ClassFile cf = CodeBuilderUtil.createStorableClassFile( - ci, - interceptorType, - false, - StorableInterceptorFactory.class.getName()); - - // private final Storable mProxy$; - cf.addField(Modifiers.PRIVATE.toFinal(true), PROXY, userTypeDesc); - - final TypeDesc[] ctorParams = {userTypeDesc}; - // Add public constructor: - { - final int storableHandler = 0; - MethodInfo mi = cf.addConstructor(Modifiers.PUBLIC, ctorParams); - CodeBuilder b = new CodeBuilder(mi); - b.loadThis(); - try { - interceptorType.getConstructor(new Class[] {userType}); - b.loadLocal(b.getParameter(storableHandler)); - b.invokeSuperConstructor(ctorParams); - } - catch (NoSuchMethodException e) { - b.invokeSuperConstructor(null); - } - - - //// this.storableHandler = storableHandler - CodeBuilderUtil.assertParameterNotNull(b, storableHandler); - b.loadThis(); - b.loadLocal(b.getParameter(storableHandler)); - b.storeField(PROXY, userTypeDesc); - - b.returnVoid(); - } - - - // Add delegation for all abstract methods. It is the responsibility of the implementor - // to delegate the non-abstract methods - - for (Method method : interceptorType.getMethods()) { - if (Modifier.isAbstract(method.getModifiers())) { - MethodInfo mi = cf.addMethod(method); - CodeBuilder b = new CodeBuilder(mi); - - // If we're asked to short circuit, we don't bother proxying. This is useful - // for creating a "visitor" -- that is, only implement a few "set" methods - if (!doShortCircuit) { - b.loadThis(); - b.loadField(PROXY, userTypeDesc); - for (int i = 0; i < method.getParameterTypes().length; i++) { - b.loadLocal(b.getParameter(i)); - } - b.invoke(method); - } - - if (void.class == method.getReturnType()) { - b.returnVoid(); - } else { - b.returnValue(TypeDesc.forClass(method.getReturnType())); - } - } - } - - Class result = ci.defineClass(cf); - return (Class) result; - } - - /** - * Create a new proxied storable instance which delegates to the given - * proxies. All methods are fully delegated. - * - * @param storable to use as a proxy - */ - public S create(Storable storable) { - try { - return mConstructor.newInstance(storable); - } - catch (InstantiationException e) { - InternalError error = new InternalError(); - error.initCause(e); - throw error; - } catch (IllegalAccessException e) { - InternalError error = new InternalError(); - error.initCause(e); - throw error; - } catch (InvocationTargetException e) { - Throwable cause = e.getCause(); - if (cause instanceof RuntimeException) { - throw (RuntimeException) cause; - } - if (cause instanceof Error) { - throw (Error) cause; - } - InternalError error = new InternalError(); - error.initCause(cause == null ? e : cause); - throw error; - } - } -} diff --git a/src/test/java/com/amazon/carbonado/spi/TestConversionComparator.java b/src/test/java/com/amazon/carbonado/spi/TestConversionComparator.java deleted file mode 100644 index 5cd7caa..0000000 --- a/src/test/java/com/amazon/carbonado/spi/TestConversionComparator.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2006 Amazon Technologies, Inc. or its affiliates. - * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks - * of Amazon Technologies, Inc. or its affiliates. All rights reserved. - * - * 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. - */ - -package com.amazon.carbonado.spi; - -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import com.amazon.carbonado.spi.ConversionComparator; - -/** - * Test cases for {@link ConversionComparator}. - * - * @author Brian S O'Neill - */ -public class TestConversionComparator extends TestCase { - private static final int BOOLEAN_CODE = 0; - private static final int BYTE_CODE = 1; - private static final int SHORT_CODE = 2; - private static final int CHAR_CODE = 3; - private static final int INT_CODE = 4; - private static final int FLOAT_CODE = 5; - private static final int LONG_CODE = 6; - private static final int DOUBLE_CODE = 7; - - private static final Class[] PRIMITIVE_CLASSES = { - boolean.class, byte.class, short.class, char.class, - int.class, float.class, long.class, double.class - }; - - private static final Class[] BOXED_PRIMITIVE_CLASSES = { - Boolean.class, Byte.class, Short.class, Character.class, - Integer.class, Float.class, Long.class, Double.class - }; - - // States which primitive conversions are allowed. - private static final boolean[][] PRIMITIVE_MATRIX = { - // from... - // boolean byte short char int float long double - { true, false, false, false, false, false, false, false }, // to boolean - { false, true, false, false, false, false, false, false }, // to byte - { false, true, true, false, false, false, false, false }, // to short - { false, false, false, true, false, false, false, false }, // to char - { false, true, true, false, true, false, false, false }, // to int - { false, true, true, false, false, true, false, false }, // to float - { false, true, true, false, true, false, true, false }, // to long - { false, true, true, false, true, true, false, true }, // to double - }; - - public static void main(String[] args) { - junit.textui.TestRunner.run(suite()); - } - - public static TestSuite suite() { - return new TestSuite(TestConversionComparator.class); - } - - public TestConversionComparator(String name) { - super(name); - } - - public void test_isConversionPossible_basics() { - ConversionComparator cc = new ConversionComparator(Object.class); - assertEquals(true, cc.isConversionPossible(Object.class)); - assertEquals(false, cc.isConversionPossible(String.class)); - assertEquals(false, cc.isConversionPossible(boolean.class)); - assertEquals(false, cc.isConversionPossible(Integer.class)); - assertEquals(false, cc.isConversionPossible(int.class)); - - cc = new ConversionComparator(String.class); - assertEquals(true, cc.isConversionPossible(Object.class)); - assertEquals(true, cc.isConversionPossible(String.class)); - assertEquals(false, cc.isConversionPossible(boolean.class)); - assertEquals(false, cc.isConversionPossible(Integer.class)); - assertEquals(false, cc.isConversionPossible(int.class)); - - cc = new ConversionComparator(boolean.class); - assertEquals(true, cc.isConversionPossible(Object.class)); - assertEquals(false, cc.isConversionPossible(String.class)); - assertEquals(true, cc.isConversionPossible(boolean.class)); - assertEquals(false, cc.isConversionPossible(Integer.class)); - assertEquals(false, cc.isConversionPossible(int.class)); - - cc = new ConversionComparator(Integer.class); - assertEquals(true, cc.isConversionPossible(Object.class)); - assertEquals(false, cc.isConversionPossible(String.class)); - assertEquals(false, cc.isConversionPossible(boolean.class)); - assertEquals(true, cc.isConversionPossible(Integer.class)); - assertEquals(true, cc.isConversionPossible(int.class)); - - cc = new ConversionComparator(int.class); - assertEquals(true, cc.isConversionPossible(Object.class)); - assertEquals(false, cc.isConversionPossible(String.class)); - assertEquals(false, cc.isConversionPossible(boolean.class)); - assertEquals(true, cc.isConversionPossible(Integer.class)); - assertEquals(true, cc.isConversionPossible(int.class)); - } - - public void test_isConversionPossible_primitives() { - test_isConversionPossible_primitives(false, false); - test_isConversionPossible_primitives(false, true); - test_isConversionPossible_primitives(true, false); - test_isConversionPossible_primitives(true, true); - } - - private void test_isConversionPossible_primitives(boolean fromBoxed, boolean toBoxed) { - for (int fromCode = BOOLEAN_CODE; fromCode <= DOUBLE_CODE; fromCode++) { - ConversionComparator cc = new ConversionComparator - (fromBoxed ? BOXED_PRIMITIVE_CLASSES[fromCode] : PRIMITIVE_CLASSES[fromCode]); - for (int toCode = BOOLEAN_CODE; toCode <= DOUBLE_CODE; toCode++) { - boolean expected = PRIMITIVE_MATRIX[toCode][fromCode]; - Class toType = toBoxed ? BOXED_PRIMITIVE_CLASSES[toCode] : PRIMITIVE_CLASSES[toCode]; - assertEquals(expected, cc.isConversionPossible(toType)); - } - } - } - - public void test_compare() { - ConversionComparator cc = new ConversionComparator(Object.class); - assertEquals(true, cc.compare(Object.class, String.class) < 0); - assertEquals(true, cc.compare(String.class, Object.class) > 0); - assertEquals(0, cc.compare(Object.class, Object.class)); - assertEquals(0, cc.compare(String.class, String.class)); - assertEquals(0, cc.compare(String.class, String.class)); - assertEquals(0, cc.compare(int.class, Number.class)); - - cc = new ConversionComparator(String.class); - assertEquals(true, cc.compare(String.class, Object.class) < 0); - assertEquals(true, cc.compare(Object.class, String.class) > 0); - assertEquals(0, cc.compare(String.class, String.class)); - assertEquals(true, cc.compare(int.class, String.class) > 0); - - cc = new ConversionComparator(Integer.class); - assertEquals(true, cc.compare(String.class, Object.class) > 0); - assertEquals(true, cc.compare(Object.class, String.class) < 0); - assertEquals(true, cc.compare(Object.class, Number.class) > 0); - assertEquals(true, cc.compare(Integer.class, Number.class) < 0); - assertEquals(true, cc.compare(int.class, Number.class) > 0); - assertEquals(true, cc.compare(long.class, Number.class) > 0); - assertEquals(true, cc.compare(long.class, Long.class) < 0); - - cc = new ConversionComparator(int.class); - assertEquals(true, cc.compare(String.class, Object.class) > 0); - assertEquals(true, cc.compare(Object.class, String.class) < 0); - assertEquals(true, cc.compare(Object.class, Number.class) > 0); - assertEquals(true, cc.compare(Integer.class, Number.class) < 0); - assertEquals(true, cc.compare(int.class, Number.class) < 0); - assertEquals(true, cc.compare(long.class, Number.class) < 0); - assertEquals(true, cc.compare(long.class, Long.class) < 0); - - cc = new ConversionComparator(Byte.class); - assertEquals(true, cc.compare(int.class, Number.class) > 0); - assertEquals(true, cc.compare(long.class, Number.class) > 0); - assertEquals(true, cc.compare(long.class, Integer.class) < 0); - - cc = new ConversionComparator(byte.class); - assertEquals(true, cc.compare(short.class, int.class) < 0); - assertEquals(true, cc.compare(long.class, int.class) > 0); - - cc = new ConversionComparator(java.util.Date.class); - assertEquals(true, cc.compare(Object.class, Comparable.class) > 0); - assertEquals(0, cc.compare(java.io.Serializable.class, Comparable.class)); - } -} diff --git a/src/test/java/com/amazon/carbonado/spi/TestStorableSerializer.java b/src/test/java/com/amazon/carbonado/spi/TestStorableSerializer.java deleted file mode 100644 index 664bf12..0000000 --- a/src/test/java/com/amazon/carbonado/spi/TestStorableSerializer.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2006 Amazon Technologies, Inc. or its affiliates. - * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks - * of Amazon Technologies, Inc. or its affiliates. All rights reserved. - * - * 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. - */ - -package com.amazon.carbonado.spi; - -import java.io.*; - -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import com.amazon.carbonado.*; -import com.amazon.carbonado.lob.*; - -import com.amazon.carbonado.repo.toy.ToyRepository; -import com.amazon.carbonado.stored.*; - -/** - * Test case for {@link StorableSerializer}. - * - * @author Brian S O'Neill - */ -public class TestStorableSerializer extends TestCase { - public static void main(String[] args) { - junit.textui.TestRunner.run(suite()); - } - - public static TestSuite suite() { - return new TestSuite(TestStorableSerializer.class); - } - - private Repository mRepository; - - public TestStorableSerializer(String name) { - super(name); - } - - protected void setUp() { - mRepository = new ToyRepository(); - } - - protected void tearDown() { - mRepository.close(); - mRepository = null; - } - - public void testReadAndWrite() throws Exception { - Storage storage = mRepository.storageFor(StorableTestBasic.class); - StorableTestBasic stb = storage.prepare(); - stb.setId(50); - stb.setStringProp("hello"); - stb.setIntProp(100); - stb.setLongProp(999); - stb.setDoubleProp(2.718281828d); - - StorableSerializer serializer = - StorableSerializer.forType(StorableTestBasic.class); - - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - DataOutputStream dout = new DataOutputStream(bout); - - serializer.write(stb, (DataOutput) dout); - dout.flush(); - - byte[] bytes = bout.toByteArray(); - - ByteArrayInputStream bin = new ByteArrayInputStream(bytes); - DataInputStream din = new DataInputStream(bin); - - StorableTestBasic stb2 = serializer.read(storage, (DataInput) din); - - assertEquals(stb, stb2); - } - - /* - public void testReadAndWriteLobs() throws Exception { - Storage storage = mRepository.storageFor(StorableWithLobs.class); - StorableWithLobs s = storage.prepare(); - s.setBlobValue(new ByteArrayBlob("Hello Blob".getBytes())); - s.setClobValue(new StringClob("Hello Clob")); - - StorableSerializer serializer = - StorableSerializer.forType(StorableWithLobs.class); - - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - DataOutputStream dout = new DataOutputStream(bout); - - serializer.write(s, (DataOutput) dout); - dout.flush(); - - byte[] bytes = bout.toByteArray(); - - ByteArrayInputStream bin = new ByteArrayInputStream(bytes); - DataInputStream din = new DataInputStream(bin); - - StorableWithLobs s2 = serializer.read(storage, (DataInput) din); - - assertEquals(s, s2); - } - */ -} diff --git a/src/test/java/com/amazon/carbonado/spi/TestWrappedStorableFactory.java b/src/test/java/com/amazon/carbonado/spi/TestWrappedStorableFactory.java deleted file mode 100644 index fd0cd35..0000000 --- a/src/test/java/com/amazon/carbonado/spi/TestWrappedStorableFactory.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2006 Amazon Technologies, Inc. or its affiliates. - * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks - * of Amazon Technologies, Inc. or its affiliates. All rights reserved. - * - * 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. - */ - -package com.amazon.carbonado.spi; - -import java.lang.reflect.Method; - -import junit.framework.TestSuite; - -import com.amazon.carbonado.Cursor; -import com.amazon.carbonado.Repository; -import com.amazon.carbonado.Storable; -import com.amazon.carbonado.Storage; -import com.amazon.carbonado.TestStorableBase; -import com.amazon.carbonado.TestStorables; - -import com.amazon.carbonado.stored.StorableTestBasic; -import com.amazon.carbonado.stored.STBContainer; - -/** - * - * - * @author Brian S O'Neill - * @author Don Schneider - */ -public class TestWrappedStorableFactory extends TestStorableBase { - public static void main(String[] args) { - junit.textui.TestRunner.run(suite()); - } - - public static TestSuite suite() { - return new TestSuite(TestWrappedStorableFactory.class); - } - - public TestWrappedStorableFactory() { - super(); - } - - /** - * Test setAndGet - */ - public void test_proxiedSetAndGet() throws Exception { - Class wrapperClass = StorableGenerator - .getWrappedClass(StorableTestBasic.class); - - TestStorables.InvocationTracker props = new TestStorables.InvocationTracker("props"); - TestStorables.InvocationTracker handler = new TestStorables.InvocationTracker("handler"); - - StorableTestBasic wrapper = wrapperClass - .getConstructor(WrappedSupport.class, Storable.class) - .newInstance(handler, props); - - setPrimaryKeyProperties(wrapper); - setBasicProperties(wrapper); - - wrapper.getStringProp(); - wrapper.getIntProp(); - wrapper.getLongProp(); - wrapper.getDoubleProp(); - wrapper.getId(); - - for (Method method : Storable.class.getMethods()) { - if (method.getParameterTypes().length > 0) { - if (method.getParameterTypes()[0] != String.class) { - method.invoke(wrapper, wrapper); - } - } else { - method.invoke(wrapper, (Object[]) null); - } - } - - props.assertTrack(TestStorables.ALL_GET_METHODS - | TestStorables.ALL_SET_METHODS - // Copy is called on wrapped storable because wrapped storage is null - | TestStorables.sCopy - | TestStorables.sToStringKeyOnly - | TestStorables.sHasDirtyProperties - | TestStorables.sEqualKeys - | TestStorables.sEqualProperties - | TestStorables.sMarkPropertiesClean - | TestStorables.sMarkAllPropertiesClean - | TestStorables.sMarkPropertiesDirty - | TestStorables.sMarkAllPropertiesDirty - | TestStorables.ALL_COPY_PROP_METHODS); - - handler.assertTrack(TestStorables.sTryLoad - | TestStorables.sLoad - | TestStorables.sInsert - | TestStorables.sTryInsert - | TestStorables.sUpdate - | TestStorables.sTryUpdate - | TestStorables.sDelete - | TestStorables.sTryDelete); - } - - /** - * Verify that storables from joined property are also wrapped. - */ - public void test_wrappedJoin() throws Exception { - Storage stbStorage = - getRepository().storageFor(StorableTestBasic.class); - StorableTestBasic stb = stbStorage.prepare(); - //assertEquals(stbStorage, stb.storage()); - //assertTrue(stb.storage().getClass().getName().indexOf("IndexedStorage") > 0); - - stb.setId(1); - stb.initBasicProperties(); - stb.setStringProp("Hello"); - stb.insert(); - - stb = stbStorage.prepare(); - stb.setId(2); - stb.initBasicProperties(); - stb.setStringProp("Hello"); - stb.insert(); - - stb = stbStorage.prepare(); - stb.setId(3); - stb.initBasicProperties(); - stb.setStringProp("World"); - stb.insert(); - - Storage containerStorage = getRepository().storageFor(STBContainer.class); - - STBContainer container = containerStorage.prepare(); - container.setName("A"); - container.setCategory("Hello"); - container.setCount(2); - container.insert(); - - container = containerStorage.prepare(); - container.setName("B"); - container.setCategory("World"); - container.setCount(1); - container.insert(); - - // Test wrapping of query results - /* - container = containerStorage.prepare(); - container.setName("A"); - container.load(); - Cursor cursor = container.getContained().fetch(); - while (cursor.hasNext()) { - stb = cursor.next(); - assertTrue(stb.storage().getClass().getName().indexOf("IndexedStorage") > 0); - } - */ - } -} -- cgit v1.2.3