Author: aadamchik
Date: Sat Sep 2 06:22:28 2006
New Revision: 439589
URL: http://svn.apache.org/viewvc?rev=439589&view=rev
Log:
CAY-648
Added:
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/access/MiscTypesTst.java
Modified:
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/types/SerializableTypeFactory.java
Modified:
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java?rev=439589&r1=439588&r2=439589&view=diff
==============================================================================
---
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java
(original)
+++
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java
Sat Sep 2 06:22:28 2006
@@ -82,7 +82,7 @@
// note that Serializable type should be used as a last resort after
all other
// alternatives are exhausted.
- internalTypeFactories.add(new SerializableTypeFactory());
+ internalTypeFactories.add(new SerializableTypeFactory(this));
}
/**
Modified:
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/types/SerializableTypeFactory.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/types/SerializableTypeFactory.java?rev=439589&r1=439588&r2=439589&view=diff
==============================================================================
---
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/types/SerializableTypeFactory.java
(original)
+++
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/types/SerializableTypeFactory.java
Sat Sep 2 06:22:28 2006
@@ -18,15 +18,126 @@
****************************************************************/
package org.apache.cayenne.access.types;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.validation.ValidationResult;
+
/**
- * ExtendedTypeFactory for handling serializable objects.
+ * ExtendedTypeFactory for handling serializable objects. Returned
ExtendedType is simply
+ * an object serialization wrapper on top of byte[] ExtendedType.
*
* @since 3.0
* @author Andrus Adamchik
*/
class SerializableTypeFactory implements ExtendedTypeFactory {
+ private ExtendedTypeMap map;
+
+ SerializableTypeFactory(ExtendedTypeMap map) {
+ this.map = map;
+ }
+
public ExtendedType getType(Class objectClass) {
+
+ if (Serializable.class.isAssignableFrom(objectClass)) {
+ return new SerializableType(objectClass);
+ }
+
return null;
+ }
+
+ /**
+ * A serialization wrapper on top of byte[] ExtendedType
+ */
+ final class SerializableType implements ExtendedType {
+
+ private Class javaClass;
+ private ExtendedType bytesType;
+
+ SerializableType(Class javaClass) {
+ this.javaClass = javaClass;
+
+ // using a binary stream delegate instead of byte[] may actually
speed up
+ // things in some dbs, but at least byte[] type works consistently
across
+ // adapters...
+
+ this.bytesType = map.getRegisteredType(byte[].class);
+
+ // not sure if this condition ever occurs, but still worth
checking...
+ if (bytesType instanceof SerializableType) {
+ throw new IllegalStateException("No ExtendedType exists for
byte[]");
+ }
+ }
+
+ public String getClassName() {
+ return javaClass.getName();
+ }
+
+ public Object materializeObject(CallableStatement rs, int index, int
type)
+ throws Exception {
+
+ byte[] bytes = (byte[]) bytesType.materializeObject(rs, index,
type);
+ return readObject(bytes);
+ }
+
+ public Object materializeObject(ResultSet rs, int index, int type)
+ throws Exception {
+ byte[] bytes = (byte[]) bytesType.materializeObject(rs, index,
type);
+ return readObject(bytes);
+ }
+
+ public void setJdbcObject(
+ PreparedStatement statement,
+ Object value,
+ int pos,
+ int type,
+ int precision) throws Exception {
+
+ if (value == null) {
+ statement.setNull(pos, type);
+ }
+ else {
+ byte[] bytes = writeObject((Serializable) value);
+ bytesType.setJdbcObject(statement, bytes, pos, type,
precision);
+ }
+ }
+
+ public boolean validateProperty(
+ Object source,
+ String property,
+ Object value,
+ DbAttribute dbAttribute,
+ ValidationResult validationResult) {
+ return true;
+ }
+
+ private Object readObject(byte[] bytes) throws Exception {
+ return bytes != null && bytes.length > 0 ? new ObjectInputStream(
+ new ByteArrayInputStream(bytes)).readObject() : null;
+ }
+
+ private byte[] writeObject(Serializable object) throws Exception {
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream() {
+
+ // avoid unneeded array copy...
+ public synchronized byte[] toByteArray() {
+ return buf;
+ }
+ };
+
+ ObjectOutputStream out = new ObjectOutputStream(bytes);
+ out.writeObject(object);
+ out.close();
+
+ return bytes.toByteArray();
+ }
}
}
Added:
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/access/MiscTypesTst.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/access/MiscTypesTst.java?rev=439589&view=auto
==============================================================================
---
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/access/MiscTypesTst.java
(added)
+++
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/access/MiscTypesTst.java
Sat Sep 2 06:22:28 2006
@@ -0,0 +1,52 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+package org.apache.cayenne.access;
+
+import org.apache.art.SerializableEntity;
+import org.apache.cayenne.MockSerializable;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.unit.CayenneTestCase;
+
+public class MiscTypesTst extends CayenneTestCase {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ deleteTestData();
+ }
+
+ public void testSerializable() throws Exception {
+
+ DataContext context = createDataContext();
+
+ SerializableEntity test = (SerializableEntity) context
+ .newObject(SerializableEntity.class);
+
+ MockSerializable i = new MockSerializable("abc");
+ test.setSerializableField(i);
+ context.commitChanges();
+
+ SelectQuery q = new SelectQuery(SerializableEntity.class);
+ SerializableEntity testRead = (SerializableEntity)
context.performQuery(q).get(0);
+ assertNotNull(testRead.getSerializableField());
+ assertEquals(i.getName(), testRead.getSerializableField().getName());
+
+ test.setSerializableField(null);
+ context.commitChanges();
+ }
+}