Custom Ant Task

Posted on: February 29th, 2012 by Spade No Comments »

А что если при сборке приложения вам нужно дождаться выполнения определенного условия – например некоторого флага из базы данных или ответа REST-сервиса? Для этих случаев сборщик Apache Ant предлагает специальный тэг waitfor – он дает возможность приостановить выполнения скрипта до момента наличия некоторого условия. Есть возможность установить сколько ждать, и как часть проверять это условие. Внутри него можно поместить дочерний тэг, который возвращает булево значение. Класс такого тэга должен реализовывать интерфейс org.apache.tools.ant.taskdefs.condition.Condition, главная функция которого – public boolean eval().

Рассмортим пример, в котором требуется проверить некоторое поле в базе данных на соответствие требованиям, и только потом продолжить скрипт. Для реализации  собственного ant task с доступом к базе, нужно наследовать его от org.apache.tools.ant.taskdefs.JDBCTask – тогда нам по умолчанию будут доступны параметры для создания подключения и осуществления запросов. Итак, код класса:

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.condition.Condition;
import org.apache.tools.ant.taskdefs.JDBCTask;
 
import java.sql.*;
 
public class CheckMyDBFlag extends JDBCTask implements Condition {
 
    private String tableName;
    private String fieldName;
    private Long rowId;
 
    @Override
    public boolean eval() throws BuildException {
 
        boolean result = false;
 
        Connection conn = getConnection();
        Statement stmt=null;
        try {
            if (tableName == null) {
                throw new BuildException("TableName must be specified",location);
            }
            String sql = "SELECT count(1) FROM " + tableName + " WHERE flagID = " + rowId + " and " + fieldName + "= 0";
            stmt= conn.createStatement();
            ResultSet rs = stmt.executeQuery(sql);
            if (rs.next()) {
                result = rs.getInt(1) == 1;
            }
            log("result:" + result);
        } catch (SQLException e) {
            log("exception:" + e.getMessage());
        } finally {
            if (stmt != null) {
                try {stmt.close();}catch (SQLException e) {}
            }
            if (conn != null) {
                try {conn.close();}catch (SQLException e) {}
            }
        }
 
        return result;
    }
 
    public void setTableName(String tableName) {
        this.tableName = tableName;
    }
 
    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }
 
    public void setRowId(Long rowId) {
        this.rowId = rowId;
    }
}

Функция getConnection() наследованная от супер-класса создает нам подключение основываясь на обязательных параметрах тэга (настройки подключения к базе).
С помощью переменных класса мы создадим параметры тэга – имя таблицы, имя поля и значения первичного ключа. Конечно, мы немного упростим себе задачу и допустим, что знаем имя поля первичного ключа и значение проверяемого флага. Из публичных методов нужны только setter-ы – чтоб установить значения при разборе xml-тэга. О конвертации типов написано тут.

Скомпилируем класс в jar-архив и скопируем в директорию библиотек нашей установки apache ant.

 

Объявим тэг с типом нашего класса, и используем его внутри waitfor, в свойствах предварительно прописав сколько именно будем ждать.
Voila!

Leave a Reply