/** * ログ取得コードをThrowableのcatch節として追加する * * @param pool Statementを含むプール * @param ctClass PreparedStatementを実装するクラス * @param behaviour behaviour * @throws CannotCompileException コンパイルができないときの例外 */ public static void convertCatch( final ClassPool pool, final CtClass ctClass, final CtBehavior behaviour) throws CannotCompileException { try { CtClass throwable = pool.get("java.lang.Throwable"); // メソッドの定義がない場合は実行しない。 final int MODIFIER = behaviour.getModifiers(); if (Modifier.isAbstract(MODIFIER)) { return; } // JavelinLogger#writeExceptionLogの呼び出しコードを作成する。 StringBuffer code = new StringBuffer(); // 後処理(例外場合) code.append(JAVELIN_RECORDER_NAME); code.append(".postProcessNG("); code.append("$e"); code.append(");"); // 例外を再throwする。 code.append("throw $e;"); // ログ取得コードをThrowableのcatch節として追加する。 behaviour.addCatch(code.toString(), throwable); } catch (NotFoundException nfe) { SystemLogger.getInstance().warn(nfe); } }
/** * Statementのメソッドに対して計測コードを埋め込む。 * * @param pool Statementを含むプール。 * @param ctClass Statementを実装するクラス * @return 変換結果 */ public static CtClass convertConnection(final ClassPool pool, final CtClass ctClass) { CtClass jvnConnction; try { jvnConnction = pool.get(JdbcJavelinConnection.class.getCanonicalName()); boolean hasInterface = hasInterface(ctClass, jvnConnction); if (hasInterface == false) { ctClass.addInterface(jvnConnction); } // すでにメソッドを追加している場合は処理を行わない if (hasBehavior(ctClass, "getJdbcJavelinProcessor")) { return ctClass; } CtField procField = CtField.make( "private " + DBProcessor.class.getCanonicalName() + " dbProcessor_;", ctClass); ctClass.addField(procField); CtMethod procGetMethod = CtMethod.make( "public " + DBProcessor.class.getCanonicalName() + " getJdbcJavelinProcessor(){ return dbProcessor_; }", ctClass); ctClass.addMethod(procGetMethod); CtMethod procSetMethod = CtMethod.make( "public void setJdbcJavelinProcessor(" + DBProcessor.class.getCanonicalName() + " dbProcessor){ dbProcessor_ = dbProcessor; }", ctClass); ctClass.addMethod(procSetMethod); CtField urlField = CtField.make("private String jdbcUrl_;", ctClass); ctClass.addField(urlField); CtMethod urlMethod = CtMethod.make("public String getJdbcUrl(){ return jdbcUrl_; }", ctClass); ctClass.addMethod(urlMethod); CtMethod urlSetMethod = CtMethod.make( "public void " + "setJdbcUrl(String jdbcUrl)" + "{ jdbcUrl_ = jdbcUrl; }", ctClass); ctClass.addMethod(urlSetMethod); } catch (NotFoundException ex) { SystemLogger.getInstance().warn(ex); return null; } catch (CannotCompileException ex) { SystemLogger.getInstance().warn(ex); return null; } CtBehavior[] behaviors = ctClass.getDeclaredBehaviors(); for (int index = 0; index < behaviors.length; index++) { CtBehavior method = behaviors[index]; // メソッドの定義がない場合、あるいはpublicでない // (->インターフェースに定義されていない)場合は実行しない。 final int MODIFIER = method.getModifiers(); if (Modifier.isAbstract(MODIFIER) || !Modifier.isPublic(MODIFIER)) { continue; } // BCI対象クラス「java.sql.Connection」に対して、コード転換を行う String methodName = method.getName(); try { if ("prepareStatement".equals(methodName)) { addSqlToFieldCon(ctClass, method); } else if ("prepareCall".equals(methodName)) { addSqlToFieldCon(ctClass, method); } } catch (CannotCompileException ex) { SystemLogger.getInstance().warn(ex); } } try { return ctClass; } catch (Exception ex) { SystemLogger.getInstance().warn(ex); return null; } }