/* Copyright 2013 Nationale-Nederlanden Licensed 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 nl.nn.adapterframework.jdbc; import java.io.Reader; import java.sql.ResultSet; import java.sql.SQLException; import nl.nn.adapterframework.core.SenderException; /** * Pipe that iterates over the lines in a clob. * * <p><b>Configuration:</b> * <table border="1"> * <tr><th>attributes</th><th>description</th><th>default</th></tr> * <tr><td>className</td><td>nl.nn.adapterframework.jdbc.ClobLineIteratingPipe</td><td> </td></tr> * <tr><td>{@link #setName(String) name}</td><td>name of the Pipe</td><td> </td></tr> * <tr><td>{@link #setMaxThreads(int) maxThreads}</td><td>maximum number of threads that may call {@link #doPipe(java.lang.Object, nl.nn.adapterframework.core.IPipeLineSession)} simultaneously</td><td>0 (unlimited)</td></tr> * <tr><td>{@link #setDurationThreshold(long) durationThreshold}</td><td>if durationThreshold >=0 and the duration (in milliseconds) of the message processing exceeded the value specified the message is logged informatory</td><td>-1</td></tr> * <tr><td>{@link #setGetInputFromSessionKey(String) getInputFromSessionKey}</td><td>when set, input is taken from this session key, instead of regular input</td><td> </td></tr> * <tr><td>{@link #setStoreResultInSessionKey(String) storeResultInSessionKey}</td><td>when set, the result is stored under this session key</td><td> </td></tr> * <tr><td>{@link #setCheckXmlWellFormed(boolean) checkXmlWellFormed}</td><td>when set <code>true</code>, the XML well-formedness of the result is checked</td><td>false</td></tr> * <tr><td>{@link #setPreserveInput(boolean) preserveInput}</td><td>when set <code>true</code>, the input of a pipe is restored before processing the next one</td><td>false</td></tr> * <tr><td>{@link #setNamespaceAware(boolean) namespaceAware}</td><td>controls namespaceAwareness for parameters</td><td>application default</td></tr> * <tr><td>{@link #setTransactionAttribute(String) transactionAttribute}</td><td>Defines transaction and isolation behaviour. Equal to <A href="http://java.sun.com/j2ee/sdk_1.2.1/techdocs/guides/ejb/html/Transaction2.html#10494">EJB transaction attribute</a>. Possible values are: * <table border="1"> * <tr><th>transactionAttribute</th><th>callers Transaction</th><th>Pipe excecuted in Transaction</th></tr> * <tr><td colspan="1" rowspan="2">Required</td> <td>none</td><td>T2</td></tr> * <tr><td>T1</td> <td>T1</td></tr> * <tr><td colspan="1" rowspan="2">RequiresNew</td> <td>none</td><td>T2</td></tr> * <tr><td>T1</td> <td>T2</td></tr> * <tr><td colspan="1" rowspan="2">Mandatory</td> <td>none</td><td>error</td></tr> * <tr><td>T1</td> <td>T1</td></tr> * <tr><td colspan="1" rowspan="2">NotSupported</td><td>none</td><td>none</td></tr> * <tr><td>T1</td> <td>none</td></tr> * <tr><td colspan="1" rowspan="2">Supports</td> <td>none</td><td>none</td></tr> * <tr><td>T1</td> <td>T1</td></tr> * <tr><td colspan="1" rowspan="2">Never</td> <td>none</td><td>none</td></tr> * <tr><td>T1</td> <td>error</td></tr> * </table></td><td> </td></tr> * <tr><td>{@link #setForwardName(String) forwardName}</td> <td>name of forward returned upon completion</td><td>"success"</td></tr> * <tr><td>{@link #setResultOnTimeOut(String) resultOnTimeOut}</td><td>result returned when no return-message was received within the timeout limit (e.g. "receiver timed out").</td><td> </td></tr> * <tr><td>{@link #setLinkMethod(String) linkMethod}</td><td>Indicates wether the server uses the correlationID or the messageID in the correlationID field of the reply</td><td>CORRELATIONID</td></tr> * <tr><td>{@link #setAuditTrailXPath(String) auditTrailXPath}</td><td>xpath expression to extract audit trail from message</td><td> </td></tr> * <tr><td>{@link #setCorrelationIDXPath(String) correlationIDXPath}</td><td>xpath expression to extract correlationID from message</td><td> </td></tr> * <tr><td>{@link #setStopConditionXPathExpression(String) stopConditionXPathExpression}</td><td>expression evaluated on each result if set. * Iteration stops if condition returns anything other than <code>false</code> or an empty result. * For example, to stop after the second child element has been processed, one of the following expressions could be used: * <table> * <tr><td><li><code>result[@item='2']</code></td><td>returns result element after second child element has been processed</td></tr> * <tr><td><li><code>result/@item='2'</code></td><td>returns <code>false</code> after second child element has been processed, <code>true</code> for others</td></tr> * </table> * </td><td> </td></tr> * <tr><td>{@link #setRemoveXmlDeclarationInResults(boolean) removeXmlDeclarationInResults}</td><td>postprocess each partial result, to remove the xml-declaration, as this is not allowed inside an xml-document</td><td>false</td></tr> * <tr><td>{@link #setCollectResults(boolean) collectResults}</td><td>controls whether all the results of each iteration will be collected in one result message. If set <code>false</code>, only a small summary is returned</td><td>true</td></tr> * <tr><td>{@link #setQuery(String) query}</td><td>the SQL query text</td><td> </td></tr> * <tr><td>{@link #setDatasourceName(String) datasourceName}</td><td>can be configured from JmsRealm, too</td><td> </td></tr> * <tr><td>{@link #setBlockSize(int) blockSize}</td><td>controls multiline behaviour. when set to a value greater than 0, it specifies the number of rows send in a block to the sender.</td><td>0 (one line at a time, no prefix of suffix)</td></tr> * <tr><td>{@link #setBlockPrefix(String) blockPrefix}</td><td>When <code>blockSize > 0</code>, this string is inserted at the start of the set of lines.</td><td><block></td></tr> * <tr><td>{@link #setBlockSuffix(String) blockSuffix}</td><td>When <code>blockSize > 0</code>, this string is inserted at the end of the set of lines.</td><td></block></td></tr> * </table> * <table border="1"> * <tr><th>nested elements</th><th>description</th></tr> * <tr><td>{@link nl.nn.adapterframework.core.ISender sender}</td><td>specification of sender to send messages with</td></tr> * <tr><td>{@link nl.nn.adapterframework.core.ICorrelatedPullingListener listener}</td><td>specification of listener to listen to for replies</td></tr> * <tr><td>{@link nl.nn.adapterframework.parameters.Parameter param}</td><td>any parameters defined on the pipe will be handed to the sender, if this is a {@link nl.nn.adapterframework.core.ISenderWithParameters ISenderWithParameters}</td></tr> * <tr><td><code>inputValidator</code></td><td>specification of Pipe to validate input messages</td></tr> * <tr><td><code>outputValidator</code></td><td>specification of Pipe to validate output messages</td></tr> * <tr><td>{@link nl.nn.adapterframework.core.ITransactionalStorage messageLog}</td><td>log of all messages sent</td></tr> * </table> * </p> * <p><b>Exits:</b> * <table border="1"> * <tr><th>state</th><th>condition</th></tr> * <tr><td>"success"</td><td>default when a good message was retrieved (synchronous sender), or the message was successfully sent and no listener was specified and the sender was not synchronous</td></tr> * <tr><td><i>{@link #setForwardName(String) forwardName}</i></td><td>if specified, and otherwise under same condition as "success"</td></tr> * <tr><td>"timeout"</td><td>no data was received (timeout on listening), if the sender was synchronous or a listener was specified.</td></tr> * <tr><td>"exception"</td><td>an exception was thrown by the Sender or its reply-Listener. The result passed to the next pipe is the exception that was caught.</td></tr> * </table> * </p> * * * @author Gerrit van Brakel * @since 4.7 */ public class ClobLineIteratingPipe extends LobLineIteratingPipeBase { protected Reader getReader(ResultSet rs) throws SenderException { try { return rs.getCharacterStream(1); } catch (SQLException e) { throw new SenderException(e); } } }