/******************************************************************************* | |
* Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved. | |
* This program and the accompanying materials are made available under the | |
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 | |
* which accompanies this distribution. | |
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html | |
* and the Eclipse Distribution License is available at | |
* http://www.eclipse.org/org/documents/edl-v10.php. | |
* | |
* Contributors: | |
* Oracle - initial API and implementation from Oracle TopLink | |
******************************************************************************/ | |
package org.eclipse.persistence.testing.tests.types; | |
import java.util.*; | |
import org.eclipse.persistence.descriptors.RelationalDescriptor; | |
import org.eclipse.persistence.sessions.Session; | |
import org.eclipse.persistence.tools.schemaframework.*; | |
import org.eclipse.persistence.testing.framework.*; | |
/** | |
* A Tester for BLOB data, treated as a byte array internally. | |
* NOTE: Direct attribute accessing for byte[] does not work (reflection problem) | |
*/ | |
public class BLOBTester extends TypeTester { | |
public byte[] bytes; | |
protected int length; | |
public BLOBTester() { | |
this(0); | |
} | |
public BLOBTester(int numBytes) { | |
super("BLOB(" + numBytes + ")"); | |
length = numBytes; | |
bytes = null; | |
} | |
private String buildName() { | |
return "BLOB(" + length + ")"; | |
} | |
public static RelationalDescriptor descriptor() { | |
RelationalDescriptor descriptor = new RelationalDescriptor(); | |
/* First define the class, table and descriptor properties. */ | |
descriptor.setJavaClass(BLOBTester.class); | |
descriptor.setTableName("BLOBS"); | |
descriptor.setPrimaryKeyFieldName("NAME"); | |
/* Next define the attribute mappings. */ | |
descriptor.addDirectMapping("testName", "getTestName", "setTestName", "NAME"); | |
//MySQL gets confused when reserved words are used as a name such as BLOB. Changed to BLOB_ | |
descriptor.addDirectMapping("bytes", "BLOB_"); | |
return descriptor; | |
} | |
public static RelationalDescriptor descriptorWithAccessors() { | |
RelationalDescriptor descriptor = new RelationalDescriptor(); | |
/* First define the class, table and descriptor properties. */ | |
descriptor.setJavaClass(BLOBTester.class); | |
descriptor.setTableName("BLOBS"); | |
descriptor.setPrimaryKeyFieldName("NAME"); | |
/* Next define the attribute mappings. */ | |
descriptor.addDirectMapping("testName", "getTestName", "setTestName", "NAME"); | |
descriptor.addDirectMapping("bytes", "getBytes", "setBytes", "BLOB_"); | |
return descriptor; | |
} | |
public byte[] getBytes() { | |
return bytes; | |
} | |
public void setBytes(byte[] newBytes) { | |
length = newBytes.length; | |
bytes = newBytes; | |
} | |
public void setup(Session session) { | |
// Access does not support BLOBS or CLOBS | |
if (session.getPlatform().isAccess()) { | |
throw new TestWarningException("Access and DB2 do not support BLOBS or CLOBS."); | |
} | |
if (bytes == null) { | |
bytes = new byte[length]; | |
new Random().nextBytes(bytes); | |
} | |
} | |
/** | |
*Return a platform independant definition of the database table. | |
*/ | |
public static TableDefinition tableDefinition(Session session) { | |
TableDefinition definition = TypeTester.tableDefinition(); | |
definition.setName("BLOBS"); | |
definition.addField("BLOB_", Byte[].class, 33000); | |
return definition; | |
} | |
/** | |
* Catch null point that occurs frequently an make as warning (known bug). | |
*/ | |
protected void test(WriteTypeObjectTest testCase) throws TestWarningException { | |
try { | |
super.test(testCase); | |
} catch (NullPointerException e) { | |
throw new TestWarningException("Blob value was returned as null, this means the drivers max size was exceeded." + org.eclipse.persistence.internal.helper.Helper.cr() + caughtException); | |
} | |
} | |
public static Vector testInstances() { | |
Vector tests = new Vector(); | |
tests.addElement(new BLOBTester(1000)); | |
tests.addElement(new BLOBTester(5000)); | |
tests.addElement(new BLOBTester(10000)); | |
tests.addElement(new BLOBTester(25000)); | |
tests.addElement(new BLOBTester(32768)); | |
tests.addElement(new BLOBTester(33000)); | |
return tests; | |
} | |
public String toString() { | |
if (getTestName().equals(buildName())) { | |
return getTestName(); | |
} else { | |
return getTestName() + " {" + length + "}"; | |
} | |
} | |
protected void verify(WriteTypeObjectTest testCase) throws TestException { | |
try { | |
super.verify(testCase); | |
} catch (TestException e) { | |
// JConnect does not support non-native BLOBs | |
if ((caughtException != null) && (caughtException.toString().indexOf("JZ0S8: An escape sequence") != -1)) { | |
throw new TestProblemException("JConnect does not do BLOBs in non-native SQL:\n" + caughtException.getInternalException()); | |
} | |
// In VA/Java setting array object reflectivey throws an exception | |
if ((e.getInternalException() != null) && (e.getInternalException().getClass() == IllegalAccessException.class)) { | |
try { | |
Class.forName("com.ibm.uvm.tools.DebugSupport"); | |
throw new TestWarningException("IllegalAccessException attempting to reflectively set byte[]"); | |
} catch (ClassNotFoundException ce) { | |
} | |
} | |
BLOBTester original = (BLOBTester)testCase.getOriginalObject(); | |
BLOBTester database = (BLOBTester)testCase.getObjectFromDatabase(); | |
if (database == null) { | |
throw new TestWarningException("Write of BLOB failed, nothing was written or read.\n" + caughtException); | |
} | |
if ((database.getBytes() != null) && (original.getBytes().length == database.getBytes().length)) { | |
int numGood = 0; | |
for (int index = 0; index < original.getBytes().length; index++) { | |
if (original.getBytes()[index] == database.getBytes()[index]) { | |
numGood++; | |
} | |
} | |
throw new TestWarningException("Two BLOBs did not match, " + numGood + " bytes matched"); | |
} | |
throw new TestWarningException("Blobs just suck with this driver or max size exceeded, \n" + e); | |
} | |
} | |
} |