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. --- .../carbonado/spi/StorableInterceptorFactory.java | 203 --------------------- .../carbonado/spi/TestConversionComparator.java | 179 ------------------ .../carbonado/spi/TestStorableSerializer.java | 115 ------------ .../carbonado/spi/TestWrappedStorableFactory.java | 164 ----------------- 4 files changed, 661 deletions(-) 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/java/com/amazon/carbonado/spi') 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