com.nextep.designer.sqlgen.oracle.debug.ctrl.DebugMethod.java Source code

Java tutorial

Introduction

Here is the source code for com.nextep.designer.sqlgen.oracle.debug.ctrl.DebugMethod.java

Source

/*******************************************************************************
 * Copyright (c) 2011 neXtep Software and contributors.
 * All rights reserved.
 *
 * This file is part of neXtep designer.
 *
 * NeXtep designer is free software: you can redistribute it 
 * and/or modify it under the terms of the GNU General Public 
 * License as published by the Free Software Foundation, either 
 * version 3 of the License, or any later version.
 *
 * NeXtep designer is distributed in the hope that it will be 
 * useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     neXtep Softwares - initial API and implementation
 *******************************************************************************/
package com.nextep.designer.sqlgen.oracle.debug.ctrl;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Struct;
import java.sql.Types;
import oracle.jdbc.OracleTypes;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.nextep.datadesigner.exception.ErrorException;
import com.nextep.datadesigner.impl.MethodInvoker;
import com.nextep.designer.core.CorePlugin;
import com.nextep.designer.core.model.IConnection;
import com.nextep.designer.sqlgen.helpers.CaptureHelper;
import com.nextep.designer.sqlgen.ui.services.IBreakpoint;
import com.nextep.designer.sqlgen.ui.services.SQLEditorUIServices;

/**
 * @author Christophe Fondacci
 */
public class DebugMethod extends MethodInvoker {

    private static final Log LOGGER = LogFactory.getLog(DebugMethod.class);

    private Connection targetConn;
    private Connection debugConn;
    private String debugSessionID;

    @Override
    public String getMethodName() {
        return "Debug PL/SQL Procedure";
    }

    @Override
    public Class<?>[] getParameterTypes() {
        return new Class<?>[] { IConnection.class };
    }

    @Override
    public Object invokeMethod(Object... arg) {

        IConnection conn = (IConnection) arg[0];

        CallableStatement stmt = null;
        Thread debuggedThread = null;
        try {
            // Initializing our target connection
            targetConn = CorePlugin.getConnectionService().connect(conn);
            //
            stmt = targetConn.prepareCall("ALTER SESSION SET PLSQL_DEBUG=TRUE"); //$NON-NLS-1$
            try {
                stmt.execute();
            } finally {
                CaptureHelper.safeClose(null, stmt);
            }

            stmt = targetConn.prepareCall("{ ? = CALL DBMS_DEBUG.INITIALIZE() }"); //$NON-NLS-1$
            try {
                stmt.registerOutParameter(1, Types.VARCHAR);
                stmt.execute();
                debugSessionID = stmt.getString(1);
            } catch (SQLException e) {
                throw new ErrorException(e);
            } finally {
                CaptureHelper.safeClose(null, stmt);
            }

            // Switching to debug mode
            stmt = targetConn.prepareCall("{ CALL DBMS_DEBUG.DEBUG_ON() }"); //$NON-NLS-1$
            try {
                stmt.execute();
            } finally {
                CaptureHelper.safeClose(null, stmt);
            }

            // Starting our target code
            debuggedThread = new Thread(new TargetRunnable(targetConn));
            debuggedThread.start();

            // Now that we have our ID, we initialize debug connection
            debugConn = CorePlugin.getConnectionService().connect(conn);
            // new Thread(new DebugRunnable(debugConn,debugSessionID)).start();

            stmt = debugConn.prepareCall("{ CALL DBMS_DEBUG.ATTACH_SESSION(?) }"); //$NON-NLS-1$
            try {
                stmt.setString(1, debugSessionID);
                stmt.execute();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                CaptureHelper.safeClose(null, stmt);
            }

            stmt = debugConn.prepareCall("{ ? = CALL DBMS_DEBUG.SYNCHRONIZE(?,0) }"); //$NON-NLS-1$
            try {
                stmt.registerOutParameter(1, Types.INTEGER);
                stmt.registerOutParameter(2, OracleTypes.OTHER, "DBMS_DEBUG.RUNTIME_INFO"); //$NON-NLS-1$
                stmt.execute();
                Object o = stmt.getObject(2);
                if (o != null) {

                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                CaptureHelper.safeClose(null, stmt);
            }
            // // Setting breakpoints
            // stmt =
            // debugConn.prepareCall("{ call adp_debug.set_breakpoint(p_line=>?, p_name=>?, p_body=>true) }");
            // try {
            // for(IBreakpoint bp : SQLEditorUIServices.getInstance().getBreakpoints()) {
            // stmt.setInt(1, bp.getLine());
            // stmt.setString(2,bp.getTarget().getName());
            // stmt.execute();
            // }
            // } catch( Exception e) {
            // e.printStackTrace();
            // } finally {
            // stmt.close();
            // }
            stmt = debugConn.prepareCall("{ ? = CALL DBMS_DEBUG.CONTINUE(?,0,46) }"); //$NON-NLS-1$
            stmt.registerOutParameter(1, Types.INTEGER);
            stmt.registerOutParameter(2, OracleTypes.OTHER, "DBMS_DEBUG.RUNTIME_INFO"); //$NON-NLS-1$

            try {
                stmt.execute();
                Struct struct = (Struct) stmt.getObject(2);
                Object[] attrs = struct.getAttributes();
                int line = (Integer) attrs[0];
                int terminated = (Integer) attrs[1];
                int breakpoint = (Integer) attrs[2];
                LOGGER.debug(
                        "Continued to line " + line + ", terminated=" + terminated + ", breakpoint=" + breakpoint);
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                CaptureHelper.safeClose(null, stmt);
            }

        } catch (SQLException e) {
            if (debuggedThread != null) {
                debuggedThread.interrupt();
            }
            throw new ErrorException(e);
        } finally {
            try {
                if (debugConn != null) {
                    debugConn.close();
                }
            } catch (SQLException e) {
                throw new ErrorException("Unable to properly close connection: " + e.getMessage(), e);
            }
        }

        return null;
    }

    private class TargetRunnable implements Runnable {

        Connection conn;

        public TargetRunnable(Connection conn) {
            this.conn = conn;
        }

        @Override
        public void run() {
            Statement stmt = null;
            try {
                stmt = conn.createStatement();
                stmt.execute("BEGIN TECH_UTIL.CLEAN_TXT('mytest'); END;"); //$NON-NLS-1$
            } catch (SQLException e) {
                LOGGER.error("Problems in target session", e);
            } finally {
                LOGGER.debug("Terminating target session");
                CaptureHelper.safeClose(null, stmt);
            }
            LOGGER.debug("End target SUCCESS");
        }

    }

    private class DebugRunnable implements Runnable {

        private Connection conn;
        private String debugID;

        public DebugRunnable(Connection conn, String debugID) {
            this.conn = conn;
            this.debugID = debugID;
        }

        @Override
        public void run() {
            CallableStatement stmt = null;
            try {
                stmt = targetConn.prepareCall("{ CALL ADP_DEBUG.START_DEBUGGER(?) }"); //$NON-NLS-1$
                try {
                    stmt.setString(1, debugID);
                    stmt.execute();
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    CaptureHelper.safeClose(null, stmt);
                }
                // Setting breakpoints
                stmt = conn.prepareCall("{ CALL ADP_DEBUG.SET_BREAKPOINT(p_line=>?, p_name=>?, p_body=>true) }"); //$NON-NLS-1$
                try {
                    for (IBreakpoint bp : SQLEditorUIServices.getInstance().getBreakpoints()) {
                        stmt.setInt(1, bp.getLine());
                        stmt.setString(2, bp.getTarget().getName());
                        stmt.execute();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    CaptureHelper.safeClose(null, stmt);
                }

                stmt = targetConn.prepareCall("{ ? = CALL DBMS_DEBUG.CONTINUE(?,0,46) }"); //$NON-NLS-1$
                stmt.registerOutParameter(1, Types.INTEGER);
                stmt.registerOutParameter(2, Types.STRUCT, "DBMS_DEBUG.RUNTIME_INFO"); //$NON-NLS-1$
                try {
                    stmt.execute();
                    Struct struct = (Struct) stmt.getObject(2);
                    Object[] attrs = struct.getAttributes();
                    int line = (Integer) attrs[0];
                    int terminated = (Integer) attrs[1];
                    int breakpoint = (Integer) attrs[2];
                    LOGGER.debug("Continued to line " + line + ", terminated=" + terminated + ", breakpoint="
                            + breakpoint);
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    CaptureHelper.safeClose(null, stmt);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

}