You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beehive.apache.org by ek...@apache.org on 2005/05/09 22:18:03 UTC
svn commit: r169351 [8/12] - in /incubator/beehive/trunk/system-controls: ./
ant/ external/ external/commons/ external/ejb/ external/jms/ src/ src/ejb/
src/ejb/org/ src/ejb/org/apache/ src/ejb/org/apache/beehive/
src/ejb/org/apache/beehive/controls/
src/ejb/org/apache/beehive/controls/system/
src/ejb/org/apache/beehive/controls/system/ejb/ src/ejb/schema/ src/jdbc/
src/jdbc/org/ src/jdbc/org/apache/ src/jdbc/org/apache/beehive/
src/jdbc/org/apache/beehive/controls/
src/jdbc/org/apache/beehive/controls/system/
src/jdbc/org/apache/beehive/controls/system/jdbc/
src/jdbc/org/apache/beehive/controls/system/jdbc/parser/ src/jms/
src/jms/org/ src/jms/org/apache/ src/jms/org/apache/beehive/
src/jms/org/apache/beehive/controls/
src/jms/org/apache/beehive/controls/system/
src/jms/org/apache/beehive/controls/system/jms/
src/jms/org/apache/beehive/controls/system/jms/impl/
src/jms/org/apache/beehive/controls/system/jndi/
src/jms/org/apache/beehive/controls/system/jndi/impl/ src/webservice/
src/webservice/org/ src/webservice/org/apache/
src/webservice/org/apache/beehive/
src/webservice/org/apache/beehive/controls/
src/webservice/org/apache/beehive/controls/system/
src/webservice/org/apache/beehive/controls/system/webservice/
src/webservice/org/apache/beehive/controls/system/webservice/generator/
src/webservice/org/apache/beehive/controls/system/webservice/jaxrpc/
src/webservice/org/apache/beehive/controls/system/webservice/utils/ test/
test/ant/ test/conf/ test/src/ test/src/jdbc/ test/src/jdbc/controls/
test/src/jdbc/controls/org/ test/src/jdbc/controls/org/apache/
test/src/jdbc/controls/org/apache/beehive/
test/src/jdbc/controls/org/apache/beehive/controls/
test/src/jdbc/controls/org/apache/beehive/controls/system/
test/src/jdbc/controls/org/apache/beehive/controls/system/jdbc/
test/src/jdbc/controls/org/apache/beehive/controls/system/jdbc/test/
test/src/jdbc/controls/org/apache/beehive/controls/system/jdbc/test/dbconnection/
test/src/jdbc/controls/org/apache/beehive/controls/system/jdbc/test/errors/
test/src/jdbc/controls/org/apache/beehive/controls/system/jdbc/test/results/
test/src/jdbc/controls/schemas/ test/src/jdbc/controls/schemas/badusers/
test/src/jdbc/controls/schemas/users/ test/src/jdbc/jdbc-container/
test/src/jdbc/jdbc-container/application/ test/src/jdbc/jdbc-container/src/
test/src/jdbc/jdbc-container/src/org/
test/src/jdbc/jdbc-container/src/org/apache/
test/src/jdbc/jdbc-container/src/org/apache/beehive/
test/src/jdbc/jdbc-container/src/org/apache/beehive/controls/
test/src/jdbc/jdbc-container/src/org/apache/beehive/controls/system/
test/src/jdbc/jdbc-container/src/org/apache/beehive/controls/system/jdbc/
test/src/jdbc/jdbc-container/src/org/apache/beehive/controls/system/jdbc/containertest/
test/src/jdbc/jdbc-container/webapp/
test/src/jdbc/jdbc-container/webapp/WEB-INF/
test/src/jdbc/jdbc-container/webapp/conf/
test/src/jdbc/jdbc-container/webapp/conf/Catalina/
test/src/jdbc/jdbc-container/webapp/conf/Catalina/localhost/
test/src/jdbc/junitTests/ test/src/jdbc/junitTests/org/
test/src/jdbc/junitTests/org/apache/
test/src/jdbc/junitTests/org/apache/beehive/
test/src/jdbc/junitTests/org/apache/beehive/controls/
test/src/jdbc/junitTests/org/apache/beehive/controls/system/
test/src/jdbc/junitTests/org/apache/beehive/controls/system/jdbc/
test/src/jdbc/junitTests/org/apache/beehive/controls/system/jdbc/units/
test/src/jdbc/junitTests/org/apache/beehive/controls/system/jdbc/units/dbconnection/
test/src/jdbc/junitTests/org/apache/beehive/controls/system/jdbc/units/errors/
test/src/jdbc/junitTests/org/apache/beehive/controls/system/jdbc/units/results/
test/src/jdbc/junitTests/org/apache/beehive/controls/system/jdbc/units/sqlparser/
test/src/jdbc/junitTests/org/apache/beehive/controls/system/jdbc/units/utils/
Added: incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlStatement.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlStatement.java?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlStatement.java (added)
+++ incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlStatement.java Mon May 9 13:17:58 2005
@@ -0,0 +1,522 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+
+package org.apache.beehive.controls.system.jdbc.parser;
+
+import org.apache.beehive.controls.api.ControlException;
+import org.apache.beehive.controls.api.context.ControlBeanContext;
+import org.apache.beehive.controls.system.jdbc.JdbcControl;
+import org.apache.beehive.controls.system.jdbc.TypeMappingsFactory;
+
+import javax.sql.RowSet;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import java.util.Calendar;
+
+/**
+ * Represents a fully parsed SQL statement. SqlStatements can be used to generated a java.sql.PreparedStatement.
+ */
+public final class SqlStatement extends SqlFragmentContainer implements Serializable {
+
+ private static final TypeMappingsFactory _tmf = TypeMappingsFactory.getInstance();
+ private boolean _callableStatement = false;
+ private boolean _cacheableStatement = true;
+
+ //
+ // set from SQL annotation element values
+ //
+ private boolean _batchUpdate;
+ private boolean _getGeneratedKeys;
+ private String[] _genKeyColumnNames;
+ private int _fetchSize;
+ private int _maxArray;
+ private int _maxRows;
+ private int[] _genKeyColumnIndexes;
+ private JdbcControl.ScrollType _scrollType;
+ private JdbcControl.FetchDirection _fetchDirection;
+ private JdbcControl.HoldabilityType _holdability;
+
+ /**
+ * Create a new SqlStatement.
+ */
+ SqlStatement() {
+ super();
+ }
+
+ /**
+ * Append a SqlFragment to the end of this statement.
+ *
+ * @param frag SqlFragment to append.
+ */
+ void addChild(SqlFragment frag) {
+ super.addChild(frag);
+
+ if (frag.isDynamicFragment()) {
+ _cacheableStatement = false;
+ }
+ }
+
+
+ /**
+ * Can the PreparedStatement generated by this class be cached?
+ *
+ * @return true if this statement can be cached by the SqlParser.
+ */
+ boolean isCacheable() { return _cacheableStatement; }
+
+
+ /**
+ * Does this statement generate a callable or prepared statement?
+ *
+ * @return true if this statement generates callable statement.
+ */
+ public boolean isCallableStatement() { return _callableStatement; }
+
+ /**
+ * Does this statement do a batch update?
+ *
+ * @return true if this statement should be executed as a batch update.
+ */
+ public boolean isBatchUpdate() { return _batchUpdate; }
+
+ /**
+ * Does this statement return generatedKeys?
+ *
+ * @return true if getGeneratedKeys set to true.
+ */
+ public boolean getsGeneratedKeys() { return _getGeneratedKeys; }
+
+ /**
+ * Generates the PreparedStatement the SQL statement.
+ *
+ * @param context ControlBeanContext instance.
+ * @param connection Connection to database.
+ * @param calendar Calendar instance which can be used to resolve date/time values.
+ * @param method Method the SQL is associated with.
+ * @param arguments Method parameters.
+ * @return The PreparedStatement generated by this statement.
+ * @throws SQLException If PreparedStatement cannot be created.
+ */
+ public PreparedStatement createPreparedStatement(ControlBeanContext context, Connection connection,
+ Calendar calendar, Method method, Object[] arguments)
+ throws SQLException {
+
+ PreparedStatement preparedStatement = null;
+ loadSQLAnnotationStatmentOptions(context, method);
+ checkJdbcSupport(connection.getMetaData());
+
+ _callableStatement = setCallableStatement(arguments);
+
+ try {
+ final String sql = getPreparedStatementText(context, method, arguments);
+
+ //
+ // is this a request for generatedKeys ?
+ //
+ if (_getGeneratedKeys) {
+
+ if (_callableStatement) {
+ throw new ControlException("getGeneratedKeys not supported for CallableStatements");
+ }
+
+ if (_genKeyColumnNames.length > 0) {
+ preparedStatement = connection.prepareStatement(sql, _genKeyColumnNames);
+ } else if (_genKeyColumnIndexes.length > 0) {
+ preparedStatement = connection.prepareStatement(sql, _genKeyColumnIndexes);
+ } else {
+ preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
+ }
+
+ } else {
+
+ if (_holdability == JdbcControl.HoldabilityType.DRIVER_DEFAULT) {
+ if (_scrollType == JdbcControl.ScrollType.DRIVER_DEFAULT) {
+ preparedStatement = (_callableStatement) ? connection.prepareCall(sql) : connection.prepareStatement(sql);
+ } else {
+ preparedStatement = (_callableStatement)
+ ? connection.prepareCall(sql, _scrollType.getType(), _scrollType.getConcurrencyType())
+ : connection.prepareStatement(sql, _scrollType.getType(), _scrollType.getConcurrencyType());
+ }
+ } else {
+ preparedStatement = (_callableStatement)
+ ? connection.prepareCall(sql, _scrollType.getType(), _scrollType.getConcurrencyType(), _holdability.getHoldability())
+ : connection.prepareStatement(sql, _scrollType.getType(), _scrollType.getConcurrencyType(), _holdability.getHoldability());
+ }
+ }
+
+ //
+ // If the method argument is of type SQLParameter, treat this statement as a CallableStatement,
+ //
+ if (_callableStatement) {
+ for (SqlFragment sf : _children) {
+ if (sf.hasParamValue()) {
+ throw new ControlException("Cannot use parameter substution and SQLParameter array in the same method.");
+ }
+ }
+ JdbcControl.SQLParameter[] params = (JdbcControl.SQLParameter[]) arguments[0];
+ if (params == null) {
+ return preparedStatement;
+ }
+ for (int i = 0; i < params.length; i++) {
+ JdbcControl.SQLParameter p = params[i];
+ if (p.dir != JdbcControl.SQLParameter.OUT) {
+ Object value = params[i].value;
+ setPreparedStatementParameter(preparedStatement, i + 1, value, params[i].type, calendar);
+ }
+
+ if (p.dir != JdbcControl.SQLParameter.IN) {
+ ((CallableStatement) preparedStatement).registerOutParameter(i + 1, params[i].type);
+ }
+ }
+
+
+ //
+ // special handling for batch updates
+ //
+ } else if (_batchUpdate) {
+ doBatchUpdate(preparedStatement, arguments, calendar);
+
+
+ //
+ // standard case, not a batch or callable
+ //
+ } else {
+ int pIndex = 1;
+ for (SqlFragment sf : _children) {
+ if (sf.hasParamValue()) {
+ Object values[] = sf.getParameterValues(context, method, arguments);
+ for (Object value : values) {
+ setPreparedStatementParameter(preparedStatement, pIndex++, value, sf.getParamSqlDataType(), calendar);
+ }
+ }
+ }
+ }
+ } catch (SQLException e) {
+ if (preparedStatement != null) preparedStatement.close();
+ throw e;
+ }
+
+ preparedStatement.setFetchDirection(_fetchDirection.getDirection());
+ preparedStatement.setFetchSize(_fetchSize);
+ preparedStatement.setMaxRows(computeMaxRows(method));
+
+ return preparedStatement;
+ }
+
+ /**
+ * Generates the PreparedStatement the SQL statement.
+ *
+ * @param context ControlBeanContext instance.
+ * @param connection Connection to database.
+ * @param method Method the SQL is associated with.
+ * @param arguments Method parameters.
+ * @return The PreparedStatement generated by this statement.
+ */
+ public String createPreparedStatementString(ControlBeanContext context, Connection connection,
+ Method method, Object[] arguments) {
+
+ final boolean callableStatement = setCallableStatement(arguments);
+ StringBuilder sqlString = new StringBuilder(getPreparedStatementText(context, method, arguments));
+
+ if (callableStatement) {
+ JdbcControl.SQLParameter[] params = (JdbcControl.SQLParameter[]) arguments[0];
+ if (params == null) {
+ return sqlString.toString();
+ }
+
+ sqlString.append(" Params: {");
+ for (int i = 0; i < params.length; i++) {
+ if (i > 0) { sqlString.append(params[i].value.toString()); }
+ }
+ sqlString.append("}");
+
+ } else if (_batchUpdate) {
+ sqlString.append(" Params: batch update.");
+
+ } else {
+ sqlString.append(" Params: {");
+ boolean first = true;
+ for (SqlFragment sf : _children) {
+ if (sf.hasParamValue()) {
+ Object values[] = sf.getParameterValues(context, method, arguments);
+ for (Object value : values) {
+
+ if (!first) sqlString.append(", "); else first = false;
+ sqlString.append(value);
+ }
+ }
+ }
+ sqlString.append("}");
+ }
+ return sqlString.toString();
+ }
+
+
+ // /////////////////////////////////////////////////// PRIVATE METHODS ///////////////////////////////////////////
+
+ /**
+ * Sets the specified parameter in the prepared statement.
+ *
+ * @param ps A PreparedStatement.
+ * @param i index of parameter to set.
+ * @param value value of the parameter.
+ * @param sqlType SQL type of value.
+ * @param cal A calendar instance used to resolve date/time values.
+ * @throws SQLException If the parameter cannot be set.
+ */
+ private void setPreparedStatementParameter(PreparedStatement ps, int i, Object value, int sqlType, Calendar cal)
+ throws SQLException {
+
+ if (sqlType == Types.NULL) {
+ sqlType = _tmf.getSqlType(value);
+ }
+
+ if (value == null) {
+ ps.setNull(i, Types.NULL == sqlType ? Types.VARCHAR : sqlType);
+ return;
+ }
+
+ switch (sqlType) {
+
+ case Types.VARCHAR:
+ if (!(value instanceof String)) value = value.toString();
+ break;
+
+ case Types.BOOLEAN:
+ if (value instanceof Boolean) {
+ ps.setBoolean(i, ((Boolean) value).booleanValue());
+ return;
+ }
+ break;
+
+ case Types.TIMESTAMP:
+ if (value instanceof java.util.Calendar) {
+ Calendar calValue = (Calendar) value;
+
+// @todo: validate it is correct to comment out call to deprectated method
+// if (cal == null) {
+// /* NOTE: drivers are inconsistent in their handling of setTimestamp(i,date,cal)
+// * so we won't use that, unless the user calls setCalendar().
+// * I'm going with the theory that it makes sense to store
+// * the time relative to the Calendar's timezone rather than
+// * the system timezone otherwise, using a Calendar would be a no-op.
+// */
+// value = new java._sql.Timestamp(calValue.get(Calendar.YEAR) - 1900,
+// calValue.get(Calendar.MONTH),
+// calValue.get(Calendar.DATE),
+// calValue.get(Calendar.HOUR_OF_DAY),
+// calValue.get(Calendar.MINUTE),
+// calValue.get(Calendar.SECOND),
+// calValue.get(Calendar.MILLISECOND));
+// } else {
+ value = new java.sql.Timestamp(calValue.getTimeInMillis());
+// }
+ } else if (java.util.Date.class.equals(value.getClass())) {
+ // some drivers don't like java.util.Date
+ value = new java.sql.Timestamp(((java.util.Date) value).getTime());
+ }
+
+ if (value instanceof java.sql.Timestamp) {
+ if (cal == null)
+ ps.setTimestamp(i, (java.sql.Timestamp) value);
+ else
+ ps.setTimestamp(i, (java.sql.Timestamp) value, cal);
+ return;
+ }
+ break;
+
+ case Types.DATE:
+ if (value instanceof java.util.Calendar) {
+ /* NOTE: see note above
+ Calendar cal = (Calendar)value;
+ value = new java._sql.Date(cal.getTimeInMillis());
+ ps.setDate(i, (java._sql.Date)value, cal);
+ return;
+ */
+ Calendar calValue = (Calendar) value;
+
+ // @todo: validate that commenting out deprected method is correct behavior
+// if (cal == null) {
+// value = new java._sql.Date(calValue.get(Calendar.YEAR - 1900),
+// calValue.get(Calendar.MONTH),
+// calValue.get(Calendar.DATE));
+// } else {
+ value = new java.sql.Date(calValue.getTimeInMillis());
+// }
+ } else if (value.getClass() == java.util.Date.class) {
+ // some drivers don't like java.util.Date
+ value = new java.sql.Date(((java.util.Date) value).getTime());
+ }
+
+ if (value instanceof java.sql.Date) {
+ if (cal == null) {
+ ps.setDate(i, (java.sql.Date) value);
+ } else {
+ ps.setDate(i, (java.sql.Date) value, cal);
+ }
+ return;
+ }
+ break;
+
+ case Types.TIME:
+ if (value instanceof java.sql.Time) {
+ if (cal == null) {
+ ps.setTime(i, (java.sql.Time) value);
+ } else {
+ ps.setTime(i, (java.sql.Time) value, cal);
+ }
+ return;
+ }
+ break;
+ }
+
+ if (sqlType == Types.NULL) {
+ ps.setObject(i, value);
+ } else {
+ ps.setObject(i, value, sqlType);
+ }
+ }
+
+ /**
+ * Determine if this SQL will generate a callable or prepared statement.
+ *
+ * @param args The method's argument list which this SQL annotation was assocatied with.
+ * @return true if this statement will generated a CallableStatement
+ */
+ private boolean setCallableStatement(Object[] args) {
+
+ // CallableStatement vs. PreparedStatement
+ if (args != null && args.length == 1 && args[0] != null) {
+ Class argClass = args[0].getClass();
+ if (argClass.isArray() && JdbcControl.SQLParameter.class.isAssignableFrom(argClass.getComponentType())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Build a prepared statement for a batch update.
+ *
+ * @param ps The PreparedStatement object.
+ * @param args The parameter list of the jdbccontrol method.
+ * @param cal A Calendar instance used to resolve date/time values.
+ * @throws SQLException If a batch update cannot be performed.
+ */
+ private void doBatchUpdate(PreparedStatement ps, Object[] args, Calendar cal) throws SQLException {
+
+ final int[] sqlTypes = new int[args.length];
+ final Object[] objArrays = new Object[args.length];
+
+ // build an array of type values and object arrays
+ for (int i = 0; i < args.length; i++) {
+ sqlTypes[i] = _tmf.getSqlType(args[i].getClass().getComponentType());
+ objArrays[i] = TypeMappingsFactory.toObjectArray(args[i]);
+ }
+
+ final int rowCount = ((Object[]) objArrays[0]).length;
+ for (int i = 0; i < rowCount; i++) {
+ for (int j = 0; j < args.length; j++) {
+ setPreparedStatementParameter(ps, j + 1, ((Object[]) objArrays[j])[i], sqlTypes[j], cal);
+ }
+ ps.addBatch();
+ }
+ }
+
+ /**
+ * Load element values from the SQL annotation which apply to Statements.
+ *
+ * @param context ControlBeanContext instance.
+ * @param method Annotated method.
+ */
+ private void loadSQLAnnotationStatmentOptions(ControlBeanContext context, Method method) {
+
+ final JdbcControl.SQL methodSQL = (JdbcControl.SQL) context.getMethodPropertySet(method, JdbcControl.SQL.class);
+
+ _batchUpdate = methodSQL.batchUpdate();
+ _getGeneratedKeys = methodSQL.getGeneratedKeys();
+ _genKeyColumnNames = methodSQL.generatedKeyColumnNames();
+ _genKeyColumnIndexes = methodSQL.generatedKeyColumnIndexes();
+ _scrollType = methodSQL.scrollableResultSet();
+ _fetchDirection = methodSQL.fetchDirection();
+ _fetchSize = methodSQL.fetchSize();
+ _maxRows = methodSQL.maxRows();
+ _maxArray = methodSQL.arrayMaxLength();
+
+ _holdability = methodSQL.resultSetHoldabilityOverride();
+ }
+
+ /**
+ * Checks that all statement options specified in annotation are supported by the database.
+ *
+ * @param metaData
+ * @throws SQLException
+ */
+ private void checkJdbcSupport(DatabaseMetaData metaData) throws SQLException {
+
+ if (_getGeneratedKeys && !metaData.supportsGetGeneratedKeys()) {
+ throw new ControlException("The database does not support getGeneratedKeys.");
+ }
+
+ if (_batchUpdate && !metaData.supportsBatchUpdates()) {
+ throw new ControlException("The database does not support batchUpdates.");
+ }
+
+ if (_scrollType != JdbcControl.ScrollType.DRIVER_DEFAULT
+ && !metaData.supportsResultSetConcurrency(_scrollType.getType(), _scrollType.getConcurrencyType())) {
+ throw new ControlException("The database does not support the ResultSet concurrecy type: " + _scrollType.toString());
+ }
+
+ if (_holdability != JdbcControl.HoldabilityType.DRIVER_DEFAULT
+ && !metaData.supportsResultSetHoldability(_holdability.getHoldability())) {
+ throw new ControlException("The database does not support the ResultSet holdability type: " + _holdability.toString());
+ }
+ }
+
+ /**
+ * The much maligned method for computing the maximum number of ResultSet rows this statement should return.
+ * The values of maxRows and arrayMaxLength are enforced at compile-time by the JdbcControlChecker to be the
+ * following: MAXROWS_ALL <= maxRows, 0 < arrayMaxLength
+ *
+ * @param method The annotated method.
+ * @return max number of resultSet rows to return from the query.
+ */
+ private int computeMaxRows(Method method) {
+
+ Class returnType = method.getReturnType();
+
+ final boolean isArray = returnType.isArray();
+ final boolean isRowSet = returnType.equals(RowSet.class);
+
+ int maxSet = _maxRows;
+ if (isArray && _maxArray != JdbcControl.MAXROWS_ALL) {
+ maxSet = _maxRows == JdbcControl.MAXROWS_ALL ? _maxArray + 1 : Math.min(_maxArray + 1, _maxRows);
+ } else if (isRowSet && _maxRows > 0) {
+ maxSet = _maxRows + 1;
+ }
+
+ return maxSet;
+ }
+}
Added: incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlSubstitutionFragment.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlSubstitutionFragment.java?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlSubstitutionFragment.java (added)
+++ incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlSubstitutionFragment.java Mon May 9 13:17:58 2005
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+
+package org.apache.beehive.controls.system.jdbc.parser;
+
+import org.apache.beehive.controls.api.context.ControlBeanContext;
+import org.apache.beehive.controls.system.jdbc.TypeMappingsFactory;
+
+import java.lang.reflect.Method;
+
+/**
+ * Represents a fragement from the SQL annotation's statement member which begins with '{sql:'.
+ * Substitution fragements are unique in that they are fully evaluated BEFORE a PreparedStatement
+ * is generated.
+ * <p/>
+ * Supported 'sql:' escapes are subst and fn. subst is the default mode, and will be used if 'sql: '
+ * is specified.
+ *
+ * The <tt>fn</tt> variant of this construct has a very ridgid syntax at this point. It must conform to:
+ *
+ * <pre>
+ * {sql:fn in(x,{y})}
+ * </pre>
+ *
+ * where the '{y}' could also be some literal term.
+ */
+public class SqlSubstitutionFragment extends SqlFragmentContainer {
+
+ /**
+ * Constructor for subst or function with no param substitution
+ *
+ * @param child An child which is contained in this fragment.
+ */
+ SqlSubstitutionFragment(SqlFragment child) {
+ super();
+ addChild(child);
+ }
+
+ /**
+ * Constructor for a function which includes a ReflectionFragment
+ *
+ * @param lf A LiteralFragment which contains the text up to the parameter substitution.
+ * @param rf The ReflectionFragment containing the parameter substitution
+ * @param lff A LiteralFragment which contains any text which occures after the parameter substitution.
+ */
+ SqlSubstitutionFragment(LiteralFragment lf, ReflectionFragment rf, LiteralFragment lff) {
+ super();
+ addChild(lf);
+ addChild(rf);
+ addChild(lff);
+ }
+
+ /**
+ * Always true for this fragment type
+ * @return true
+ */
+ boolean isDynamicFragment() { return true; }
+
+ /**
+ * Always false for this fragment type, since all param values are resolved
+ * before the prepared statement is created.
+ * @return false
+ */
+ boolean hasParamValue() { return false; }
+
+ /**
+ * Return the text for a PreparedStatement from this fragment.
+ *
+ * @param context A ControlBeanContext instance
+ * @param m The annotated method
+ * @param args The method parameters
+ * @return A String containing the value of this fragment and its children
+ */
+ String getPreparedStatementText(ControlBeanContext context, Method m, Object[] args) {
+
+ StringBuilder sb = new StringBuilder();
+ for (SqlFragment frag : _children) {
+ if (frag.hasParamValue()) {
+ Object[] pValues = frag.getParameterValues(context, m, args);
+ for (Object o : pValues) {
+ sb.append(processSqlParams(o));
+ }
+ } else {
+ sb.append(frag.getPreparedStatementText(context, m, args));
+ }
+ }
+ return sb.toString();
+ }
+
+
+// ////////////////////////////////////////////// Private Methods //////////////////////////////////////////////
+
+
+ /**
+ * Check for the cases of a null or array type param value. If array type build a string of the array values
+ * seperated by commas.
+ *
+ * @param value
+ * @return
+ */
+ private String processSqlParams(Object value) {
+
+ Object[] arr = null;
+ if (value != null) {
+ arr = TypeMappingsFactory.toObjectArray(value);
+ }
+
+ if (value == null || (arr != null && arr.length == 0)) {
+ return "";
+ } else if (arr != null) {
+ StringBuilder result = new StringBuilder();
+ for (int i = 0; i < arr.length; i++) {
+ if (i > 0) {
+ result.append(',');
+ result.append(arr[i].toString());
+ } else {
+ result.append(arr[i].toString());
+ }
+ }
+ return result.toString();
+ } else {
+ return value.toString();
+ }
+ }
+}
Added: incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/Token.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/Token.java?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/Token.java (added)
+++ incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/Token.java Mon May 9 13:17:58 2005
@@ -0,0 +1,81 @@
+/* Generated By:JavaCC: Do not edit this line. Token.java Version 3.0 */
+package org.apache.beehive.controls.system.jdbc.parser;
+
+/**
+ * Describes the input token stream.
+ */
+
+public class Token {
+
+ /**
+ * An integer that describes the kind of this token. This numbering
+ * system is determined by JavaCCParser, and a table of these numbers is
+ * stored in the file ...Constants.java.
+ */
+ public int kind;
+
+ /**
+ * beginLine and beginColumn describe the position of the first character
+ * of this token; endLine and endColumn describe the position of the
+ * last character of this token.
+ */
+ public int beginLine, beginColumn, endLine, endColumn;
+
+ /**
+ * The string image of the token.
+ */
+ public String image;
+
+ /**
+ * A reference to the next regular (non-special) token from the input
+ * stream. If this is the last token from the input stream, or if the
+ * token manager has not read tokens beyond this one, this field is
+ * set to null. This is true only if this token is also a regular
+ * token. Otherwise, see below for a description of the contents of
+ * this field.
+ */
+ public Token next;
+
+ /**
+ * This field is used to access special tokens that occur prior to this
+ * token, but after the immediately preceding regular (non-special) token.
+ * If there are no such special tokens, this field is set to null.
+ * When there are more than one such special token, this field refers
+ * to the last of these special tokens, which in turn refers to the next
+ * previous special token through its specialToken field, and so on
+ * until the first special token (whose specialToken field is null).
+ * The next fields of special tokens refer to other special tokens that
+ * immediately follow it (without an intervening regular token). If there
+ * is no such token, this field is null.
+ */
+ public Token specialToken;
+
+ /**
+ * Returns the image.
+ */
+ public String toString()
+ {
+ return image;
+ }
+
+ /**
+ * Returns a new Token object, by default. However, if you want, you
+ * can create and return subclass objects based on the value of ofKind.
+ * Simply add the cases to the switch for all those special cases.
+ * For example, if you have a subclass of Token called IDToken that
+ * you want to create if ofKind is ID, simlpy add something like :
+ *
+ * case MyParserConstants.ID : return new IDToken();
+ *
+ * to the following switch statement. Then you can cast matchedToken
+ * variable to the appropriate type and use it in your lexical actions.
+ */
+ public static final Token newToken(int ofKind)
+ {
+ switch(ofKind)
+ {
+ default : return new Token();
+ }
+ }
+
+}
Added: incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/TokenMgrError.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/TokenMgrError.java?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/TokenMgrError.java (added)
+++ incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/TokenMgrError.java Mon May 9 13:17:58 2005
@@ -0,0 +1,133 @@
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 3.0 */
+package org.apache.beehive.controls.system.jdbc.parser;
+
+public class TokenMgrError extends Error
+{
+ /*
+ * Ordinals for various reasons why an Error of this type can be thrown.
+ */
+
+ /**
+ * Lexical error occured.
+ */
+ static final int LEXICAL_ERROR = 0;
+
+ /**
+ * An attempt wass made to create a second instance of a static token manager.
+ */
+ static final int STATIC_LEXER_ERROR = 1;
+
+ /**
+ * Tried to change to an invalid lexical state.
+ */
+ static final int INVALID_LEXICAL_STATE = 2;
+
+ /**
+ * Detected (and bailed out of) an infinite loop in the token manager.
+ */
+ static final int LOOP_DETECTED = 3;
+
+ /**
+ * Indicates the reason why the exception is thrown. It will have
+ * one of the above 4 values.
+ */
+ int errorCode;
+
+ /**
+ * Replaces unprintable characters by their espaced (or unicode escaped)
+ * equivalents in the given string
+ */
+ protected static final String addEscapes(String str) {
+ StringBuffer retval = new StringBuffer();
+ char ch;
+ for (int i = 0; i < str.length(); i++) {
+ switch (str.charAt(i))
+ {
+ case 0 :
+ continue;
+ case '\b':
+ retval.append("\\b");
+ continue;
+ case '\t':
+ retval.append("\\t");
+ continue;
+ case '\n':
+ retval.append("\\n");
+ continue;
+ case '\f':
+ retval.append("\\f");
+ continue;
+ case '\r':
+ retval.append("\\r");
+ continue;
+ case '\"':
+ retval.append("\\\"");
+ continue;
+ case '\'':
+ retval.append("\\\'");
+ continue;
+ case '\\':
+ retval.append("\\\\");
+ continue;
+ default:
+ if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+ String s = "0000" + Integer.toString(ch, 16);
+ retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+ } else {
+ retval.append(ch);
+ }
+ continue;
+ }
+ }
+ return retval.toString();
+ }
+
+ /**
+ * Returns a detailed message for the Error when it is thrown by the
+ * token manager to indicate a lexical error.
+ * Parameters :
+ * EOFSeen : indicates if EOF caused the lexicl error
+ * curLexState : lexical state in which this error occured
+ * errorLine : line number when the error occured
+ * errorColumn : column number when the error occured
+ * errorAfter : prefix that was seen before this error occured
+ * curchar : the offending character
+ * Note: You can customize the lexical error message by modifying this method.
+ */
+ protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
+ return("Lexical error at line " +
+ errorLine + ", column " +
+ errorColumn + ". Encountered: " +
+ (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
+ "after : \"" + addEscapes(errorAfter) + "\"");
+ }
+
+ /**
+ * You can also modify the body of this method to customize your error messages.
+ * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+ * of end-users concern, so you can return something like :
+ *
+ * "Internal Error : Please file a bug report .... "
+ *
+ * from this method for such cases in the release version of your parser.
+ */
+ public String getMessage() {
+ return super.getMessage();
+ }
+
+ /*
+ * Constructors of various flavors follow.
+ */
+
+ public TokenMgrError() {
+ }
+
+ public TokenMgrError(String message, int reason) {
+ super(message);
+ errorCode = reason;
+ }
+
+ public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
+ this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
+ }
+}
Added: incubator/beehive/trunk/system-controls/src/jms/build.xml
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jms/build.xml?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jms/build.xml (added)
+++ incubator/beehive/trunk/system-controls/src/jms/build.xml Mon May 9 13:17:58 2005
@@ -0,0 +1,48 @@
+<?xml version="1.0" ?>
+
+<project name="jms-control" default="build" basedir=".">
+
+ <import file="../../systemcontrols-imports.xml"/>
+
+ <property name="module.name" value="jms-control"/>
+ <property name="module.dir" location="${src.dir}/jms"/>
+
+ <path id="module.classpath">
+ <path refid="ejb.dependency.path"/>
+ <path refid="controls.dependency.path"/>
+ <path refid="velocity.dependency.path"/>
+ <path refid="log4j.dependency.path"/>
+ <path refid="xbean.dependency.path"/>
+ </path>
+
+ <taskdef name="control-jar"
+ classname="org.apache.beehive.controls.runtime.packaging.ControlJarTask"
+ onerror="report"
+ classpathref="module.classpath"/>
+
+
+ <!-- =================================================================== -->
+ <!-- clean - cleans the Jdbc Control -->
+ <!-- =================================================================== -->
+ <target name="clean" description="Clean the JMS control build area.">
+ <delete dir="${classes.dir}/${module.name}"/>
+ <delete dir="${gen.src.dir}/${module.name}"/>
+ <delete file="${build.lib.dir}/${jmscontrol.jar.name}"/>
+ </target>
+
+
+ <!-- =================================================================== -->
+ <!-- build - build the Jms Control -->
+ <!-- =================================================================== -->
+ <target name="build" description="Builds the JMS control.">
+
+ <mkdir dir="${classes.dir}/${module.name}"/>
+ <mkdir dir="${gen.src.dir}/${module.name}"/>
+
+ <build-controls srcdir="${module.dir}" destdir="${classes.dir}/${module.name}"
+ tempdir="${gen.src.dir}/${module.name}" classpathref="module.classpath"/>
+
+ <control-jar destfile="${build.lib.dir}/${jmscontrol.jar.name}" basedir="${classes.dir}/${module.name}"/>
+
+ </target>
+</project>
Added: incubator/beehive/trunk/system-controls/src/jms/org/apache/beehive/controls/system/jms/JMSControl.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jms/org/apache/beehive/controls/system/jms/JMSControl.java?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jms/org/apache/beehive/controls/system/jms/JMSControl.java (added)
+++ incubator/beehive/trunk/system-controls/src/jms/org/apache/beehive/controls/system/jms/JMSControl.java Mon May 9 13:17:58 2005
@@ -0,0 +1,455 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+
+package org.apache.beehive.controls.system.jms;
+
+import org.apache.beehive.controls.api.ControlException;
+import org.apache.beehive.controls.api.bean.AnnotationMemberTypes;
+import org.apache.beehive.controls.api.bean.Control;
+import org.apache.beehive.controls.api.bean.ControlInterface;
+import org.apache.beehive.controls.api.bean.AnnotationConstraints;
+import org.apache.beehive.controls.api.properties.PropertySet;
+import org.apache.beehive.controls.api.packaging.*;
+import org.apache.beehive.controls.api.events.EventSet;
+import java.lang.annotation.*;
+import java.util.Date;
+import java.util.Map;
+
+import javax.jms.Session;
+
+/**
+ * The control interface for the jms control.
+ */
+@ControlInterface (defaultBinding="org.apache.beehive.controls.system.jms.impl.JMSControlImpl")
+public interface JMSControl
+{
+ /**
+ * The destination type.
+ */
+ enum DestinationType
+ {
+ /** The destination is set from the object obtained from JNDI. */
+ Auto,
+ /** The destination must be a javax.jms.QueueSender. */
+ Queue,
+ /** The destination must be a javax.jms.TopicPublisher. */
+ Topic
+ };
+
+ /**
+ * The header type. Corresponds to the JMS* bean properties on a JMS message.
+ */
+ enum HeaderType
+ {
+ /** see javax.jms.Message.getJMSCorrelationID() */
+ JMSCorrelationID,
+ /** see javax.jms.Message.getJMSDeliveryMode */
+ JMSDeliveryMode,
+ /** see javax.jms.Message.getJMSPriority */
+ JMSPriority,
+ /** see javax.jms.Message.getJMSExpiration */
+ JMSExpiration,
+ /** see javax.jms.Message.getJMSMessageID */
+ JMSMessageID,
+ /** see javax.jms.Message.getJMSType */
+ JMSType,
+ /** see javax.jms.Message.getJMSRedelivered */
+ JMSRedelivered,
+ /** see javax.jms.Message.getJMSTimestamp */
+ JMSTimestamp
+ };
+
+ /**
+ * The message type.
+ */
+ enum MessageType
+ {
+ /** Message is determined from the body instance class. If the method is not annotated with Body, then the message type is Map. */
+ Auto,
+ /** Message is a javax.jms.TextMessage */
+ Text,
+ /** Message is a javax.jms.BytesMessage */
+ Bytes,
+ /** Message is a javax.jms.ObjectMessage */
+ Object,
+ /** Message is a javax.jms.MapMessage */
+ Map,
+ /** Message is a javax.jms.Message as given by the Body parameter */
+ JMSMessage
+ };
+
+ /**
+ * The delivery mode.
+ */
+ enum DeliveryMode
+ {
+ /** see javax.jms.DeliveryMode.NON_PERSISTENT */
+ NonPersistent,
+ /** see javax.jms.DeliveryMode.PERSISTENT */
+ Persistent,
+ /** The default for the provider */
+ Auto
+ };
+
+ /**
+ * The acknowledge mode.
+ */
+ enum AcknowledgeMode
+ {
+ /** see javax.jms.Session.AUTO_ACKNOWLEDGE */
+ Auto,
+ /** see javax.jms.Session.CLIENT_ACKNOWLEDGE */
+ Client,
+ /** see javax.jms.Session.DUPS_OK_ACKNOWLEDGE */
+ DupsOk
+ };
+
+ /**
+ * Indicates the JMSCorrelationID message header.
+ *
+ * @deprecated
+ * @see HeaderType
+ */
+ public static final String HEADER_CORRELATIONID = HeaderType.JMSCorrelationID.toString();
+ /**
+ * Indicates the JMSDeliveryMode message header.
+ *
+ * @deprecated
+ * @see HeaderType
+ */
+ public static final String HEADER_DELIVERYMODE = HeaderType.JMSDeliveryMode.toString();
+ /**
+ * Indicates the JMSExpiration message header.
+ * Use with the getHeaders and setHeaders methods.
+ *
+ * @deprecated
+ * @see HeaderType
+ */
+ public static final String HEADER_EXPIRATION = HeaderType.JMSExpiration.toString();
+ /**
+ * Indicates the JMSMessageID message header.
+ *
+ * @deprecated
+ * @see HeaderType
+ */
+ public static final String HEADER_MESSAGEID = HeaderType.JMSMessageID.toString();
+ /**
+ * Indicates the JMSPriority message header.
+ *
+ * @deprecated
+ * @see HeaderType
+ */
+ public static final String HEADER_PRIORITY = HeaderType.JMSPriority.toString();
+ /**
+ * Indicates the JMSRedelivered message header.
+ *
+ * @deprecated
+ * @see HeaderType
+ */
+ public static final String HEADER_REDELIVERED = HeaderType.JMSRedelivered.toString();
+ /**
+ * Indicates the JMSTimestamp message header.
+ *
+ * @deprecated
+ * @see HeaderType
+ */
+ public static final String HEADER_TIMESTAMP = HeaderType.JMSTimestamp.toString();
+ /**
+ * Indicates the JMSType message header.
+ *
+ * @deprecated
+ * @see HeaderType
+ */
+ public static final String HEADER_TYPE = HeaderType.JMSType.toString();
+
+ /**
+ * Get the JMS Session object.
+ * @return the session.
+ */
+ public Session getSession() throws ControlException;
+
+ /**
+ * Get the JMS Connection.
+ * @return the connection.
+ */
+ public javax.jms.Connection getConnection() throws ControlException;
+
+ /**
+ * Get the jms-destination.
+ *
+ * @return an instance destination object.
+ */
+ public javax.jms.Destination getDestination() throws ControlException;
+
+
+ /**
+ * Sets the JMS headers to be assigned to the next JMS message
+ * sent. Note that these headers are set only on the next message,
+ * subsequent messages will not get these headers. Also note that
+ * if the body is a message itself,
+ * then any header set through this map will override headers set
+ * in the message.
+ *
+ * @param headers A map of header names (Strings or HeaderType) to header values.
+ */
+ public void setHeaders(Map headers);
+
+ /**
+ * Sets a JMS header to be assigned to the next JMS message
+ * sent. Note that this headers is set only on the next message,
+ * subsequent messages will not get this header. Also note that
+ * if the body is a message itself,
+ * then the header set here will override the header set
+ * in the message.
+ *
+ * @param type the header type.
+ * @param value the value for the header.
+ */
+ public void setHeader(JMSControl.HeaderType type,Object value);
+
+ /**
+ * Sets the JMS properties to be assigned to the next JMS message
+ * sent. Note that these properties are set only on the next
+ * message, subsequent messages will not get these
+ * properties. Also note that if the next message is sent through
+ * a publish method, then any property set through this
+ * map will override properties set in the message itself.
+ *
+ * @param properties A map of property names (Strings) to property
+ * values.
+ */
+ public void setProperties(Map properties);
+
+ /**
+ * Set the given JMS property to be assigned to the next JMS message
+ * sent. Note that this property is set only on the next
+ * message, subsequent messages will not get this
+ * property. Also note that
+ * if the body is a message itself,
+ * then the property set here will override the property set
+ * in the message.
+ *
+ * @param name the property name.
+ * @param value the property value.
+ */
+ public void setProperty(String name,Object value);
+
+ /**
+ * The message type used by the method. The default is
+ * to use the type of the body parameter.
+ */
+ @PropertySet(prefix="Message")
+ @Target({ElementType.METHOD})
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface Message
+ {
+ @FeatureInfo(shortDescription="The message type")
+ public JMSControl.MessageType value() default JMSControl.MessageType.Auto;
+ }
+
+ /**
+ * The method parameter representing a message property with the given name.
+ * see javax.jms.Message.getProperty()/setProperty().
+ */
+ @Target({ElementType.PARAMETER})
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface Property
+ {
+ /**
+ * The property name.
+ */
+ public String name();
+ }
+
+ /**
+ * The method parameter representing a message property with the given name and value.
+ * see javax.jms.Message.getProperty()/setProperty().
+ */
+ @PropertySet(prefix="Property")
+ @Target({ElementType.METHOD})
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface PropertyValue
+ {
+ /**
+ * The property name.
+ */
+ public String name();
+
+ /**
+ * The property value.
+ */
+ public String value();
+
+ /**
+ * The property type.
+ */
+ public Class type() default String.class;
+
+ }
+
+ /**
+ * The method/parameter annotation representing a message priority. If not given
+ * then the default for the JMS provider is used.
+ */
+ @PropertySet(prefix="Priority")
+ @Target({ElementType.PARAMETER,ElementType.METHOD})
+ @Retention(RetentionPolicy.RUNTIME)
+ @AnnotationConstraints.AllowExternalOverride
+ public @interface Priority
+ {
+ @AnnotationMemberTypes.Optional
+ public int value() default -1;
+ }
+ /**
+ * The method/parameter representing the message JMS type.
+ */
+ @PropertySet(prefix="Type")
+ @Target({ElementType.PARAMETER,ElementType.METHOD})
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface Type
+ {
+ public String value() default "";
+ }
+ /**
+ * The method/parameter representing the message JMS CorrelationID.
+ */
+ @PropertySet(prefix="CorrelationId")
+ @Target({ElementType.PARAMETER,ElementType.METHOD})
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface CorrelationId
+ {
+ public String value() default "";
+ }
+ /**
+ * The method parameter representing a message expiration in milliseconds.
+ * If not given then the default for the JMS provider is used.
+ */
+ @PropertySet(prefix="Expiration")
+ @Target({ElementType.PARAMETER,ElementType.METHOD})
+ @Retention(RetentionPolicy.RUNTIME)
+ @AnnotationConstraints.AllowExternalOverride
+ public @interface Expiration
+ {
+ @AnnotationMemberTypes.Optional
+ public long value() default -1L;
+ }
+ /**
+ * The method parameter representing a message delivery mode.
+ * If not given then the default for the JMS provider is used.
+ */
+ @PropertySet(prefix="Delivery")
+ @Target({ElementType.PARAMETER,ElementType.METHOD})
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface Delivery
+ {
+ public JMSControl.DeliveryMode value() default JMSControl.DeliveryMode.Auto;
+ }
+ /**
+ * The method parameter representing one or more properties.
+ */
+ @PropertySet(prefix="Properties")
+ @Target({ElementType.METHOD})
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface Properties
+ {
+ public PropertyValue[] value();
+ }
+ /**
+ * The JMS destination annotation for a extended class method.
+ */
+ @PropertySet
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ElementType.TYPE,ElementType.FIELD})
+ @AnnotationConstraints.AllowExternalOverride
+ public @interface Destination
+ {
+ /**
+ * The JNDI name of the queue or topic.
+ */
+ // BUG: There should be a JMS_TOPIC_OR_QUEUE resource type.
+ @FeatureInfo(shortDescription="JNDI name of the queue or topic")
+ @AnnotationMemberTypes.JndiName( resourceType = AnnotationMemberTypes.JndiName.ResourceType.OTHER )
+ public String sendJndiName();
+
+ /**
+ * The Correlation-Id for messages.
+ */
+ @FeatureInfo(shortDescription="Correlation-Id for messages")
+ @AnnotationMemberTypes.Optional
+ public String sendCorrelationProperty() default "";
+
+ /**
+ * The JNDI name of queue connection factory.
+ */
+ @FeatureInfo(shortDescription="JNDI name of queue connection factory")
+ public String jndiConnectionFactory();
+
+ /**
+ * The destination type (DestinationType). The default is to use the type of the destination object named by the JNDI name.
+ */
+ @FeatureInfo(shortDescription="The destination type (DestinationType). The default is to use the type of the destination object named by the JNDI name")
+ @AnnotationMemberTypes.Optional
+ public JMSControl.DestinationType sendType() default JMSControl.DestinationType.Auto;
+
+ /**
+ * True if send is transacted. The default is transacted.
+ */
+ @FeatureInfo(shortDescription="True if send is transacted. The default is transacted")
+ @AnnotationMemberTypes.Optional
+ public boolean transacted() default true;
+
+ /**
+ * The acknowledge mode. The default is to use auto-acknowledge.
+ */
+ @FeatureInfo(shortDescription="The acknowledge mode. The default is to use auto-acknowledge")
+ @AnnotationMemberTypes.Optional
+ public JMSControl.AcknowledgeMode acknowledgeMode() default JMSControl.AcknowledgeMode.Auto;
+
+ /**
+ * The JNDI context factory.
+ */
+ @FeatureInfo(shortDescription="JNDI context factory")
+ @AnnotationMemberTypes.Optional
+ public String jndiContextFactory() default "";
+
+ /**
+ * The JNDI provider URL.
+ */
+ @FeatureInfo(shortDescription="JNDI provider URL")
+ @AnnotationMemberTypes.Optional
+ @AnnotationMemberTypes.URI
+ public String jndiProviderURL() default "";
+
+ /**
+ * The JNDI security principal.
+ */
+ @FeatureInfo(shortDescription="JNDI security principal")
+ @AnnotationMemberTypes.Optional
+ public String jndiUsername() default "";
+
+
+ /**
+ * The JNDI security credentials.
+ */
+ @FeatureInfo(shortDescription="JNDI security credentials")
+ @AnnotationMemberTypes.Optional
+ public String jndiPassword() default "";
+ }
+
+
+}