View Javadoc

1   /*
2    * Copyright 2002,2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.commons.jelly.tags.sql;
18  
19  import java.sql.Connection;
20  import java.sql.PreparedStatement;
21  import java.sql.SQLException;
22  import java.sql.Statement;
23  
24  import org.apache.commons.jelly.JellyTagException;
25  import org.apache.commons.jelly.XMLOutput;
26  import org.apache.commons.jelly.tags.Resources;
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  
30  /***
31   * <p>Tag handler for &lt;Update&gt; in JSTL.
32   *
33   * @author Hans Bergsten
34   * @author Justyna Horwat
35   */
36  
37  public class UpdateTag extends SqlTagSupport {
38  
39      /*** The Log to which logging calls will be made. */
40      private static final Log log = LogFactory.getLog(UpdateTag.class);
41  
42      /*
43       * Instance variables that are not for attributes
44       */
45      private Connection conn;
46  
47      //**********************************************************************
48      // Constructor and initialization
49  
50      public UpdateTag() {
51      }
52  
53      //*********************************************************************
54      // Tag logic
55  
56      /**
57       * <p>Execute the SQL statement, set either through the <code>sql</code>
58       * attribute or as the body, and save the result as a variable
59       * named by the <code>var</code> attribute in the scope specified
60       * by the <code>scope</code> attribute, as an object that implements
61       * the Result interface.
62       *
63       * <p>The connection used to execute the statement comes either
64       * from the <code>DataSource</code> specified by the
65       * <code>dataSource</code> attribute, provided by a parent action
66       * element, or is retrieved from a JSP scope  attribute
67       * named <code>javax.servlet.jsp.jstl.sql.dataSource</code>.
68       */
69      public void doTag(XMLOutput output) throws JellyTagException {
70          try {
71              conn = getConnection();
72          }
73          catch (SQLException e) {
74              throw new JellyTagException(sql + ": " + e.getMessage(), e);
75          }
76  
77          /*
78           * Use the SQL statement specified by the sql attribute, if any,
79           * otherwise use the body as the statement.
80           */
81          String sqlStatement = null;
82          if (sql != null) {
83              sqlStatement = sql;
84          }
85          else {
86              sqlStatement = getBodyText();
87          }
88          if (sqlStatement == null || sqlStatement.trim().length() == 0) {
89              throw new JellyTagException(Resources.getMessage("SQL_NO_STATEMENT"));
90          }
91  
92          Statement statement = null;
93          int result = 0;
94          try {
95              if ( hasParameters() ) {
96                  PreparedStatement ps = conn.prepareStatement(sqlStatement);
97                  statement = ps;
98                  setParameters(ps);
99                  result = ps.executeUpdate();
100             }
101             else {
102                 statement = conn.createStatement();
103                 result = statement.executeUpdate(sqlStatement);
104             }
105             if (var != null) {
106                 context.setVariable(var, new Integer(result));
107             }
108 
109             // lets nullify before we close in case we get exceptions
110             // while closing, we don't want to try to close again
111             Statement tempStatement = statement;
112             statement = null;
113             tempStatement.close();
114         }
115         catch (SQLException e) {
116             throw new JellyTagException(sqlStatement + ": " + e.getMessage(), e);
117         }
118         finally {
119             if (statement != null) {
120                 try {
121                     statement.close();
122                 }
123                 catch (SQLException e) {
124                     log.error("Caught exception while closing statement: " + e, e);
125                 }
126             }
127             if (conn != null && !isPartOfTransaction) {
128                 try {
129                     conn.close();
130                 }
131                 catch (SQLException e) {
132                     log.error("Caught exception while closing connection: " + e, e);
133                 }
134             }
135             clearParameters();
136         }
137     }
138 }