/** * Decodes a String from the database representing a clob object. See getDbDescription(). * * @param os an ObjectStore that the clob is stored in * @param description the description from the database * @return a ClobAccess object, or a subclass */ public static ClobAccess decodeDbDescription(ObjectStore os, String description) { String[] parts = description.split(","); ClobAccess clob = new ClobAccess(os, new Clob(Integer.parseInt(parts[0]))); if (parts.length >= 3) { int offset = Integer.parseInt(parts[1]); int length = Integer.parseInt(parts[2]); clob = clob.subSequence(offset, offset + length); } String className = null; if (parts.length == 2) { className = parts[1]; } else if (parts.length == 4) { className = parts[3]; } if (className != null) { // So, className is a class that extends ClobAccess. We expect there to be a static // method called getFactory() that returns a ClobAccessSubclassFactory object that we // can store in a cache, which will call the constructor quickly. Map<String, ClobAccessSubclassFactory> factoryCache = subclassFactoryCache.get(); ClobAccessSubclassFactory factory = factoryCache.get(className); if (factory == null) { try { Class<?> subclass = Class.forName(className); Method subMethod = subclass.getMethod("getFactory"); factory = (ClobAccessSubclassFactory) subMethod.invoke(null); factoryCache.put(className, factory); } catch (ClassNotFoundException e) { throw new RuntimeException( "Could not read Clob subclass " + className + " from database.", e); } catch (NoSuchMethodException e) { throw new RuntimeException( "Could not read Clob subclass " + className + " from database.", e); } catch (InvocationTargetException e) { throw new RuntimeException( "Could not read Clob subclass " + className + " from database.", e); } catch (IllegalAccessException e) { throw new RuntimeException( "Could not read Clob subclass " + className + " from database.", e); } } clob = factory.invokeConstructor(clob); } return clob; }
public void testClob() throws Exception { Clob clob = writer.createClob(); writer.replaceClob(clob, "Monkey"); ClobAccess ca = new ClobAccess(writer, clob); assertEquals("Monkey", ca.toString()); StringBuilder longString = new StringBuilder(); for (int i = 0; i < 10000; i++) { longString.append("Lots of monkeys. "); } writer.replaceClob(clob, longString.toString()); assertEquals("Monkey", ca.toString()); ca = new ClobAccess(writer, clob); assertEquals(170000, ca.length()); assertEquals(longString.toString(), ca.toString()); assertEquals('L', ca.charAt(1700)); assertEquals('L', ca.charAt(16983)); ClobAccess sub = ca.subSequence(85000, 85016); assertEquals("Lots of monkeys.", sub.toString()); assertEquals(16, sub.length()); }