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 [6/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/RowToXmlObjectMapper.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/RowToXmlObjectMapper.java?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/RowToXmlObjectMapper.java (added)
+++ incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/RowToXmlObjectMapper.java Mon May 9 13:17:58 2005
@@ -0,0 +1,325 @@
+/*
+ * 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;
+
+import org.apache.beehive.controls.api.ControlException;
+import org.apache.xmlbeans.SchemaProperty;
+import org.apache.xmlbeans.SchemaType;
+import org.apache.xmlbeans.XmlObject;
+import org.apache.xmlbeans.XmlOptions;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.Calendar;
+import java.util.HashMap;
+
+/**
+ * Maps a ResultSet row to an XmlObject.
+ */
+public class RowToXmlObjectMapper extends RowMapper {
+
+ private final int _columnCount;
+ private final SchemaType _schemaType;
+
+ private SetterMethod[] _setterMethods;
+ private final Object[] _args = new Object[1];
+
+ /**
+ * Create a new RowToXmlObjectMapper.
+ *
+ * @param resultSet ResultSet to map
+ * @param returnTypeClass Class to map to.
+ * @param cal Calendar instance for date/time mappings.
+ * @throws SQLException on error.
+ */
+ RowToXmlObjectMapper(ResultSet resultSet, Class returnTypeClass, Calendar cal)
+ throws SQLException {
+ super(resultSet, returnTypeClass, cal);
+
+ _columnCount = resultSet.getMetaData().getColumnCount();
+ _schemaType = getSchemaType(_returnTypeClass);
+ _setterMethods = null;
+ }
+
+ /**
+ * map a row from the ResultSet to an XmlObject instance
+ *
+ * @return An XmlObject instance.
+ */
+ public Object mapRowToReturnType() {
+
+ Object resultObject = null;
+ if (_columnCount == 1) {
+
+ final int typeId = _tmf.getTypeId(_returnTypeClass);
+
+ try {
+ if (typeId != TypeMappingsFactory.TYPE_UNKNOWN) {
+ return extractColumnValue(1, typeId);
+ } else {
+ // we still might want a single value (i.e. java.util.Date)
+ Object val = extractColumnValue(1, typeId);
+ if (_returnTypeClass.isAssignableFrom(val.getClass())) {
+ return val;
+ }
+ }
+ } catch (SQLException e) {
+ throw new ControlException(e.getMessage(), e);
+ }
+ }
+
+ if (_setterMethods == null) {
+ try {
+ getResultSetMappings();
+ } catch (SQLException e) {
+ throw new ControlException(e.getMessage(), e);
+ }
+ }
+
+ resultObject = XmlObject.Factory.newInstance(new XmlOptions().setDocumentType(_schemaType));
+
+ for (int i = 1; i < _setterMethods.length; i++) {
+ Method setterMethod = _setterMethods[i].getSetter();
+ Object resultValue = null;
+
+ try {
+ resultValue = extractColumnValue(i, _setterMethods[i].getParameterType());
+
+ // if the setter is for an xmlbean enum type, convert the extracted resultset column
+ // value to the proper xmlbean enum type. All xmlbean enums are derived from the class
+ // StringEnumAbstractBase
+ if (_setterMethods[i].getParameterType() == TypeMappingsFactory.TYPE_XMLBEAN_ENUM) {
+ Class parameterClass = _setterMethods[i].getParameterClass();
+ Method m = parameterClass.getMethod("forString", new Class[]{String.class});
+ resultValue = m.invoke(null, new Object[]{resultValue});
+ }
+
+ _args[0] = resultValue;
+ setterMethod.invoke(resultObject, _args);
+
+ if (_setterMethods[i].getNilable() != null) {
+ if (_resultSet.wasNull()) {
+ _setterMethods[i].getNilable().invoke(resultObject, (Object[]) null);
+ }
+ }
+ } catch (SQLException se) {
+ throw new ControlException(se.getMessage(), se);
+ } catch (IllegalArgumentException iae) {
+ try {
+ ResultSetMetaData md = _resultSet.getMetaData();
+ throw new ControlException("The declared Java type for method " + setterMethod.getName()
+ + setterMethod.getParameterTypes()[0].toString()
+ + " is incompatible with the SQL format of column " + md.getColumnName(i).toString()
+ + md.getColumnTypeName(i).toString()
+ + " which returns objects of type " + resultValue.getClass().getName());
+ } catch (SQLException e) {
+ throw new ControlException(e.getMessage(), e);
+ }
+ } catch (IllegalAccessException e) {
+ throw new ControlException("IllegalAccessException when trying to access method " + setterMethod.getName(), e);
+ } catch (NoSuchMethodException e) {
+ throw new ControlException("NoSuchMethodException when trying to map schema enum value using Enum.forString().", e);
+ } catch (InvocationTargetException e) {
+ throw new ControlException("IllegalInvocationException when trying to access method " + setterMethod.getName(), e);
+ }
+ }
+ return resultObject;
+ }
+
+
+// ///////////////////////////////////////////////// private methods /////////////////////////////////////////////////
+
+ /**
+ * Build the necessary structures to do the mapping
+ *
+ * @throws SQLException
+ */
+ private void getResultSetMappings() throws SQLException {
+
+ //
+ // special case for XmlObject, find factory class
+ //
+ if (_schemaType.isDocumentType()) {
+ return;
+ }
+
+ final String[] keys = getKeysFromResultSet();
+
+ //
+ // find setters for return class
+ //
+ HashMap<String, Method> mapFields = new HashMap<String, Method>(_columnCount * 2);
+ for (int i = 1; i <= _columnCount; i++) {
+ mapFields.put(keys[i], null);
+ }
+
+ // public methods
+ Method[] classMethods = _returnTypeClass.getMethods();
+ for (Method method : classMethods) {
+
+ if (isSetterMethod(method)) {
+ final String fieldName = method.getName().substring(3).toUpperCase();
+ if (mapFields.containsKey(fieldName)) {
+ mapFields.put(fieldName, method);
+ }
+ }
+ }
+
+ // finally actually init the fields array
+ _setterMethods = new SetterMethod[_columnCount + 1];
+
+ for (int i = 1; i < _setterMethods.length; i++) {
+ Method setterMethod = mapFields.get(keys[i]);
+ if (setterMethod == null) {
+ throw new ControlException("Unable to map the SQL column " + keys[i]
+ + " to a field on the " + _returnTypeClass.getName() +
+ " class. Mapping is done using a case insensitive comparision of SQL ResultSet "
+ + "columns to public setter methods on the return class.");
+ }
+
+ _setterMethods[i] = new SetterMethod(setterMethod);
+ }
+ }
+
+ /**
+ * Build a String array of column names from the ResultSet.
+ *
+ * @return A String array containing the column names contained within the ResultSet.
+ * @throws SQLException on error
+ */
+ protected String[] getKeysFromResultSet()
+ throws SQLException {
+
+ String[] keys = super.getKeysFromResultSet();
+
+ // check schemaProperty mapping names for more accurate column->field mapping
+ SchemaProperty[] props = _schemaType.getElementProperties();
+ for (int i = 0; i < props.length; i++) {
+
+ int col = -1;
+ try {
+ col = _resultSet.findColumn(props[i].getName().getLocalPart());
+ } catch (SQLException x) {
+ }
+
+ if (col > 0) {
+ keys[col] = props[i].getJavaPropertyName().toUpperCase();
+ }
+ }
+ return keys;
+ }
+
+ /**
+ * Get the SchemaType for the specified class.
+ *
+ * @param returnType Class to get the SchemaType for.
+ * @return SchemaType
+ */
+ private SchemaType getSchemaType(Class returnType) {
+ SchemaType schemaType = null;
+ if (XmlObject.class.isAssignableFrom(returnType)) {
+ try {
+ Field f = returnType.getField("type");
+ if (SchemaType.class.isAssignableFrom(f.getType()) && Modifier.isStatic(f.getModifiers())) {
+ schemaType = (SchemaType) f.get(null);
+ }
+ } catch (NoSuchFieldException x) {
+ } catch (IllegalAccessException x) {
+ }
+ }
+ return schemaType;
+ }
+
+ // /////////////////////////////////////////////INNER CLASSES/////////////////////////////////////////////////
+
+ /**
+ * Helper class which contains setter method information.
+ */
+ private final class SetterMethod {
+ private final Method _setter;
+ private final int _parameterType;
+ private final Class _parameterClass;
+ private final Method _nilable;
+
+ /**
+ * Create a new setter method.
+ *
+ * @param setter Method instance.
+ */
+ SetterMethod(Method setter) {
+ _setter = setter;
+ _parameterClass = _setter.getParameterTypes()[0];
+ _parameterType = _tmf.getTypeId(_parameterClass);
+ _nilable = isNilable();
+ }
+
+ /**
+ * Return the setter method.
+ *
+ * @return Method
+ */
+ Method getSetter() { return _setter; }
+
+ /**
+ * Return the class of the setter method's paramater.
+ *
+ * @return Class of the setter method's param.
+ */
+ Class getParameterClass() { return _parameterClass; }
+
+ /**
+ * Get the type of the methods paramter.
+ * Type is defined by the TypeMappingsFactory, prefixed by TYPE_.
+ *
+ * @return int type.
+ */
+ int getParameterType() { return _parameterType; }
+
+ /**
+ * Get the nilable method for this setter.
+ *
+ * @return Method.
+ */
+ Method getNilable() { return _nilable; }
+
+ /**
+ * This takes care of the special case for xml beans return types.
+ * since they return primitive types even if they are nillable, we
+ * must explicitly call setNil after getting the column out of the resultSet.
+ * for that, we need to keep track of each field's setNil method.
+ * if the field is not nillable, it will not have a setNil method, and
+ * that array index will be null.
+ *
+ * @return Method
+ */
+ private Method isNilable() {
+ try {
+ return _returnTypeClass.getMethod("setNil" + _setter.getName().substring(3), new Class[]{});
+ } catch (NoSuchMethodException e) {
+ // NOOP - just means there is no setNil
+ }
+ return null;
+ }
+ }
+}
Added: incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/TypeMappingsFactory.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/TypeMappingsFactory.java?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/TypeMappingsFactory.java (added)
+++ incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/TypeMappingsFactory.java Mon May 9 13:17:58 2005
@@ -0,0 +1,392 @@
+/*
+ * 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;
+
+import org.apache.beehive.controls.api.ControlException;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.sql.Types;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Currently contains all types of type mappings. Implemented using singleton pattern.
+ */
+//@todo: refactor!
+public final class TypeMappingsFactory {
+
+
+ private static TypeMappingsFactory _instance;
+
+ /**
+ * Get an instance of this class.
+ * @return TypeMappingsFactory instance.
+ */
+ public static TypeMappingsFactory getInstance() {
+ if (_instance == null) {
+ _instance = new TypeMappingsFactory();
+ }
+ return _instance;
+ }
+
+ public static final int TYPE_UNKNOWN = 0;
+ static final int TYPE_BYTE = 1;
+ static final int TYPE_SHORT = 2;
+ static final int TYPE_INT = 3;
+ static final int TYPE_LONG = 4;
+ static final int TYPE_FLOAT = 5;
+ static final int TYPE_DOUBLE = 6;
+ static final int TYPE_BOOLEAN = 7;
+ static final int TYPE_BYTE_OBJ = 8;
+ static final int TYPE_SHORT_OBJ = 9;
+ static final int TYPE_INT_OBJ = 10;
+ static final int TYPE_LONG_OBJ = 11;
+ static final int TYPE_FLOAT_OBJ = 12;
+ static final int TYPE_DOUBLE_OBJ = 13;
+ static final int TYPE_BOOLEAN_OBJ = 14;
+ static final int TYPE_BIG_DECIMAL = 15;
+ static final int TYPE_STRING = 16;
+ static final int TYPE_BYTES = 17;
+ static final int TYPE_SQLDATE = 18;
+ static final int TYPE_TIME = 19;
+ static final int TYPE_TIMESTAMP = 20;
+ static final int TYPE_STREAM = 21;
+ static final int TYPE_READER = 22;
+ static final int TYPE_CLOB = 23;
+ static final int TYPE_BLOB = 24;
+ static final int TYPE_ARRAY = 25;
+ static final int TYPE_REF = 26;
+ static final int TYPE_DATE = 27;
+ static final int TYPE_CALENDAR = 28;
+ static final int TYPE_STRUCT = 29;
+ static final int TYPE_XMLBEAN_ENUM = 30;
+ static final int TYPE_MAX = 31;
+
+ private Map<Class, Object> _primitiveDefaults;
+
+ //
+ // keys in this map are the class of the method's return type,
+ // values are the set of constants defined above all prefixed with
+ // TYPE_
+ //
+ private Map<Class, Integer> _typeMap;
+ private Map<Class, Integer> _typeSqlMap;
+
+ /**
+ * Map a string version of sql type to sql type (java.sql.Types).
+ * example: "INTEGER" maps to java.sql.Types.INTEGER
+ */
+ private Map<String, Integer> _typeSqlNameMap;
+
+ private static Method _methodMapGet;
+
+ /**
+ * Constructor
+ */
+ TypeMappingsFactory() {
+
+ _primitiveDefaults = new HashMap<Class, Object>();
+ _primitiveDefaults.put(Boolean.TYPE, Boolean.FALSE);
+ _primitiveDefaults.put(Integer.TYPE, new Integer(0));
+ _primitiveDefaults.put(Long.TYPE, new Long(0));
+ _primitiveDefaults.put(Byte.TYPE, new Byte((byte) 0));
+ _primitiveDefaults.put(Short.TYPE, new Short((short) 0));
+ _primitiveDefaults.put(Character.TYPE, new Character('\u0000'));
+ _primitiveDefaults.put(Float.TYPE, new Float(0.0f));
+ _primitiveDefaults.put(Double.TYPE, new Double(0.0d));
+
+ // Class to internal enum
+ _typeMap = new HashMap<Class, Integer>(TYPE_MAX * 2);
+ _typeMap.put(Boolean.TYPE, new Integer(TYPE_BOOLEAN));
+ _typeMap.put(Integer.TYPE, new Integer(TYPE_INT));
+ _typeMap.put(Long.TYPE, new Integer(TYPE_LONG));
+ _typeMap.put(Byte.TYPE, new Integer(TYPE_BYTE));
+ _typeMap.put(Short.TYPE, new Integer(TYPE_SHORT));
+ _typeMap.put(Float.TYPE, new Integer(TYPE_FLOAT));
+ _typeMap.put(Double.TYPE, new Integer(TYPE_DOUBLE));
+ _typeMap.put(Boolean.class, new Integer(TYPE_BOOLEAN_OBJ));
+ _typeMap.put(Integer.class, new Integer(TYPE_INT_OBJ));
+ _typeMap.put(Long.class, new Integer(TYPE_LONG_OBJ));
+ _typeMap.put(Byte.class, new Integer(TYPE_BYTE_OBJ));
+ _typeMap.put(Short.class, new Integer(TYPE_SHORT_OBJ));
+ _typeMap.put(Float.class, new Integer(TYPE_FLOAT_OBJ));
+ _typeMap.put(Double.class, new Integer(TYPE_DOUBLE_OBJ));
+ _typeMap.put(String.class, new Integer(TYPE_STRING));
+ _typeMap.put(java.math.BigDecimal.class, new Integer(TYPE_BIG_DECIMAL));
+ _typeMap.put(byte[].class, new Integer(TYPE_BYTES));
+ _typeMap.put(java.sql.Timestamp.class, new Integer(TYPE_TIMESTAMP));
+ _typeMap.put(java.sql.Time.class, new Integer(TYPE_TIME));
+ _typeMap.put(java.sql.Date.class, new Integer(TYPE_SQLDATE));
+ _typeMap.put(java.sql.Ref.class, new Integer(TYPE_REF));
+ _typeMap.put(java.sql.Blob.class, new Integer(TYPE_BLOB));
+ _typeMap.put(java.sql.Clob.class, new Integer(TYPE_CLOB));
+ _typeMap.put(java.sql.Array.class, new Integer(TYPE_ARRAY));
+ _typeMap.put(java.sql.Struct.class, new Integer(TYPE_STRUCT));
+ _typeMap.put(java.io.Reader.class, new Integer(TYPE_READER));
+ _typeMap.put(java.io.InputStream.class, new Integer(TYPE_STREAM));
+ _typeMap.put(java.util.Date.class, new Integer(TYPE_DATE));
+ _typeMap.put(java.util.Calendar.class, new Integer(TYPE_CALENDAR));
+ _typeMap.put(java.util.GregorianCalendar.class, new Integer(TYPE_CALENDAR));
+ _typeMap.put(org.apache.xmlbeans.StringEnumAbstractBase.class, new Integer(TYPE_XMLBEAN_ENUM));
+
+ // Class to java.sql.Types
+ _typeSqlMap = new HashMap<Class, Integer>(TYPE_MAX * 2);
+ _typeSqlMap.put(Boolean.TYPE, new Integer(Types.BOOLEAN));
+ _typeSqlMap.put(Integer.TYPE, new Integer(Types.INTEGER));
+ _typeSqlMap.put(Long.TYPE, new Integer(Types.BIGINT));
+ _typeSqlMap.put(Byte.TYPE, new Integer(Types.TINYINT));
+ _typeSqlMap.put(Short.TYPE, new Integer(Types.SMALLINT));
+ _typeSqlMap.put(Float.TYPE, new Integer(Types.REAL));
+ _typeSqlMap.put(Double.TYPE, new Integer(Types.DOUBLE));
+ _typeSqlMap.put(Boolean.class, new Integer(Types.BOOLEAN));
+ _typeSqlMap.put(Integer.class, new Integer(Types.INTEGER));
+ _typeSqlMap.put(Long.class, new Integer(Types.BIGINT));
+ _typeSqlMap.put(Byte.class, new Integer(Types.TINYINT));
+ _typeSqlMap.put(Short.class, new Integer(Types.SMALLINT));
+ _typeSqlMap.put(Float.class, new Integer(Types.REAL));
+ _typeSqlMap.put(Double.class, new Integer(Types.DOUBLE));
+ _typeSqlMap.put(String.class, new Integer(Types.VARCHAR));
+ _typeSqlMap.put(java.math.BigDecimal.class, new Integer(Types.DECIMAL));
+ _typeSqlMap.put(byte[].class, new Integer(Types.VARBINARY));
+ _typeSqlMap.put(java.sql.Timestamp.class, new Integer(Types.TIMESTAMP));
+ _typeSqlMap.put(java.sql.Time.class, new Integer(Types.TIME));
+ _typeSqlMap.put(java.sql.Date.class, new Integer(Types.DATE));
+ _typeSqlMap.put(java.sql.Ref.class, new Integer(Types.REF));
+ _typeSqlMap.put(java.sql.Blob.class, new Integer(Types.BLOB));
+ _typeSqlMap.put(java.sql.Clob.class, new Integer(Types.CLOB));
+ _typeSqlMap.put(java.sql.Array.class, new Integer(Types.ARRAY));
+ _typeSqlMap.put(java.sql.Struct.class, new Integer(Types.STRUCT));
+ _typeSqlMap.put(java.util.Date.class, new Integer(Types.TIMESTAMP));
+ _typeSqlMap.put(java.util.Calendar.class, new Integer(Types.TIMESTAMP));
+ _typeSqlMap.put(java.util.GregorianCalendar.class, new Integer(Types.TIMESTAMP));
+ _typeSqlMap.put(org.apache.xmlbeans.StringEnumAbstractBase.class, new Integer(Types.VARCHAR));
+
+ // String to java.sql.Types
+ _typeSqlNameMap = new HashMap<String, Integer>(TYPE_MAX * 2);
+ _typeSqlNameMap.put("BIT", new Integer(Types.BIT));
+ _typeSqlNameMap.put("TINYINT", new Integer(Types.TINYINT));
+ _typeSqlNameMap.put("SMALLINT", new Integer(Types.SMALLINT));
+ _typeSqlNameMap.put("INTEGER", new Integer(Types.INTEGER));
+ _typeSqlNameMap.put("BIGINT", new Integer(Types.BIGINT));
+ _typeSqlNameMap.put("FLOAT", new Integer(Types.REAL));
+ _typeSqlNameMap.put("REAL", new Integer(Types.REAL));
+ _typeSqlNameMap.put("DOUBLE", new Integer(Types.DOUBLE));
+ _typeSqlNameMap.put("NUMERIC", new Integer(Types.NUMERIC));
+ _typeSqlNameMap.put("DECIMAL", new Integer(Types.DECIMAL));
+ _typeSqlNameMap.put("CHAR", new Integer(Types.CHAR));
+ _typeSqlNameMap.put("VARCHAR", new Integer(Types.VARCHAR));
+ _typeSqlNameMap.put("LONGVARCHAR", new Integer(Types.LONGVARCHAR));
+ _typeSqlNameMap.put("DATE", new Integer(Types.DATE));
+ _typeSqlNameMap.put("TIME", new Integer(Types.TIME));
+ _typeSqlNameMap.put("TIMESTAMP", new Integer(Types.TIMESTAMP));
+ _typeSqlNameMap.put("BINARY", new Integer(Types.BINARY));
+ _typeSqlNameMap.put("VARBINARY", new Integer(Types.VARBINARY));
+ _typeSqlNameMap.put("LONGVARBINARY", new Integer(Types.LONGVARBINARY));
+ _typeSqlNameMap.put("NULL", new Integer(Types.NULL));
+ _typeSqlNameMap.put("OTHER", new Integer(Types.OTHER));
+ _typeSqlNameMap.put("JAVA_OBJECT", new Integer(Types.JAVA_OBJECT));
+ _typeSqlNameMap.put("DISTINCT", new Integer(Types.DISTINCT));
+ _typeSqlNameMap.put("STRUCT", new Integer(Types.STRUCT));
+ _typeSqlNameMap.put("ARRAY", new Integer(Types.ARRAY));
+ _typeSqlNameMap.put("BLOB", new Integer(Types.BLOB));
+ _typeSqlNameMap.put("CLOB", new Integer(Types.CLOB));
+ _typeSqlNameMap.put("REF", new Integer(Types.REF));
+ _typeSqlNameMap.put("DATALINK", new Integer(Types.DATALINK));
+ _typeSqlNameMap.put("BOOLEAN", new Integer(Types.BOOLEAN));
+
+ // some JAVA synonyms
+ _typeSqlNameMap.put("BYTE", new Integer(Types.TINYINT));
+ _typeSqlNameMap.put("SHORT", new Integer(Types.SMALLINT));
+ _typeSqlNameMap.put("INT", new Integer(Types.INTEGER));
+ _typeSqlNameMap.put("LONG", new Integer(Types.BIGINT));
+
+ // cache the Map.get method for efficiency
+ try {
+ _methodMapGet = java.util.Map.class.getMethod("get", new Class[]{Object.class});
+ } catch (NoSuchMethodException e) {
+ throw new ControlException("Can not find java.util.Map.get(Object) method");
+ }
+ }
+
+ /**
+ * Convert a type string to its SQL Type int value.
+ * @param type A String containing the SQL type name.
+ * @return The SQL type, TYPE_UNKNOWN if cannot convert.
+ */
+ public int convertStringToSQLType(String type) {
+ if (_typeSqlNameMap.containsKey(type.toUpperCase())) {
+ return _typeSqlNameMap.get(type.toUpperCase());
+ }
+ return TYPE_UNKNOWN;
+ }
+
+ /**
+ * Get the SQL type of a class, start at top level class an check all super classes until match is found.
+ * @param classType Class to get SQL type of.
+ * @return Types.OTHER if cannot find SQL type.
+ */
+ public int getSqlType(Class classType) {
+
+ final Class origType = classType;
+ while (classType != null) {
+ Integer type = _typeSqlMap.get(classType);
+ if (type != null) {
+ return type.intValue();
+ }
+ classType = classType.getSuperclass();
+ }
+
+ //
+ // special check for blobs/clobs they are interfaces not derived from
+ //
+ if (Blob.class.isAssignableFrom(origType)) {
+ return _typeSqlMap.get(Blob.class).intValue();
+ } else if (Clob.class.isAssignableFrom(origType)) {
+ return _typeSqlMap.get(Clob.class).intValue();
+ }
+
+ return Types.OTHER;
+ }
+
+ /**
+ * Get the SQL type for an object.
+ * @param o Object to get SQL type of.
+ * @return SQL type of the object, Types.OTHER if cannot classify.
+ */
+ public int getSqlType(Object o) {
+ if (null == o) {
+ return Types.NULL;
+ }
+ return getSqlType(o.getClass());
+ }
+
+ /**
+ *
+ * @param val
+ * @param args
+ * @return
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
+ public Object lookupType(Object val, Object[] args)
+ throws IllegalAccessException, InvocationTargetException
+ {
+ return _methodMapGet.invoke(val, args);
+ }
+
+ /**
+ * Get the type id (defined by this class) for the given class.
+ * @param classType Class to get type of.
+ * @return Type id of class.
+ */
+ public int getTypeId(Class classType) {
+
+ final Class origType = classType;
+ while (null != classType) {
+ Integer typeObj = (Integer) _typeMap.get(classType);
+ if (null != typeObj) {
+ return typeObj.intValue();
+ }
+ classType = classType.getSuperclass();
+ }
+
+ //
+ // special check for blobs/clobs they are interfaces not derived from
+ //
+ if (Blob.class.isAssignableFrom(origType)) {
+ return _typeMap.get(Blob.class).intValue();
+ } else if (Clob.class.isAssignableFrom(origType)) {
+ return _typeMap.get(Clob.class).intValue();
+ }
+
+ return TYPE_UNKNOWN;
+ }
+
+ /**
+ * Returns a primitive legal value as opposed to null if type is primitive.
+ * @param type type to get null value for.
+ * @return null value for specifed type.
+ */
+ public Object fixNull(Class type) {
+ return type.isPrimitive() ? _primitiveDefaults.get(type) : null;
+ }
+
+ /**
+ * Create an Object array for the given array.
+ *
+ * @param o An array.
+ * @return A new object array.
+ */
+ public static Object[] toObjectArray(Object o) {
+
+ Class clas = o.getClass().getComponentType();
+
+ if (null == clas) return null;
+
+ Object[] arr;
+
+ if (clas == Boolean.TYPE) {
+ boolean[] src = (boolean[]) o;
+ arr = new Object[src.length];
+ for (int i = 0; i < src.length; i++)
+ arr[i] = new Boolean(src[i]);
+ } else if (clas == Character.TYPE) {
+ char[] src = (char[]) o;
+ arr = new Object[src.length];
+ for (int i = 0; i < src.length; i++)
+ arr[i] = new Character(src[i]);
+ } else if (clas == Byte.TYPE) {
+ byte[] src = (byte[]) o;
+ arr = new Object[src.length];
+ for (int i = 0; i < src.length; i++)
+ arr[i] = new Byte(src[i]);
+ } else if (clas == Short.TYPE) {
+ short[] src = (short[]) o;
+ arr = new Object[src.length];
+ for (int i = 0; i < src.length; i++)
+ arr[i] = new Short(src[i]);
+ } else if (clas == Integer.TYPE) {
+ int[] src = (int[]) o;
+ arr = new Object[src.length];
+ for (int i = 0; i < src.length; i++)
+ arr[i] = new Integer(src[i]);
+ } else if (clas == Long.TYPE) {
+ long[] src = (long[]) o;
+ arr = new Object[src.length];
+ for (int i = 0; i < src.length; i++)
+ arr[i] = new Long(src[i]);
+ } else if (clas == Float.TYPE) {
+ float[] src = (float[]) o;
+ arr = new Object[src.length];
+ for (int i = 0; i < src.length; i++)
+ arr[i] = new Float(src[i]);
+ } else if (clas == Double.TYPE) {
+ double[] src = (double[]) o;
+ arr = new Object[src.length];
+ for (int i = 0; i < src.length; i++)
+ arr[i] = new Double(src[i]);
+ } else {
+ arr = (Object[]) o;
+ }
+ return arr;
+ }
+}
Added: incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/JdbcFragment.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/JdbcFragment.java?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/JdbcFragment.java (added)
+++ incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/JdbcFragment.java Mon May 9 13:17:58 2005
@@ -0,0 +1,73 @@
+/*
+ * 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 java.lang.reflect.Method;
+import java.util.ArrayList;
+
+/**
+ * Represents an SQL escape sequence found in the SQL annotation's statement member. A JdbcFragment may
+ * contain child SqlFragments, typically these fragments consist of LiteralFragments and ReflectionFragments.
+ * Parameter substitutions may occur within the SQL escape delimiters {}.
+ *
+ * Syntactically an SQL escape sequence must match one of the following forms, where <i>_space_</i> is a whitespace character:
+ *
+ * <UL><LI>{call_space_.....}</LI>
+ * <LI>{?=_space_.....}</LI>
+ * <LI>{d_space_.....}</LI>
+ * <LI>{t_space_.....}</LI>
+ * <LI>{ts_space_.....}</LI>
+ * <LI>{fn_space_.....}</LI>
+ * <LI>{escape_space_.....}</LI>
+ * <LI>{oj_space_.....}</LI>
+ */
+public final class JdbcFragment extends SqlFragmentContainer {
+
+ /**
+ * Create a new JdbcFragment
+ */
+ JdbcFragment() {
+ super();
+ }
+
+ /**
+ * Get the prepared statement parameter value(s) contained within this fragment.
+ *
+ * @param context A ControlBeanContext instance.
+ * @param method The annotated method.
+ * @param args The method's arguments.
+ *
+ * @return null if this fragment doesn't contain a parameter value.
+ */
+ Object[] getParameterValues(ControlBeanContext context, Method method, Object[] args) {
+
+ ArrayList<Object> values = new ArrayList<Object>();
+ for (SqlFragment sf : _children) {
+ if (sf.hasParamValue()) {
+ Object[] moreValues = sf.getParameterValues(context, method, args);
+ for (Object o : moreValues) {
+ values.add(o);
+ }
+ }
+ }
+ return values.toArray();
+ }
+}
Added: incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/LiteralFragment.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/LiteralFragment.java?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/LiteralFragment.java (added)
+++ incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/LiteralFragment.java Mon May 9 13:17:58 2005
@@ -0,0 +1,59 @@
+/*
+ * 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 java.lang.reflect.Method;
+
+/**
+ * Represents a portion of the SQL annotation's statement member which is not within substitution delimiters.
+ * The parser creates LiteralFragements for portions of the SQL statement which do not require any special processing.
+ */
+public final class LiteralFragment extends SqlFragment {
+
+ private final String _value;
+
+ /**
+ * Create an new LiteralFragment with the specified value.
+ * @param value Value of this fragment.
+ */
+ LiteralFragment(String value) {
+ _value = value;
+ }
+
+ /**
+ * Get the text for a PreparedStatement
+ * @param context A ControlBeanContext instance
+ * @param m The annotated method.
+ * @param args The method's parameters.
+ * @return A String containing the literal value for this fragment.
+ */
+ String getPreparedStatementText(ControlBeanContext context, Method m, Object[] args) {
+ return _value;
+ }
+
+ /**
+ * Required for JUnit testing.
+ * @return The String value of this fragment.
+ */
+ public String toString() {
+ return _value;
+ }
+}
Added: incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/ParameterChecker.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/ParameterChecker.java?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/ParameterChecker.java (added)
+++ incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/ParameterChecker.java Mon May 9 13:17:58 2005
@@ -0,0 +1,196 @@
+/*
+ * 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 com.sun.mirror.declaration.ClassDeclaration;
+import com.sun.mirror.declaration.FieldDeclaration;
+import com.sun.mirror.declaration.MethodDeclaration;
+import com.sun.mirror.declaration.ParameterDeclaration;
+import com.sun.mirror.declaration.TypeDeclaration;
+import com.sun.mirror.type.DeclaredType;
+import com.sun.mirror.type.TypeMirror;
+import com.sun.mirror.util.DeclarationFilter;
+import org.apache.beehive.controls.api.ControlException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+
+/**
+ * Does compile-time checking of reflection parameteres in the SQL annotations's statement
+ * element vs. method parameters. Invoked by the JdbcControlChecker.
+ */
+public class ParameterChecker {
+
+ /**
+ * Verify that all reflection parameters in the statement element can be mapped to method parameters.
+ *
+ * @param statement The parsed statement element.
+ * @param methodDecl The method declaration which was annotated.
+ */
+ public static void checkReflectionParameters(SqlFragmentContainer statement, MethodDeclaration methodDecl) {
+
+ ArrayList<ParameterDeclaration> params =
+ new ArrayList<ParameterDeclaration>(methodDecl.getParameters());
+ HashMap<String, ParameterDeclaration> paramMap = new HashMap<String, ParameterDeclaration>();
+
+ // don't run these checks if this is a compiled class file (method names replaced with arg0, arg1, etc)
+ if (params.size() > 0 && params.get(0).getSimpleName().equals("arg0")) {
+ return;
+ }
+
+ for (int i = 0; i < params.size(); i++) {
+ paramMap.put(params.get(i).getSimpleName(), params.get(i));
+ }
+
+ doCheck(statement, paramMap, methodDecl);
+ }
+
+ /**
+ * Walk the tree of children of the statement, process all children of type ReflectionFragment.
+ *
+ * @param statement The parsed statement element.
+ * @param paramMap The method parameters, keyed by name.
+ * @param method The method declaration which was annotated.
+ */
+ private static void doCheck(SqlFragmentContainer statement, HashMap<String, ParameterDeclaration> paramMap,
+ final MethodDeclaration method)
+ {
+
+ SqlFragment[] fragments = statement.getChildren();
+ for (SqlFragment fragment : fragments) {
+
+ // if the fragment is a container check all of its children.
+ if (fragment instanceof SqlFragmentContainer) {
+ doCheck((SqlFragmentContainer) fragment, paramMap, method);
+
+ // reflection fragment - make sure it can be mapped using the method's param values.
+ } else if (fragment instanceof ReflectionFragment) {
+ checkReflectionFragment((ReflectionFragment) fragment, paramMap, method);
+ }
+ }
+ }
+
+ /**
+ * Check the fragment. Must be able to resolve references like 'foo.bar' -> 'foo' where 'foo' is a method param
+ * of a type which contains a public getter or field named 'getBar()' or 'bar' respectively.
+ *
+ * @param fragment The reflection fragment to check.
+ * @param paramMap The method parameters, keyed by name.
+ * @param method The method declaration which was annotated.
+ */
+ private static void checkReflectionFragment(ReflectionFragment fragment,
+ HashMap<String, ParameterDeclaration> paramMap, MethodDeclaration method)
+ {
+
+ final String[] paramNameQualifiers = ((ReflectionFragment) fragment).getParameterNameQualifiers();
+ final String parameterName = ((ReflectionFragment) fragment).getParameterName();
+
+ if (paramMap.containsKey(paramNameQualifiers[0]) == false) {
+ throw new ControlException(buildMessage(parameterName, method.getSimpleName()));
+ }
+
+ ParameterDeclaration tpd = paramMap.get(paramNameQualifiers[0]);
+ TypeMirror type = tpd.getType();
+
+ MethodDeclaration getterMethod = null;
+ FieldDeclaration field = null;
+
+ for (int i = 1; i < paramNameQualifiers.length; i++) {
+
+ getterMethod = null;
+ field = null;
+
+ // loop through superclasses until we find a match or run out of superclasses
+ while (type != null) {
+
+ if (type instanceof DeclaredType == false) {
+ throw new ControlException(buildMessage(parameterName, method.getSimpleName()));
+ }
+
+ TypeDeclaration td = ((DeclaredType) type).getDeclaration();
+ //
+ // abort if Map!!! No further checking can be done.
+ //
+ if (td.getQualifiedName().equals("java.util.Map")) {
+ return;
+ }
+
+ Collection<? extends MethodDeclaration> methods =
+ DeclarationFilter.FILTER_PUBLIC.filter(td.getMethods());
+ for (MethodDeclaration m : methods) {
+ String upperFirst = paramNameQualifiers[i].substring(0,1).toUpperCase();
+ if (paramNameQualifiers[i].length() > 1) {
+ upperFirst = upperFirst + paramNameQualifiers[i].substring(1);
+ }
+ if (m.getSimpleName().equals("get" + upperFirst)
+ || m.getSimpleName().equals("is" + upperFirst)) {
+ getterMethod = m;
+ }
+ }
+
+ if (getterMethod == null) {
+ Collection<FieldDeclaration> fields =
+ DeclarationFilter.FILTER_PUBLIC.filter(td.getFields());
+ for (FieldDeclaration fd : fields) {
+ if (fd.getSimpleName().equals(paramNameQualifiers[i])) {
+ field = fd;
+ }
+ }
+ }
+
+ // try the super-class
+ if (getterMethod == null && field == null) {
+ if (td instanceof ClassDeclaration) {
+ type = ((ClassDeclaration) td).getSuperclass();
+ continue;
+ }
+ }
+
+ break;
+ } // while
+
+ // found a match, get its type and continue within the for loop
+ if (getterMethod != null) {
+ type = getterMethod.getReturnType();
+ } else if (field != null) {
+ type = field.getType();
+ } else {
+ throw new ControlException(buildMessage(parameterName, method.getSimpleName()));
+ }
+ }
+ }
+
+ /**
+ * build the error message for this module.
+ *
+ * @param parameterName
+ * @param methodName
+ * @return
+ */
+ private static String buildMessage(String parameterName, String methodName) {
+ StringBuilder message = new StringBuilder();
+ message.append("Unable to map the parameter in SQL statement ");
+ message.append(parameterName);
+ message.append(" to a parameter of the method ");
+ message.append(methodName);
+ message.append(". Mapping is accomplished by matching a method parameter name to ");
+ message.append("a value delimited by '{' and '}' in the statement element.");
+ return message.toString();
+ }
+}
Added: incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/ParseException.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/ParseException.java?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/ParseException.java (added)
+++ incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/ParseException.java Mon May 9 13:17:58 2005
@@ -0,0 +1,192 @@
+/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */
+package org.apache.beehive.controls.system.jdbc.parser;
+
+/**
+ * This exception is thrown when parse errors are encountered.
+ * You can explicitly create objects of this exception type by
+ * calling the method generateParseException in the generated
+ * parser.
+ *
+ * You can modify this class to customize your error reporting
+ * mechanisms so long as you retain the public fields.
+ */
+public class ParseException extends Exception {
+
+ /**
+ * This constructor is used by the method "generateParseException"
+ * in the generated parser. Calling this constructor generates
+ * a new object of this type with the fields "currentToken",
+ * "expectedTokenSequences", and "tokenImage" set. The boolean
+ * flag "specialConstructor" is also set to true to indicate that
+ * this constructor was used to create this object.
+ * This constructor calls its super class with the empty string
+ * to force the "toString" method of parent class "Throwable" to
+ * print the error message in the form:
+ * ParseException: <result of getMessage>
+ */
+ public ParseException(Token currentTokenVal,
+ int[][] expectedTokenSequencesVal,
+ String[] tokenImageVal
+ )
+ {
+ super("");
+ specialConstructor = true;
+ currentToken = currentTokenVal;
+ expectedTokenSequences = expectedTokenSequencesVal;
+ tokenImage = tokenImageVal;
+ }
+
+ /**
+ * The following constructors are for use by you for whatever
+ * purpose you can think of. Constructing the exception in this
+ * manner makes the exception behave in the normal way - i.e., as
+ * documented in the class "Throwable". The fields "errorToken",
+ * "expectedTokenSequences", and "tokenImage" do not contain
+ * relevant information. The JavaCC generated code does not use
+ * these constructors.
+ */
+
+ public ParseException() {
+ super();
+ specialConstructor = false;
+ }
+
+ public ParseException(String message) {
+ super(message);
+ specialConstructor = false;
+ }
+
+ /**
+ * This variable determines which constructor was used to create
+ * this object and thereby affects the semantics of the
+ * "getMessage" method (see below).
+ */
+ protected boolean specialConstructor;
+
+ /**
+ * This is the last token that has been consumed successfully. If
+ * this object has been created due to a parse error, the token
+ * followng this token will (therefore) be the first error token.
+ */
+ public Token currentToken;
+
+ /**
+ * Each entry in this array is an array of integers. Each array
+ * of integers represents a sequence of tokens (by their ordinal
+ * values) that is expected at this point of the parse.
+ */
+ public int[][] expectedTokenSequences;
+
+ /**
+ * This is a reference to the "tokenImage" array of the generated
+ * parser within which the parse error occurred. This array is
+ * defined in the generated ...Constants interface.
+ */
+ public String[] tokenImage;
+
+ /**
+ * This method has the standard behavior when this object has been
+ * created using the standard constructors. Otherwise, it uses
+ * "currentToken" and "expectedTokenSequences" to generate a parse
+ * error message and returns it. If this object has been created
+ * due to a parse error, and you do not catch it (it gets thrown
+ * from the parser), then this method is called during the printing
+ * of the final stack trace, and hence the correct error message
+ * gets displayed.
+ */
+ public String getMessage() {
+ if (!specialConstructor) {
+ return super.getMessage();
+ }
+ String expected = "";
+ int maxSize = 0;
+ for (int i = 0; i < expectedTokenSequences.length; i++) {
+ if (maxSize < expectedTokenSequences[i].length) {
+ maxSize = expectedTokenSequences[i].length;
+ }
+ for (int j = 0; j < expectedTokenSequences[i].length; j++) {
+ expected += tokenImage[expectedTokenSequences[i][j]] + " ";
+ }
+ if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
+ expected += "...";
+ }
+ expected += eol + " ";
+ }
+ String retval = "Encountered \"";
+ Token tok = currentToken.next;
+ for (int i = 0; i < maxSize; i++) {
+ if (i != 0) retval += " ";
+ if (tok.kind == 0) {
+ retval += tokenImage[0];
+ break;
+ }
+ retval += add_escapes(tok.image);
+ tok = tok.next;
+ }
+ retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
+ retval += "." + eol;
+ if (expectedTokenSequences.length == 1) {
+ retval += "Was expecting:" + eol + " ";
+ } else {
+ retval += "Was expecting one of:" + eol + " ";
+ }
+ retval += expected;
+ return retval;
+ }
+
+ /**
+ * The end of line string for this machine.
+ */
+ protected String eol = System.getProperty("line.separator", "\n");
+
+ /**
+ * Used to convert raw characters to their escaped version
+ * when these raw version cannot be used as part of an ASCII
+ * string literal.
+ */
+ protected String add_escapes(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();
+ }
+
+}
Added: incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/ReflectionFragment.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/ReflectionFragment.java?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/ReflectionFragment.java (added)
+++ incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/ReflectionFragment.java Mon May 9 13:17:58 2005
@@ -0,0 +1,258 @@
+/*
+ * 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.TypeMappingsFactory;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * Represents a method parameter substitution into the SQL annotation's statement member. Delimited by '{' and '}'.
+ * Method parameter names must exactly match the name used in the SQL statement in order for the substitution to occur.
+ * <p/>
+ * <pre>
+ * SQL(statement="SELECT * FROM {tableName}")
+ * public void getAll(String tableName) throws SQLException;
+ * </pre>
+ */
+public final class ReflectionFragment extends SqlFragment {
+
+ private static final String PREPARED_STATEMENT_SUB_MARK = "?";
+ private static final Pattern s_parameterNamePattern = Pattern.compile("\\.");
+
+ private final String _parameterName;
+ private final String[] _nameQualifiers;
+ private int _sqlDataType;
+
+ /**
+ * Create a new ReflectionFragment with the specifed method parameter name.
+ *
+ * @param parameterName The name of the parameter whose value should be substituted at this location.
+ */
+ ReflectionFragment(String parameterName) {
+ _parameterName = parameterName;
+ _sqlDataType = TypeMappingsFactory.TYPE_UNKNOWN;
+ _nameQualifiers = s_parameterNamePattern.split(_parameterName);
+ }
+
+ /**
+ * Create a new ReflectionFragment with the specified method parameter name and SQL type.
+ *
+ * @param parameterName The name of the parameter whose value should be substituted at this location.
+ * @param sqlDataType A String specifing the SQL data type for this parameter.
+ */
+ ReflectionFragment(String parameterName, String sqlDataType) {
+ this(parameterName);
+ if (sqlDataType != null) {
+ _sqlDataType = TypeMappingsFactory.getInstance().convertStringToSQLType(sqlDataType);
+ }
+ }
+
+ /**
+ * Return text generated by this fragment for a PreparedStatement
+ *
+ * @param context A ControlBeanContext instance.
+ * @param m The annotated method.
+ * @param args The method's parameters
+ * @return Always returns a PREPARED_STATEMENT_SUB_MARK
+ */
+ String getPreparedStatementText(ControlBeanContext context, Method m, Object[] args) {
+ return PREPARED_STATEMENT_SUB_MARK;
+ }
+
+ /**
+ * Always true for ReflectionFragment.
+ *
+ * @return true
+ */
+ boolean hasParamValue() { return true; }
+
+ /**
+ * Get the parameter name (as specified in the SQL statement).
+ *
+ * @return The parameter name.
+ */
+ String getParameterName() { return _parameterName; }
+
+ /**
+ * Get a copy of the array of parameter name qualifiers.
+ *
+ * @return An array of parameter name qualifiers.
+ */
+ String[] getParameterNameQualifiers() {
+ String[] nameQualifiersCopy = new String[_nameQualifiers.length];
+ System.arraycopy(_nameQualifiers, 0, nameQualifiersCopy, 0, _nameQualifiers.length);
+ return nameQualifiersCopy;
+ }
+
+ /**
+ * Get the SQL data type of this param.
+ *
+ * @return The SQL data type for this param.
+ */
+ int getParamSqlDataType() { return _sqlDataType; }
+
+ /**
+ * For JUnit testing.
+ *
+ * @return The String value of this fragment.
+ */
+ public String toString() { return PREPARED_STATEMENT_SUB_MARK; }
+
+ /**
+ * Get the value of this parameter.
+ *
+ * @param context ControlBeanContext instance to evaluate the parameter's value against.
+ * @param method Method instance to evaluate against.
+ * @param args Method argument values
+ * @return All parameter object values contained within this fragment
+ */
+ Object[] getParameterValues(ControlBeanContext context, Method method, Object[] args) {
+
+ Object value = null;
+ try {
+ value = context.getParameterValue(method, _nameQualifiers[0], args);
+ } catch (IllegalArgumentException iae) {
+ throw new ControlException("Invalid argument name in SQL statement: " + _nameQualifiers[0], iae);
+ }
+
+ for (int i = 1; i < _nameQualifiers.length; i++) {
+ // handle maps, properties, and fields...
+ value = extractValue(value, _nameQualifiers[i - 1], _nameQualifiers[i]);
+ }
+ return new Object[]{value};
+ }
+
+ //
+ // /////////////////////////////////////////////// PRIVATE METHODS /////////////////////////////////////////////
+ //
+
+ /**
+ * Get the value from the referenced method parameter using java reflection
+ *
+ * @param aValue
+ * @param aName
+ * @param bName
+ * @return
+ */
+ private Object extractValue(Object aValue, String aName, String bName) {
+
+ Class aClass = aValue.getClass();
+ Object value = null;
+
+ //
+ // a.isB() or a.getB()
+ //
+ String bNameCapped = Character.toUpperCase(bName.charAt(0)) + bName.substring(1);
+ Method getMethod = null;
+ Class retType = null;
+
+ //
+ // try a.isB() first, if found verify that a.isB() returns a boolean value,
+ // and that there is not also a a.getB() method - if there is except
+ //
+ try {
+
+ getMethod = aClass.getMethod("is" + bNameCapped, (Class[]) null);
+ retType = getMethod.getReturnType();
+ if (!(retType.equals(Boolean.class) ||
+ retType.equals(Boolean.TYPE))) {
+ // only boolean returns can be isB()
+ getMethod = null;
+ } else {
+ /**
+ * make sure ("get" + bNameCapped) does not exist as well
+ * see CR216159
+ */
+ boolean getMethodFound = true;
+ try {
+ aClass.getMethod("get" + bNameCapped, (Class[])null);
+ } catch (NoSuchMethodException e) {
+ getMethodFound = false;
+ }
+
+ if (getMethodFound) {
+ throw new ControlException("Colliding field accsessors in user defined class '"
+ + aClass.getName() + "' for field '" + bName
+ + "'. Please use is<FieldName> for boolean fields and get<FieldName> name for other datatypes.");
+ }
+ }
+ } catch (NoSuchMethodException e) {
+ }
+
+ //
+ // try a.getB() if a.isB() was not found.
+ //
+ if (getMethod == null) {
+ try {
+ getMethod = aClass.getMethod("get" + bNameCapped, (Class[])null);
+ retType = getMethod.getReturnType();
+ } catch (NoSuchMethodException e) {
+ }
+ }
+
+ if (getMethod != null) {
+ // OK- a.getB()
+ try {
+ value = getMethod.invoke(aValue, (Object[]) null);
+ } catch (IllegalAccessException e) {
+ throw new ControlException("Unable to access public method: " + e.toString());
+ } catch (java.lang.reflect.InvocationTargetException e) {
+ throw new ControlException("Exception thrown when executing : " + getMethod.getName() + "() to use as parameter");
+ }
+ return value;
+ }
+
+ //
+ // try a.b
+ //
+
+ try {
+ value = aClass.getField(bName).get(aValue);
+ return value;
+ } catch (NoSuchFieldException e) {
+ } catch (IllegalAccessException e) {
+ }
+
+ //
+ // try a.get(b)
+ //
+
+ if (aValue instanceof Map) {
+ try {
+ value = TypeMappingsFactory.getInstance().lookupType(aValue, new Object[]{bName});
+ return value;
+ } catch (Exception mapex) {
+ throw new ControlException("Exception thrown when executing Map.get() to resolve parameter" + mapex.toString());
+ }
+ }
+
+ // no other options...
+ if (true) {
+ throw new ControlException("Illegal argument in SQL statement: " + _parameterName.toString()
+ + "; unable to find suitable method of retrieving property " + bName.toString()
+ + " out of object " + aName.toString() + ".");
+ }
+ return null;
+ }
+}
Added: incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SimpleCharStream.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SimpleCharStream.java?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SimpleCharStream.java (added)
+++ incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SimpleCharStream.java Mon May 9 13:17:58 2005
@@ -0,0 +1,401 @@
+/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 3.0 */
+package org.apache.beehive.controls.system.jdbc.parser;
+
+/**
+ * An implementation of interface CharStream, where the stream is assumed to
+ * contain only ASCII characters (without unicode processing).
+ */
+
+public class SimpleCharStream
+{
+ public static final boolean staticFlag = false;
+ int bufsize;
+ int available;
+ int tokenBegin;
+ public int bufpos = -1;
+ protected int bufline[];
+ protected int bufcolumn[];
+
+ protected int column = 0;
+ protected int line = 1;
+
+ protected boolean prevCharIsCR = false;
+ protected boolean prevCharIsLF = false;
+
+ protected java.io.Reader inputStream;
+
+ protected char[] buffer;
+ protected int maxNextCharInd = 0;
+ protected int inBuf = 0;
+
+ protected void ExpandBuff(boolean wrapAround)
+ {
+ char[] newbuffer = new char[bufsize + 2048];
+ int newbufline[] = new int[bufsize + 2048];
+ int newbufcolumn[] = new int[bufsize + 2048];
+
+ try
+ {
+ if (wrapAround)
+ {
+ System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+ System.arraycopy(buffer, 0, newbuffer,
+ bufsize - tokenBegin, bufpos);
+ buffer = newbuffer;
+
+ System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+ System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
+ bufline = newbufline;
+
+ System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+ System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
+ bufcolumn = newbufcolumn;
+
+ maxNextCharInd = (bufpos += (bufsize - tokenBegin));
+ }
+ else
+ {
+ System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+ buffer = newbuffer;
+
+ System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+ bufline = newbufline;
+
+ System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+ bufcolumn = newbufcolumn;
+
+ maxNextCharInd = (bufpos -= tokenBegin);
+ }
+ }
+ catch (Throwable t)
+ {
+ throw new Error(t.getMessage());
+ }
+
+
+ bufsize += 2048;
+ available = bufsize;
+ tokenBegin = 0;
+ }
+
+ protected void FillBuff() throws java.io.IOException
+ {
+ if (maxNextCharInd == available)
+ {
+ if (available == bufsize)
+ {
+ if (tokenBegin > 2048)
+ {
+ bufpos = maxNextCharInd = 0;
+ available = tokenBegin;
+ }
+ else if (tokenBegin < 0)
+ bufpos = maxNextCharInd = 0;
+ else
+ ExpandBuff(false);
+ }
+ else if (available > tokenBegin)
+ available = bufsize;
+ else if ((tokenBegin - available) < 2048)
+ ExpandBuff(true);
+ else
+ available = tokenBegin;
+ }
+
+ int i;
+ try {
+ if ((i = inputStream.read(buffer, maxNextCharInd,
+ available - maxNextCharInd)) == -1)
+ {
+ inputStream.close();
+ throw new java.io.IOException();
+ }
+ else
+ maxNextCharInd += i;
+ return;
+ }
+ catch(java.io.IOException e) {
+ --bufpos;
+ backup(0);
+ if (tokenBegin == -1)
+ tokenBegin = bufpos;
+ throw e;
+ }
+ }
+
+ public char BeginToken() throws java.io.IOException
+ {
+ tokenBegin = -1;
+ char c = readChar();
+ tokenBegin = bufpos;
+
+ return c;
+ }
+
+ protected void UpdateLineColumn(char c)
+ {
+ column++;
+
+ if (prevCharIsLF)
+ {
+ prevCharIsLF = false;
+ line += (column = 1);
+ }
+ else if (prevCharIsCR)
+ {
+ prevCharIsCR = false;
+ if (c == '\n')
+ {
+ prevCharIsLF = true;
+ }
+ else
+ line += (column = 1);
+ }
+
+ switch (c)
+ {
+ case '\r' :
+ prevCharIsCR = true;
+ break;
+ case '\n' :
+ prevCharIsLF = true;
+ break;
+ case '\t' :
+ column--;
+ column += (8 - (column & 07));
+ break;
+ default :
+ break;
+ }
+
+ bufline[bufpos] = line;
+ bufcolumn[bufpos] = column;
+ }
+
+ public char readChar() throws java.io.IOException
+ {
+ if (inBuf > 0)
+ {
+ --inBuf;
+
+ if (++bufpos == bufsize)
+ bufpos = 0;
+
+ return buffer[bufpos];
+ }
+
+ if (++bufpos >= maxNextCharInd)
+ FillBuff();
+
+ char c = buffer[bufpos];
+
+ UpdateLineColumn(c);
+ return (c);
+ }
+
+ /**
+ * @deprecated
+ * @see #getEndColumn
+ */
+
+ public int getColumn() {
+ return bufcolumn[bufpos];
+ }
+
+ /**
+ * @deprecated
+ * @see #getEndLine
+ */
+
+ public int getLine() {
+ return bufline[bufpos];
+ }
+
+ public int getEndColumn() {
+ return bufcolumn[bufpos];
+ }
+
+ public int getEndLine() {
+ return bufline[bufpos];
+ }
+
+ public int getBeginColumn() {
+ return bufcolumn[tokenBegin];
+ }
+
+ public int getBeginLine() {
+ return bufline[tokenBegin];
+ }
+
+ public void backup(int amount) {
+
+ inBuf += amount;
+ if ((bufpos -= amount) < 0)
+ bufpos += bufsize;
+ }
+
+ public SimpleCharStream(java.io.Reader dstream, int startline,
+ int startcolumn, int buffersize)
+ {
+ inputStream = dstream;
+ line = startline;
+ column = startcolumn - 1;
+
+ available = bufsize = buffersize;
+ buffer = new char[buffersize];
+ bufline = new int[buffersize];
+ bufcolumn = new int[buffersize];
+ }
+
+ public SimpleCharStream(java.io.Reader dstream, int startline,
+ int startcolumn)
+ {
+ this(dstream, startline, startcolumn, 4096);
+ }
+
+ public SimpleCharStream(java.io.Reader dstream)
+ {
+ this(dstream, 1, 1, 4096);
+ }
+ public void ReInit(java.io.Reader dstream, int startline,
+ int startcolumn, int buffersize)
+ {
+ inputStream = dstream;
+ line = startline;
+ column = startcolumn - 1;
+
+ if (buffer == null || buffersize != buffer.length)
+ {
+ available = bufsize = buffersize;
+ buffer = new char[buffersize];
+ bufline = new int[buffersize];
+ bufcolumn = new int[buffersize];
+ }
+ prevCharIsLF = prevCharIsCR = false;
+ tokenBegin = inBuf = maxNextCharInd = 0;
+ bufpos = -1;
+ }
+
+ public void ReInit(java.io.Reader dstream, int startline,
+ int startcolumn)
+ {
+ ReInit(dstream, startline, startcolumn, 4096);
+ }
+
+ public void ReInit(java.io.Reader dstream)
+ {
+ ReInit(dstream, 1, 1, 4096);
+ }
+ public SimpleCharStream(java.io.InputStream dstream, int startline,
+ int startcolumn, int buffersize)
+ {
+ this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
+ }
+
+ public SimpleCharStream(java.io.InputStream dstream, int startline,
+ int startcolumn)
+ {
+ this(dstream, startline, startcolumn, 4096);
+ }
+
+ public SimpleCharStream(java.io.InputStream dstream)
+ {
+ this(dstream, 1, 1, 4096);
+ }
+
+ public void ReInit(java.io.InputStream dstream, int startline,
+ int startcolumn, int buffersize)
+ {
+ ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
+ }
+
+ public void ReInit(java.io.InputStream dstream)
+ {
+ ReInit(dstream, 1, 1, 4096);
+ }
+ public void ReInit(java.io.InputStream dstream, int startline,
+ int startcolumn)
+ {
+ ReInit(dstream, startline, startcolumn, 4096);
+ }
+ public String GetImage()
+ {
+ if (bufpos >= tokenBegin)
+ return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+ else
+ return new String(buffer, tokenBegin, bufsize - tokenBegin) +
+ new String(buffer, 0, bufpos + 1);
+ }
+
+ public char[] GetSuffix(int len)
+ {
+ char[] ret = new char[len];
+
+ if ((bufpos + 1) >= len)
+ System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
+ else
+ {
+ System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
+ len - bufpos - 1);
+ System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
+ }
+
+ return ret;
+ }
+
+ public void Done()
+ {
+ buffer = null;
+ bufline = null;
+ bufcolumn = null;
+ }
+
+ /**
+ * Method to adjust line and column numbers for the start of a token.
+ */
+ public void adjustBeginLineColumn(int newLine, int newCol)
+ {
+ int start = tokenBegin;
+ int len;
+
+ if (bufpos >= tokenBegin)
+ {
+ len = bufpos - tokenBegin + inBuf + 1;
+ }
+ else
+ {
+ len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+ }
+
+ int i = 0, j = 0, k = 0;
+ int nextColDiff = 0, columnDiff = 0;
+
+ while (i < len &&
+ bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
+ {
+ bufline[j] = newLine;
+ nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+ bufcolumn[j] = newCol + columnDiff;
+ columnDiff = nextColDiff;
+ i++;
+ }
+
+ if (i < len)
+ {
+ bufline[j] = newLine++;
+ bufcolumn[j] = newCol + columnDiff;
+
+ while (i++ < len)
+ {
+ if (bufline[j = start % bufsize] != bufline[++start % bufsize])
+ bufline[j] = newLine++;
+ else
+ bufline[j] = newLine;
+ }
+ }
+
+ line = bufline[j];
+ column = bufcolumn[j];
+ }
+
+}
Added: incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlFragment.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlFragment.java?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlFragment.java (added)
+++ incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlFragment.java Mon May 9 13:17:58 2005
@@ -0,0 +1,84 @@
+/*
+ * 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;
+
+/**
+ * The abstract base class for fragments generated during parsing.
+ */
+public abstract class SqlFragment {
+
+ /**
+ * True if this fragment shouldn't be cached since the prepared statement may change on each invocation.
+ * @return true if this fragment shouldn't be cached by the parser
+ */
+ boolean isDynamicFragment() {
+ return false;
+ }
+
+ /**
+ * Does this fragment contain a parameter value for a prepared statement
+ * @return true if this fragement doesn't contain a prepared statement value.
+ */
+ boolean hasParamValue() {
+ return false;
+ }
+
+ /**
+ * Get the SQL data type for the parameter value contained within this fragment.
+ * @return The SQL data type for this fragment.
+ */
+ int getParamSqlDataType() {
+ return TypeMappingsFactory.TYPE_UNKNOWN;
+ }
+
+ /**
+ * Get the prepared statement parameter value contained within this fragment.
+ *
+ * @param context A ControlBeanContext instance
+ * @param method The annotated method
+ * @param args The method's parameters
+ * @return null if this fragment doesn't contain a parameter value.
+ */
+ Object[] getParameterValues(ControlBeanContext context, Method method, Object[] args) {
+ return null;
+ }
+
+ /**
+ * Get the text for a prepared statement generated by this fragment.
+ * @param context A ControlBeanContext instance
+ * @param method The annotated method
+ * @param args The method's parameters
+ * @return A String containing the prepared statement text generated by this fragment
+ */
+ abstract String getPreparedStatementText(ControlBeanContext context, Method method, Object[] args);
+
+ /**
+ * Must be implemented for JUnit testing.
+ * @return The String value of this fragment.
+ */
+ public String toString() {
+ assert false : "Classes which extend SqlFragment must implement toString()";
+ return null;
+ }
+}
Added: incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlFragmentContainer.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlFragmentContainer.java?rev=169351&view=auto
==============================================================================
--- incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlFragmentContainer.java (added)
+++ incubator/beehive/trunk/system-controls/src/jdbc/org/apache/beehive/controls/system/jdbc/parser/SqlFragmentContainer.java Mon May 9 13:17:58 2005
@@ -0,0 +1,98 @@
+/*
+ * 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 java.lang.reflect.Method;
+import java.util.ArrayList;
+
+/**
+ * The abstract base class for fragment's which may contain child fragments.
+ */
+public abstract class SqlFragmentContainer extends SqlFragment {
+
+ /** Child fragments of this container. */
+ protected ArrayList<SqlFragment> _children;
+
+ /**
+ * Construct a new SqlFragmentContainer instance.
+ */
+ SqlFragmentContainer() {
+ _children = new ArrayList<SqlFragment>();
+ }
+
+ /**
+ * Does this fragment contain a parameter value for a prepared statement?
+ * @return true If this fragment contains a parameter value for a PreparedStatement.
+ */
+ boolean hasParamValue() {
+ for (SqlFragment f : _children) {
+ if (f.hasParamValue()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Add a child.
+ * @param child Child to add.
+ */
+ void addChild(SqlFragment child) {
+ _children.add(child);
+ }
+
+ /**
+ * Return the array of children.
+ * @return An array of SqlFragments.
+ */
+ SqlFragment[] getChildren() {
+ SqlFragment[] fragments = new SqlFragment[_children.size()];
+ return _children.toArray(fragments);
+ }
+
+ /**
+ * Must be implemented for JUnit testing.
+ * @return The String value of this fragment and all of its child fragments.
+ */
+ public String toString() {
+ StringBuilder s = new StringBuilder();
+ for (SqlFragment f : _children) {
+ s.append(f.toString());
+ }
+ return s.toString();
+ }
+
+ /**
+ * builds the text of the prepared statement
+ *
+ * @param context A ControlBeanContext instance.
+ * @param m The annotated method.
+ * @param args The method's parameters.
+ * @return The PreparedStatement text generated by this fragment and its children.
+ */
+ String getPreparedStatementText(ControlBeanContext context, Method m, Object[] args) {
+ StringBuilder sb = new StringBuilder();
+ for (SqlFragment sf : _children) {
+ sb.append(sf.getPreparedStatementText(context, m, args));
+ }
+ return sb.toString();
+ }
+}