Web hosting packages - JavaSercer Pages 17.3.3 The Action The final database

January 27, 2007 on 10:27 am | In Java | No Comments

JavaSercer Pages 17.3.3 The Action The final database action in the example tag library is the action. A database transaction consists of the execution of a number of SQL statements on the same Connection; they either all succeed or all fail. As you may recall, the data changes resulting from executing all statements are then either permanently saved by committing the transaction, or ignored by rolling back the transaction. The task for the action is to provide a Connection to all database actions enclosed in its body, and commit the transaction when they have all been executed. The nested database actions must cooperate with the action tag handler by retrieving the shared Connection and rolling back the transaction if they fail. Let’s look at how the Connection is handled first. Example 17.22 shows the TransactionTag class declaration, the dataSource property setter method, and the doStartTag( ) method. Example 17.22. Part of the TransactionTag Class package com.ora.jsp.tags.sql; import java.io.*; import java.util.*; import java.sql.*; import javax.sql.*; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; public class TransactionTag extends TagSupport { private String dataSourceName; private Connection conn; public void setDataSource(String dataSourceName) { this.dataSourceName = dataSourceName; } public int doStartTag( ) throws JspException { conn = getTransactionConnection( ); return EVAL_BODY_INCLUDE; } The TransactionTag class extends the TagSupport class. It doesn’t need to access its body content; it only needs to tell the JSP container to execute all actions and possible scripting elements in the body, so the TagSupport class is the proper choice. The dataSource property corresponds to the attribute with the same name. The page author sets it to the name of the DataSource object in the application scope to use for all nested database actions. The doStartTag( ) method, invoked by the container before the actions in the body are processed, sets the conn instance variable by calling the get-TransactionConnection( ) method, shown in Example 17.23. Example 17.23. The TransactionTag’s getTransactionConnection( ) and getConnection( ) Methods private Connection getTransactionConnection( ) throws JspException { DataSource dataSource = (DataSource) pageContext.getAttribute(dataSourceName, PageContext.APPLICATION_SCOPE); if (dataSource == null) { throw new JspException(”dataSource ” + dataSourceName + ” not found”); } try { conn = dataSource.getConnection( ); conn.setAutoCommit(false); } catch (SQLException e) { throw new JspException(”SQL error: ” + e.getMessage( )); } return conn; } Connection getConnection( ) { return conn; } This method retrieves the DataSource object from the application scope and gets a Connection. A Connection automatically commits each SQL statement by default. In order to use the Connection to execute more than one statement within the same transaction, the setAutoCommit( ) method is called with the value false. page 254

Hint: This post is supported by Gama php5 hosting services

JavaSercer Pages 17.3.2 The Action A set of (Cms hosting)

January 27, 2007 on 4:29 am | In Java | No Comments

JavaSercer Pages 17.3.2 The Action A set of value actions can be used inside the body of an or action to set the values for placeholders in the SQL statement. The example tag library contains value actions for date/time values as well as for numeric and string values. The tag handlers for all these actions have a great deal in common, so they all extend a common superclass called com.ora.jsp.tags.sql.value.ValueTag . This superclass contains instance variables and property setter methods for the attributes shared by all value actions: stringValue, pattern, param, name, and property. In addition, it contains methods used by the subclasses to get the value when it’s specified as a parameter name or a bean name plus a property name. Let’s look at the tag handler class for the action as an example. All other value actions follow the same pattern. The com.ora.jsp.tags.sql.IntValueTag class extends the ValueTag class as shown in Example 17.21. Example 17.21. The IntValueTag Class package com.ora.jsp.tags.sql.value; import java.lang.reflect.*; import java.text.*; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import com.ora.jsp.sql.value.*; import com.ora.jsp.tags.sql.ValueTagParent; import com.ora.jsp.util.*; public class IntValueTag extends ValueTag { private int value; public void setValue(int value) { this.value = value; } public int doEndTag( ) throws JspException { if (stringValue != null) { value = toInt(stringValue, pattern); } else if (param != null) { String paramValue = getParameter(param); value = toInt(paramValue, pattern); } else if (name != null) { value = getInt(name, property, pattern); } ValueTagParent parent = (ValueTagParent) findAncestorWithClass(this, ValueTagParent.class); if (parent == null) { throw new JspException(”The sqlIntValue action is not ” + “enclosed by a supported action type”); } parent.addValue(new IntValue(value)); return EVAL_PAGE; } … } The Java datatype is different for each value action, so all subclasses implement their own value property setter methods to store the value in an instance variable. The value property for the IntValueTag is of course an int. Besides the value attribute, all value actions support three other ways to set the value: as a String value specified by the stringValue attribute, as a request parameter specified by the param attribute, or as a bean property specified by the name and property attributes. The ValueTag superclass contains the setter methods and instance variables for these attributes, and the ValueTagExtraInfo class makes sure that a page author uses only one of these alternatives to specify the value. The doEndTag( ) method finds out which alternative is used by looking at all property instance variables in turn. If it’s a String value, defined by the stringValue or param attributes, the method converts the value to an int using a private toInt( ) method. If it’s specified as a bean property, another private method, getInt( ) , is used to invoke the bean to get the value. These private methods are not shown here, but you can look at the source code if you want to see how they work. The enclosing or action’s tag handler is then located, as described in Chapter 16, using the findAncestorWithClass( ) method. The tag handlers for the enclosing actions implement the ValueTagParent interface used as the parent class argument. If an enclosing action is found, its addValue( ) method is called to add the int value wrapped in an IntValue object to the parent’s value list. page 253

Hint: This post is supported by Gama php5 hosting services

JavaSercer Pages Example 17.18. The QueryTag’s execute( ) (Christian web host)

January 26, 2007 on 11:20 pm | In Java | No Comments

JavaSercer Pages Example 17.18. The QueryTag’s execute( ) Method public Object execute(SQLCommandBean sqlCommandBean) throws SQLException, UnsupportedTypeException { return sqlCommandBean.executeQuery( ); } This method simply calls the bean’s executeQuery( ) method. The UpdateTag tag handler uses the bean’s executeUpdate( ) method instead, and wraps the returned int in an Integer object, as shown in Example 17.19. Example 17.19. The UpdateTag’s execute( ) Method public Object execute(SQLCommandBean sqlCommandBean) throws SQLException, UnsupportedTypeException { return new Integer(sqlCommandBean.executeUpdate( )); } The reason for wrapping the int in an Integer is that only real objects can be saved as JSP scope objects; primitive types are not supported. The and the actions define separate TagExtraInfo classes, named QueryTagExtraInfo and UpdateTagExtraInfo, respectively. They both extend a class called com.ora.jsp.tags.sql.DBTagExtraInfo. The isValid( ) method for the DBTagExtraInfo class makes sure a valid value is specified for the scope attribute. It’s shown in Example 17.20. Example 17.20. The DBTagExtraInfo Class package com.ora.jsp.tags.sql; import javax.servlet.jsp.tagext.*; public class DBTagExtraInfo extends TagExtraInfo { /** * Returns true only if a valid scope value is specified: * page, request, session or application. */ public boolean isValid(TagData data) { boolean isValid = false; String scope = data.getAttributeString(”scope”); if (scope == null || scope.equals(”page”) || scope.equals(”request”) || scope.equals(”session”) || scope.equals(”application”)) { isValid = true; } return isValid; } } The QueryTagExtraInfo and UpdateTagExtraInfo classes implement the getVariableInfo( ) method to tell the container about the result variables they create. Here’s the UpdateTagExtraInfo class: package com.ora.jsp.tags.sql; import javax.servlet.jsp.tagext.*; public class UpdateTagExtraInfo extends DBTagExtraInfo { public VariableInfo[] getVariableInfo(TagData data) { if (data.getAttributeString(”id”) == null) { return new VariableInfo[0]; } else { return new VariableInfo[] { new VariableInfo(data.getAttributeString(”id”), “java.lang.Integer”, true, VariableInfo.AT_END) }; } } } The QueryTagExtraInfo class is almost identical. The only difference is that it sets the class name to com.ora.jsp.sql.Row instead of java.lang.Integer. page 252
Note: If you are looking for inexpensive but high quality provider to host and run your serlvet application check Astra servlet hosting services

Jboss hosting - JavaSercer Pages Example 17.15. The DBTag’s doAfterBody( )

January 26, 2007 on 7:04 pm | In Java | No Comments

JavaSercer Pages Example 17.15. The DBTag’s doAfterBody( ) Method public int doAfterBody( ) throws JspException { sqlValue = bodyContent.getString( ); return SKIP_BODY; } The SQL statement may contain question marks as placeholders for values set by nested value actions. As you will see later, the value actions create the appropriate Value subclass and call the DBTag ’s addValue( ) method, shown in Example 17.16. Example 17.16. The DBTag’s addValue( ) Method public void addValue(Value value) { if (values == null) { values = new Vector( ); } values.addElement(value); } This method creates a Vector to hold all values the first time it’s called, and then adds the Value object to the Vector. When called by subsequent value action tag handlers, the Value objects are simply added to the list. The real processing happens in the doEndTag( ) method, shown in Example 17.17. This method is called by the container when the action element’s body has been processed and the end tag is encountered. Example 17.17. The DBTag’s doEndTag( ) Method public int doEndTag( ) throws JspException { Connection conn = getConnection( ); sqlCommandBean.setConnection(conn); sqlCommandBean.setSqlValue(sqlValue); sqlCommandBean.setValues(values); Object result = null; try { result = execute(sqlCommandBean); } catch (SQLException e) { … } catch (UnsupportedTypeException e) { … } finally { … } // Save the result with the specified id in the specified scope if (id != null) { pageContext.setAttribute(id, result, scope); } return EVAL_PAGE; } The private getConnection( ) method is used to get a Connection. The Connection is retrieved either from the DataSource specified by the dataSource attribute value for the or the action itself, or from an enclosing element. We’ll return to getConnection( ) and the exception handling code later when we look at transaction support. The Connection, the SQL statement, and all values (if any) are passed to the bean. Then, the abstract execute( ) method is called to ask the bean to execute the SQL statement. The Object returned by execute( ) is saved in the scope specified by the scope attribute, using the name specified by the id attribute. The implementation of the execute( ) method is the only thing that differs between the tag handlers for the action and the action. The corresponding tag handler classes, QueryTag and UpdateTag, extend the DBTag class and implement the execute( ) method. Example 17.18 shows the implementation in the QueryTag tag handler. page 251

Hint: This post is supported by Gama web hosting php mysql provider

JavaSercer Pages 17.3.1 (Php5 hosting) The and Actions The and

January 26, 2007 on 1:11 pm | In Java | No Comments

JavaSercer Pages 17.3.1 The and Actions The and actions both need access to the action body to read the SQL statement. Hence, the corresponding tag handlers extend the BodyTagSupport class described in Chapter 16. They also implement an interface called com.ora.jsp.sql.ValueParent, which is used by the nested value actions to find the correct parent, following the pattern described for cooperating actions in Chapter 16. These two actions share the same set of attributes and have almost the same behavior, so a common superclass called com.ora.jsp.tags.sql.DBTag implements most of the tag handler functionality for both actions. Example 17.14 shows the top part of the DBTag class, with the class declaration and all property setter methods. Example 17.14. The DBTag Declaration and Properties package com.ora.jsp.tags.sql; import java.util.*; import java.sql.*; import javax.sql.*; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import com.ora.jsp.sql.*; import com.ora.jsp.sql.value.*; public abstract class DBTag extends BodyTagSupport implements ValueTagParent { private SQLCommandBean sqlCommandBean = new SQLCommandBean( ); private String dataSourceName; private String id; private int scope = PageContext.PAGE_SCOPE; private String sqlValue; private Vector values; private boolean isExceptionThrown = false; private boolean isPartOfTransaction = false; public void setDataSource(String dataSourceName) { this.dataSourceName = dataSourceName; } public void setId(String id) { this.id = id; } public void setScope(String scopeName) { if (”page”.equals(scopeName)) { scope = PageContext.PAGE_SCOPE; } else if (”request”.equals(scopeName)) { scope = PageContext.REQUEST_SCOPE; } else if (”session”.equals(scopeName)) { scope = PageContext.SESSION_SCOPE; } else if (”application”.equals(scopeName)) { scope = PageContext.APPLICATION_SCOPE; } } An instance of the SQLCommandBean is kept as a private instance variable. The bean is used to perform all database operations; the tag handler just provides an easy-to-use interface to the bean for page authors. The setter methods for the dataSource and id properties set the corresponding instance variables. The setter method for the scope property converts the String value to the corresponding scope int value defined by the PageContext class before saving the value, since the int value is later needed in the doEndTag( ) method. The page author specifies the SQL statement to execute in the action element’s body. Because the tag handler implements the BodyTag interface (by extending the BodyTagSupport class), it can read the SQL statement in the doAfterBody( ) method as shown in Example 17.15. page 250

Hint: This post is supported by Gama web hosting php mysql provider

Phpnuke hosting - JavaSercer Pages The Column class is an abstract

January 26, 2007 on 6:32 am | In Java | No Comments

JavaSercer Pages The Column class is an abstract class, very similar to the Value class shown in Example 17.4. It contains access methods for all datatypes, with default implementations that throw an UnsupportedConversionException . Each subclass provides a real implementation of the access method corresponding to its type, plus the getString( ) method. Example 17.13 shows the IntColumn class. Example 17.13. The IntColumn Class package com.ora.jsp.sql.column; import com.ora.jsp.sql.Column; public class IntColumn extends Column { private int value; public IntColumn(String name, int value) { super(name); this.value = value; } public int getInt( ) { return value; } public String getString( ) { return String.valueOf(value); } } The constructor takes the column name and value as arguments. The name is used to initialize the Column superclass and is returned by its getName( ) method. 17.3 Developing Generic Database Custom Actions The database custom actions introduced in Chapter 9 can be used like this in a JSP page: UPDATE Account SET Balance = Balance - ? WHERE AccountNumber = ? UPDATE Account SET Balance = Balance + ? WHERE AccountNumber = ? The database custom actions use all of the classes described previously in this chapter. A DataSource available in the application scope is used to get a Connection, and an SQLCommandBean is used to execute the SQL statement specified in the database action element body. The nested value actions create Value subclass instances and add them to a list held by the parent action tag handler. The action saves the result as a Vector of Row objects in the scope specified by the page author. In this section, we first look at how the tag handlers for the , , and actions are implemented. All value actions follow the same pattern as , so they are not described here. At the end of this section, we also look at the tag handler for the action to see how it provides a transaction scope for the database actions nested in its body. page 249
Hint: If you are looking for good and high quality web space to host and run your java application check Vision java web hosting services

Budget web hosting - JavaSercer Pages Example 17.12. The Row’s Column Value

January 25, 2007 on 11:13 pm | In Java | No Comments

JavaSercer Pages Example 17.12. The Row’s Column Value Access Methods public BigDecimal getBigDecimal(int columnIndex) throws NoSuchColumnException, UnsupportedConversionException { Column col = null; try { col = columns[columnIndex - 1]; } catch (ArrayIndexOutOfBoundsException e) { throw new NoSuchColumnException(String.valueOf(columnIndex)); } return col.getBigDecimal( ); } public BigDecimal getBigDecimal(String columnName) throws NoSuchColumnException, UnsupportedConversionException { return getBigDecimal(getIndex(columnName)); } public boolean getBoolean(int columnIndex) throws NoSuchColumnException, UnsupportedConversionException { Column col = null; try { col = columns[columnIndex - 1]; } catch (ArrayIndexOutOfBoundsException e) { throw new NoSuchColumnException(String.valueOf(columnIndex)); } return col.getBoolean( ); } public boolean getBoolean(String columnName) throws NoSuchColumnException, UnsupportedConversionException { return getBoolean(getIndex(columnName)); } … public String getString(int columnIndex) throws NoSuchColumnException { Column col = null; try { col = columns[columnIndex - 1]; } catch (ArrayIndexOutOfBoundsException e) { throw new NoSuchColumnException(String.valueOf(columnIndex)); } return col.getString( ); } public String getString(String columnName) throws NoSuchColumnException { return getString(getIndex(columnName)); } All these methods locate the Column subclass instance specified by the argument and call the corresponding method on the instance. Except for the getString( ) method, this call results in an UnsupportedConversionException if the column is not of the requested type. All types can be converted to a String, however, so a getString( ) call is successful provided that the requested column exists. page 248
Note: If you are looking for cheapest and affordable webspace to host and run your servlet application check Astra j2ee hosting services

JavaSercer Pages 17.2.2 The Row and Column Classes (Windows web hosting)

January 25, 2007 on 3:41 pm | In Java | No Comments

JavaSercer Pages 17.2.2 The Row and Column Classes Let’s now look at the Row and Column classes. Example 17.10 shows a part of the Row class constructor. Example 17.10. The Row Class Constructor package com.ora.jsp.sql; import java.util.*; import java.sql.*; import java.sql.Date; import java.math.*; import com.ora.jsp.sql.column.*; public class Row { private Column[] columns; public Row(ResultSet rs) throws SQLException, UnsupportedTypeException { ResultSetMetaData rsmd = rs.getMetaData( ); int cols = rsmd.getColumnCount( ); columns = new Column[cols]; // Note! Columns are numbered from 1 in the ResultSet for (int i = 1; i <= cols; i++) { int type = rsmd.getColumnType(i); switch (type) { case Types.DATE: columns[i - 1] = new DateColumn(rsmd.getColumnName(i), rs.getDate(i)); break; case Types.TIME: columns[i - 1] = new TimeColumn(rsmd.getColumnName(i), rs.getTime(i)); break; ... default: throw new UnsupportedTypeException("Unsupported SQL " + "data type: " + type); } } } The Row class keeps all column values as an array of Column objects. The constructor is called with a ResultSet that has been positioned at a new row by the caller using the next( ) method. It loops through all columns in the row and creates a Column subclass instance for each. The column's datatype, retrieved from the ResultSetMetaData object, is used to decide which Column subclass to create. Similarly to the Value class structure, the Column class structure contains subclasses corresponding to JDBC column datatypes, as shown in Figure 17.3. Two methods provide access to the number of columns and the array of Column objects, shown in Example 17.11. Example 17.11. The Row's getColumnCount( ) and getColumns( ) Methods public int getColumnCount( ) { return columns.length; } public Column[] getColumns( ) { return columns; } Another set of methods can be used to retrieve the value of an individual column, given its name or index. This set of methods contains one pair per supported datatype. Example 17.12 shows the methods for the BigDecimal, boolean, and String types. page 247
Note: If you are looking for cheap and quality provider to host and run your java application check Astra java hosting services

JavaSercer Pages The executeUpdate( ) method, shown in

January 25, 2007 on 7:38 am | In Java | No Comments

JavaSercer Pages The executeUpdate( ) method, shown in Example 17.9, is very similar to the executeQuery( ) method. Example 17.9. The SQLCommandBean’s executeUpdate( ) Method public int executeUpdate( ) throws SQLException, UnsupportedTypeException { int noOfRows = 0; ResultSet rs = null; PreparedStatement pstmt = null; Statement stmt = null; try { if (values != null && values.size( ) > 0) { // Use a PreparedStatement and set all values pstmt = conn.prepareStatement(sqlValue); setValues(pstmt, values); noOfRows = pstmt.executeUpdate( ); } else { // Use a regular Statement stmt = conn.createStatement( ); noOfRows = stmt.executeUpdate(sqlValue); } } finally { try { if (rs != null) { rs.close( ); } if (stmt != null) { stmt.close( ); } if (pstmt != null) { pstmt.close( ); } } catch (SQLException e) { // Ignore. Probably caused by a previous // SQLException thrown by the outer try block. } } return noOfRows; } The main difference is that the executeUpdate( ) method is used to execute SQL statements that do not return rows, only the number of rows affected by the statement. Examples of such statements are UPDATE, INSERT, and DELETE. In the same way as the executeQuery( ) method, a PreparedStatement is created and initialized with the values defined by the values property, if set. Otherwise a regular Statement is used. The statement is executed and the number of affected rows is returned to the caller. page 246

Hint: If you are looking for very good and affordable webspace to host and run your j2ee hosting application check Sandzak.com j2ee web hosting services

JavaSercer Pages The code for creating (Domino hosting) the PreparedStatement

January 25, 2007 on 12:28 am | In Java | No Comments

JavaSercer Pages The code for creating the PreparedStatement or Statement object and executing the statement is enclosed in a try/finally block. This is important, because if something fails (due to an invalid SQL statement, for instance), the JDBC methods throw an SQLException . You want the exception to be handled by the application using the SQLCommandBean, but first you must make sure that all JDBC resources are released and the Connection object is returned to the pool. Using a try block with a finally clause but no catch clause gives this behavior. If an exception is thrown, the finally clause is executed, and then the exception is automatically thrown to the object that called the executeQuery( ) method. In the finally clause, the ResultSet object and either the PreparedStatement or Statement object are closed. It should be enough to close the statement object according to the JDBC specification (closing the statement should also close the ResultSet associated with the statement), but doing it explicitly doesn’t hurt and makes the code work even with a buggy JDBC driver. Example 17.7 shows a part of the setValues( ) method. Example 17.7. The SQLCommandBean’s setValues( ) Method private void setValues(PreparedStatement pstmt, Vector values) throws SQLException { for (int i = 0; i < values.size( ); i++) { try { Value v = (Value) values.elementAt(i); // Set the value using the method corresponding to // the type. // Note! Set methods are indexed from 1, so we add // 1 to i if (v instanceof BigDecimalValue) { pstmt.setBigDecimal(i + 1, v.getBigDecimal( )); } else if (v instanceof BooleanValue) { pstmt.setBoolean(i + 1, v.getBoolean( )); } ... } catch (UnsupportedConversionException e) { // Can not happen here since we test the type first } } } The setValue( ) method loops through all elements in the Vector with values. For each element, it tests which Value subclass it is and uses the corresponding JDBC method to set the value for the PreparedStatement object. You may wonder why a PreparedStatement is used here, since it's used only once. It's true that a PreparedStatement is intended to be reused over and over again to execute the same SQL statement with new values. But it offers a convenient solution to the problem of different syntax for values of type date/time and numbers when represented by a string literal. When a PreparedStatement is used, the variable values in the SQL statement can be represented by Java variables of the appropriate types without worrying about what literal representation a certain JDBC driver supports. So even though it's used only once, a PreparedStatement still has an advantage over a regular Statement. The toVector( ) method is shown in Example 17.8. Example 17.8. The SQLCommandBean's toVector( ) Method private Vector toVector(ResultSet rs) throws SQLException, UnsupportedTypeException { Vector rows = new Vector( ); while (rs.next( )) { Row row = new Row(rs); rows.addElement(row); } return rows; } This method simply walks through the ResultSet and adds a new Row object for each row to a Vector that it then returns. As you will see later, the Row constructor reads all column values and creates a Column object for each. page 245
Note: If you are looking for cheap and inexpensive provider to host and run your tomcat application check professional tomcat hosting services

« Previous PageNext Page »