001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ejb.plugins.cmp.jdbc.keygen;
023:
024: import java.sql.PreparedStatement;
025: import java.sql.SQLException;
026: import java.sql.Statement;
027: import java.lang.reflect.Method;
028: import java.lang.reflect.InvocationTargetException;
029:
030: import javax.ejb.EJBException;
031:
032: import org.jboss.ejb.plugins.cmp.jdbc.JDBCIdentityColumnCreateCommand;
033: import org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager;
034: import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCEntityCommandMetaData;
035: import org.jboss.ejb.EntityEnterpriseContext;
036: import org.jboss.deployment.DeploymentException;
037:
038: /**
039: * Create command for Informix that uses the driver's getSerial method
040: * to retrieve SERIAL values. Also supports SERIAL8 columns if method
041: * attribute of entity-command is set to "getSerial8"
042: *
043: * @author <a href="mailto:jeremy@boynes.com">Jeremy Boynes</a>
044: * @author Scott.Stark@jboss.org
045: * @version $Revision: 57209 $
046: */
047: public class JDBCInformixCreateCommand extends
048: JDBCIdentityColumnCreateCommand {
049: private static final String NAME = "class-name";
050: private static final String DEFAULT_CLASS = "com.informix.jdbc.IfxStatement";
051: private static final String METHOD = "method";
052: private static final String DEFAULT_METHOD = "getSerial";
053:
054: private String className;
055: private String methodName;
056: private Method method;
057: private Method getUnderlyingStatement;
058:
059: public void init(JDBCStoreManager manager)
060: throws DeploymentException {
061: super .init(manager);
062: ClassLoader loader = GetTCLAction.getContextClassLoader();
063: try {
064: Class psClass = loader.loadClass(className);
065: method = psClass.getMethod(methodName, null);
066: } catch (ClassNotFoundException e) {
067: throw new DeploymentException(
068: "Could not load driver class: " + className, e);
069: } catch (NoSuchMethodException e) {
070: throw new DeploymentException(
071: "Driver does not have method: " + methodName + "()");
072: }
073:
074: try {
075: Class wrapperClass = loader
076: .loadClass("org.jboss.resource.adapter.jdbc.StatementAccess");
077: getUnderlyingStatement = wrapperClass.getMethod(
078: "getUnderlyingStatement", null);
079: } catch (ClassNotFoundException e) {
080: throw new DeploymentException(
081: "Could not load org.jboss.resource.adapter.jdbc.StatementAccess",
082: e);
083: } catch (NoSuchMethodException e) {
084: throw new DeploymentException(
085: "StatementAccess.getUnderlyingStatement not found",
086: e);
087: }
088: }
089:
090: protected void initEntityCommand(
091: JDBCEntityCommandMetaData entityCommand)
092: throws DeploymentException {
093: super .initEntityCommand(entityCommand);
094: className = entityCommand.getAttribute(NAME);
095: if (className == null) {
096: className = DEFAULT_CLASS;
097: }
098: methodName = entityCommand.getAttribute(METHOD);
099: if (methodName == null) {
100: methodName = DEFAULT_METHOD;
101: }
102: }
103:
104: protected int executeInsert(int paramIndex, PreparedStatement ps,
105: EntityEnterpriseContext ctx) throws SQLException {
106: int rows = ps.executeUpdate();
107:
108: // remove any JCA wrappers
109: Statement stmt = ps;
110: do {
111: try {
112: Object[] args = {};
113: stmt = (Statement) getUnderlyingStatement.invoke(stmt,
114: args);
115: } catch (IllegalAccessException e) {
116: SQLException ex = new SQLException(
117: "Failed to invoke getUnderlyingStatement");
118: ex.initCause(e);
119: throw ex;
120: } catch (InvocationTargetException e) {
121: SQLException ex = new SQLException(
122: "Failed to invoke getUnderlyingStatement");
123: ex.initCause(e);
124: throw ex;
125: }
126: } while (stmt != null
127: && method.getDeclaringClass().isInstance(stmt) == false);
128:
129: try {
130: Number pk = (Number) method.invoke(stmt, null);
131: pkField.setInstanceValue(ctx, pk);
132: return rows;
133: } catch (RuntimeException e) {
134: throw e;
135: } catch (Exception e) {
136: // throw EJBException to force a rollback as the row has been inserted
137: throw new EJBException("Error extracting generated keys", e);
138: }
139: }
140: }
|