public void process(XPathContext context) throws XPathException { // Prepare the SQL statement (only do this once) Controller controller = context.getController(); Item conn = arguments[CONNECTION].evaluateItem(context); if (!(conn instanceof ObjectValue && ((ObjectValue) conn).getObject() instanceof Connection)) { DynamicError de = new DynamicError("Value of connection expression is not a JDBC Connection"); de.setXPathContext(context); throw de; } Connection connection = (Connection) ((ObjectValue) conn).getObject(); String dbCol = arguments[COLUMN].evaluateAsString(context); String dbTab = arguments[TABLE].evaluateAsString(context); String dbWhere = arguments[WHERE].evaluateAsString(context); NamePool pool = controller.getNamePool(); int rowCode = pool.allocate("", "", rowTag); int colCode = pool.allocate("", "", colTag); PreparedStatement ps = null; ResultSet rs = null; DynamicError de = null; try { StringBuffer statement = new StringBuffer(); statement.append("SELECT " + dbCol + " FROM " + dbTab); if (dbWhere != "") { statement.append(" WHERE " + dbWhere); } // System.err.println("-> SQL: " + statement.toString()); // -- Prepare the SQL statement ps = connection.prepareStatement(statement.toString()); controller.setUserData(this, "sql:statement", ps); // -- Execute Statement rs = ps.executeQuery(); // -- Print out Result Receiver out = context.getReceiver(); String result = ""; int icol = rs.getMetaData().getColumnCount(); while (rs.next()) { // next row // System.out.print("<- SQL : "+ rowStart); out.startElement(rowCode, StandardNames.XDT_UNTYPED, locationId, 0); for (int col = 1; col <= icol; col++) { // next column // Read result from RS only once, because // of JDBC-Specifications result = rs.getString(col); out.startElement(colCode, StandardNames.XDT_UNTYPED, locationId, 0); if (result != null) { out.characters(result, locationId, options); } out.endElement(); } // System.out.println(rowEnd); out.endElement(); } // rs.close(); if (!connection.getAutoCommit()) { connection.commit(); } } catch (SQLException ex) { de = new DynamicError("(SQL) " + ex.getMessage()); de.setXPathContext(context); throw de; } finally { boolean wasDEThrown = (de != null); if (rs != null) { try { rs.close(); } catch (SQLException ex) { de = new DynamicError("(SQL) " + ex.getMessage()); de.setXPathContext(context); } } if (ps != null) { try { ps.close(); } catch (SQLException ex) { de = new DynamicError("(SQL) " + ex.getMessage()); de.setXPathContext(context); } } if (!wasDEThrown && de != null) { throw de; // test so we don't lose the real exception } } }
/** Enumerate the results of the expression */ public SequenceIterator iterate(XPathContext context) throws XPathException { Controller controller = context.getController(); Item arg2; try { arg2 = argument[2].evaluateItem(context); } catch (XPathException e) { if ("XPDY0002".equals(e.getErrorCodeLocalPart())) { dynamicError( "Cannot call the key() function when there is no context item", "XTDE1270", context); return null; } else if ("XPDY0050".equals(e.getErrorCodeLocalPart())) { dynamicError( "In the key() function," + " the node supplied in the third argument (or the context node if absent)" + " must be in a tree whose root is a document node", "XTDE1270", context); return null; } else if ("XPTY0020".equals(e.getErrorCodeLocalPart())) { dynamicError( "Cannot call the key() function when the context item is an atomic value", "XTDE1270", context); return null; } throw e; } NodeInfo origin = (NodeInfo) arg2; NodeInfo root = origin.getRoot(); if (root.getNodeKind() != Type.DOCUMENT) { dynamicError( "In the key() function," + " the node supplied in the third argument (or the context node if absent)" + " must be in a tree whose root is a document node", "XTDE1270", context); return null; } DocumentInfo doc = (DocumentInfo) root; int fprint = keyFingerprint; if (fprint == -1) { String givenkeyname = argument[0].evaluateItem(context).getStringValue(); try { fprint = controller .getNamePool() .allocateLexicalQName( givenkeyname, false, nsContext, controller.getConfiguration().getNameChecker()) & NamePool.FP_MASK; } catch (XPathException err) { dynamicError("Invalid key name: " + err.getMessage(), "XTDE1260", context); } if (fprint == -1) { dynamicError("Key '" + givenkeyname + "' has not been defined", "XTDE1260", context); return null; } } // if (internal) { // System.err.println("Using key " + fprint + " on doc " + doc); // } // If the second argument is a singleton, we evaluate the function // directly; otherwise we recurse to evaluate it once for each Item // in the sequence. Expression expression = argument[1]; SequenceIterator allResults; if (Cardinality.allowsMany(expression.getCardinality())) { final XPathContext keyContext = context; final DocumentInfo document = doc; final KeyManager keyManager = controller.getKeyManager(); MappingFunction map = new MappingFunction() { // Map a value to the sequence of nodes having that value as a key value public Object map(Item item) throws XPathException { return keyManager.selectByKey( keyFingerprint, document, (AtomicValue) item, keyContext); } }; SequenceIterator keys = argument[1].iterate(context); SequenceIterator allValues = new MappingIterator(keys, map); allResults = new DocumentOrderIterator(allValues, LocalOrderComparer.getInstance()); } else { try { AtomicValue keyValue = (AtomicValue) argument[1].evaluateItem(context); if (keyValue == null) { return EmptyIterator.getInstance(); } KeyManager keyManager = controller.getKeyManager(); allResults = keyManager.selectByKey(fprint, doc, keyValue, context); } catch (XPathException e) { if (e.getLocator() == null) { e.setLocator(this); } throw e; } } if (origin == doc) { return allResults; } SubtreeFilter filter = new SubtreeFilter(); filter.origin = origin; return new ItemMappingIterator(allResults, filter); }