/* * JBoss, Home of Professional Open Source. * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. Some portions may be licensed * to Red Hat, Inc. under one or more contributor license agreements. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. */ package org.teiid.client; import java.io.EOFException; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.OptionalDataException; import java.io.Serializable; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.teiid.core.util.ExternalizeUtil; import org.teiid.jdbc.RequestOptions; import org.teiid.runtime.client.Messages; import org.teiid.runtime.client.TeiidClientException; /** * Request Message, used by MMXStatement for submitting queries. */ public class RequestMessage implements Externalizable { private static final RequestOptions DEFAULT_REQUEST_OPTIONS = new RequestOptions(); public static final int DEFAULT_FETCH_SIZE = 2048; /** Transaction auto wrap constant - never wrap a command execution in a transaction */ public static final String TXN_WRAP_OFF = "OFF"; //$NON-NLS-1$ /** Transaction auto wrap constant - always wrap commands in a transaction. */ public static final String TXN_WRAP_ON = "ON"; //$NON-NLS-1$ /** * Transaction auto wrap constant - checks if a command * requires a transaction and will be automatically wrap it. */ public static final String TXN_WRAP_DETECT = "DETECT"; //$NON-NLS-1$ public enum StatementType { PREPARED, CALLABLE, STATEMENT } public enum ResultsMode { RESULTSET, UPDATECOUNT, EITHER } public enum ShowPlan { ON, DEBUG, OFF } private String[] commands; private boolean isBatchedUpdate; private int fetchSize = DEFAULT_FETCH_SIZE; private int cursorType; private boolean partialResultsFlag; private StatementType statementType = StatementType.STATEMENT; private List<?> parameterValues; private boolean validationMode; private String txnAutoWrapMode; private String XMLFormat; private String styleSheet; private ResultsMode resultsMode = ResultsMode.EITHER; //whether to use ResultSet cache if there is one private boolean useResultSetCache; // Treat the double quoted strings as variables in the command private boolean ansiQuotedIdentifiers = true; private ShowPlan showPlan = ShowPlan.OFF; private int rowLimit; private Serializable executionPayload; private long executionId; private int transactionIsolation; private boolean noExec; private boolean autoGeneratedKeys; private boolean delaySerialization = true; /* * Used by embedded connections, could change if we add support * for an asynch socket transport */ private boolean sync; private RequestOptions requestOptions; private Object command; public RequestMessage() { } public RequestMessage(String command) { this(); setCommands(command); } public boolean isSync() { return sync; } public void setSync(boolean sync) { this.sync = sync; } public int getFetchSize() { return fetchSize; } public boolean supportsPartialResults() { return partialResultsFlag; } /** * @param i */ public void setFetchSize(int fetchSize) { this.fetchSize = fetchSize; } /** * @param partial */ public void setPartialResults(boolean partial) { partialResultsFlag = partial; } /** * @return True if this request includes a prepared statement. */ public boolean isPreparedStatement() { return this.statementType == StatementType.PREPARED; } /** * @return True if this request includes a callable statement. */ public boolean isCallableStatement() { return this.statementType == StatementType.CALLABLE; } public void setStatementType(StatementType statementType) { this.statementType = statementType; } /** * @return A list of parameter values. May be null. */ public List<?> getParameterValues() { if (parameterValues == null) { return Collections.EMPTY_LIST; } return parameterValues; } /** * @param values */ public void setParameterValues(List<?> values) { parameterValues = values; } /** * @return String */ public int getCursorType() { return cursorType; } /** * Sets the cursorType. * @param cursorType The cursorType to set */ public void setCursorType(int cursorType) { this.cursorType = cursorType; } /** * @return boolean */ public boolean getValidationMode() { return validationMode; } /** * @return String */ public String getXMLFormat() { return XMLFormat; } /** * Sets the validationMode. * @param validationMode The validationMode to set */ public void setValidationMode(boolean validationMode) { this.validationMode = validationMode; } /** * Sets the xMLFormat. * @param xMLFormat The xMLFormat to set */ public void setXMLFormat(String xMLFormat) { XMLFormat = xMLFormat; } /** * @return String */ public String getTxnAutoWrapMode() { if (txnAutoWrapMode == null) { return TXN_WRAP_DETECT; } return txnAutoWrapMode; } /** * Sets the txnAutoWrapMode. * @param txnAutoWrapMode The txnAutoWrapMode to set * @throws TeiidClientException */ public void setTxnAutoWrapMode(String txnAutoWrapMode) throws TeiidClientException { if (txnAutoWrapMode != null) { txnAutoWrapMode = txnAutoWrapMode.toUpperCase(); if (!(txnAutoWrapMode.equals(TXN_WRAP_OFF) || txnAutoWrapMode.equals(TXN_WRAP_ON) || txnAutoWrapMode.equals(TXN_WRAP_DETECT))) { throw new TeiidClientException(Messages.gs(Messages.TEIID.TEIID20000, txnAutoWrapMode)); } } this.txnAutoWrapMode = txnAutoWrapMode; } /** * @return String */ public String getStyleSheet() { return styleSheet; } /** * Sets the styleSheet. * @param styleSheet The styleSheet to set */ public void setStyleSheet(String styleSheet) { this.styleSheet = styleSheet; } public boolean useResultSetCache() { return useResultSetCache; } public void setUseResultSetCache(boolean useResultSetCacse) { this.useResultSetCache = useResultSetCacse; } public String getCommandString() { if (commands.length == 1) { return commands[0]; } return Arrays.deepToString(commands); } public boolean isAnsiQuotedIdentifiers() { return ansiQuotedIdentifiers; } public void setAnsiQuotedIdentifiers(boolean ansiQuotedIdentifiers) { this.ansiQuotedIdentifiers = ansiQuotedIdentifiers; } public ShowPlan getShowPlan() { return showPlan; } public void setShowPlan(ShowPlan showPlan) { this.showPlan = showPlan; } /** * @return Returns the rowLimit. * @since 4.3 */ public int getRowLimit() { return this.rowLimit; } /** * @param rowLimit The rowLimit to set. * @since 4.3 */ public void setRowLimit(int rowLimit) { this.rowLimit = rowLimit; } public String[] getCommands() { return commands; } public void setCommands(String... batchedCommands) { this.commands = batchedCommands; } public Object getCommand() { return command; } public void setCommand(Object command) { this.command = command; } public void setExecutionPayload(Serializable executionPayload) { this.executionPayload = executionPayload; } public Serializable getExecutionPayload() { return executionPayload; } public long getExecutionId() { return executionId; } public void setExecutionId(long executionId) { this.executionId = executionId; } public void setBatchedUpdate(boolean isBatchedUpdate) { this.isBatchedUpdate = isBatchedUpdate; } public boolean isBatchedUpdate() { return isBatchedUpdate; } public ResultsMode getResultsMode() { return resultsMode; } public void setResultsMode(ResultsMode resultsMode) { this.resultsMode = resultsMode; } public int getTransactionIsolation() { return transactionIsolation; } public void setTransactionIsolation(int transactionIsolation) { this.transactionIsolation = transactionIsolation; } public boolean isNoExec() { return noExec; } public void setNoExec(boolean noExec) { this.noExec = noExec; } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { this.commands = ExternalizeUtil.readStringArray(in); this.isBatchedUpdate = in.readBoolean(); this.fetchSize = in.readInt(); this.cursorType = in.readInt(); this.partialResultsFlag = in.readBoolean(); this.statementType = StatementType.values()[in.readByte()]; this.parameterValues = ExternalizeUtil.readList(in); this.validationMode = in.readBoolean(); this.txnAutoWrapMode = (String)in.readObject(); this.XMLFormat = (String)in.readObject(); this.styleSheet = (String)in.readObject(); this.resultsMode = ResultsMode.values()[in.readByte()]; this.useResultSetCache = in.readBoolean(); this.ansiQuotedIdentifiers = in.readBoolean(); this.showPlan = ShowPlan.values()[in.readByte()]; this.rowLimit = in.readInt(); this.executionPayload = (Serializable)in.readObject(); this.executionId = in.readLong(); this.transactionIsolation = in.readInt(); this.noExec = in.readBoolean(); try { byte options = in.readByte(); //8.3 property this.autoGeneratedKeys = (options & 1) == 1; //8.4 property this.delaySerialization = (options & 2) == 2; } catch (OptionalDataException e) { } catch (EOFException e) { } } @Override public void writeExternal(ObjectOutput out) throws IOException { ExternalizeUtil.writeArray(out, commands); out.writeBoolean(isBatchedUpdate); out.writeInt(fetchSize); out.writeInt(cursorType); out.writeBoolean(partialResultsFlag); out.writeByte(statementType.ordinal()); ExternalizeUtil.writeList(out, parameterValues); out.writeBoolean(validationMode); out.writeObject(txnAutoWrapMode); out.writeObject(XMLFormat); out.writeObject(styleSheet); out.writeByte(resultsMode.ordinal()); out.writeBoolean(useResultSetCache); out.writeBoolean(ansiQuotedIdentifiers); out.writeByte(showPlan.ordinal()); out.writeInt(rowLimit); out.writeObject(executionPayload); out.writeLong(executionId); out.writeInt(transactionIsolation); out.writeBoolean(noExec); byte options = 0; if (autoGeneratedKeys) { options |= 1; } if (delaySerialization) { options |= 2; } out.writeByte(options); } public RequestOptions getRequestOptions() { if (this.requestOptions == null) { this.requestOptions = DEFAULT_REQUEST_OPTIONS; } return this.requestOptions; } public void setRequestOptions(RequestOptions requestOptions) { this.requestOptions = requestOptions; } public void setReturnAutoGeneratedKeys(boolean autoGenerateKeys) { this.autoGeneratedKeys = autoGenerateKeys; } public boolean isReturnAutoGeneratedKeys() { return this.autoGeneratedKeys; } public boolean isDelaySerialization() { return delaySerialization; } public void setDelaySerialization(boolean delaySerialization) { this.delaySerialization = delaySerialization; } }