/** {@inheritDoc} */ @Override public ActionForward execute( @SuppressWarnings("unused") ActionMapping mapping, @SuppressWarnings("unused") ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { HttpSession session = request.getSession(); final InterMineAPI im = SessionMethods.getInterMineAPI(session); ObjectStore os = im.getObjectStore(); WebConfig webConfig = SessionMethods.getWebConfig(request); Integer objectId = new Integer(request.getParameter("object")); String fieldName = request.getParameter("field"); String fileType = request.getParameter("type"); InterMineObject object = os.getObjectById(objectId); FieldExporter fieldExporter = null; Set classes = DynamicUtil.decomposeClass(object.getClass()); Iterator classIter = classes.iterator(); while (classIter.hasNext()) { Class c = (Class) classIter.next(); Type thisTypeConfig = webConfig.getTypes().get(c.getName()); FieldConfig fc = thisTypeConfig.getFieldConfigMap().get(fieldName); if (fc != null) { String fieldExporterClassName = fc.getFieldExporter(); if (fieldExporterClassName != null) { fieldExporter = (FieldExporter) Class.forName(fieldExporterClassName).newInstance(); break; } } } if (fieldExporter == null) { Object fieldValue = object.getFieldValue(fieldName); if (fileType == null || fileType.length() == 0) { response.setContentType("text/plain; charset=UTF-8"); response.setHeader("Content-Disposition ", "inline; filename=" + fieldName + ".txt"); } else { response.setContentType("text/" + fileType); response.setHeader( "Content-Disposition ", "inline; filename=" + fieldName + "." + fileType); } PrintStream out = new PrintStream(response.getOutputStream()); if (fieldValue instanceof ClobAccess) { ((ClobAccess) fieldValue).drainToPrintStream(out); } else { out.print(fieldValue); } out.flush(); } else { fieldExporter.exportField(object, fieldName, os, response); } return null; }
/** * 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()); }