ExpandoMetaClass でクラスを拡張する

Groovy 1.1 から ExpandoMetaClass と呼ばれる特別なメタクラスを使用することで指定のクラスに新規にメソッドを追加したり、オーバーライドしたりする事が可能になっている。

ExpandoMetaClass は、metaClass プロパティで提供される

ただし、この機能はインスタンス化の前に実施したものだけが有効となるようで、AOP のように動的に変更することはできない模様。

  • 構文
    • メソッドの追加演算子は << を使用
    • メソッドのオーバーライド演算子は = を使用
  • 記述例
    • コンストラクタ追加
      • xxx.metaClass.constructor << {・・・ -> new xxx(・・・)}
    • インスタンスメソッド追加
      • xxx.metaClass.メソッド名 << {・・・}
    • クラスメソッド追加
      • xxx.metaClass.'static'.メソッド名 << {・・・}

サンプル

//ExpandoMetaClass で POI の Excel 操作系クラスを拡張
import java.io.*
import org.apache.poi.hssf.usermodel.*

//コンストラクタ追加
HSSFWorkbook.metaClass.constructor << {String xlsFileName ->
    new HSSFWorkbook(new FileInputStream(xlsFileName))
}

//メソッド追加
HSSFSheet.metaClass.getCell << {row, col -> 
    rowObj = getRow(row)
    if (rowObj == null) rowObj = createRow(row)

    cellObj = rowObj.getCell((short)col)
    (cellObj != null)? cellObj: rowObj.createCell((short)col)
}

//プロパティ追加
HSSFCell.metaClass.getText << { ->
    richStringCellValue.string
}

//プロパティ追加
HSSFCell.metaClass.setText << {text ->
    setCellValue(new HSSFRichTextString(text))
}

wb = new HSSFWorkbook("test.xls")
sh = wb.getSheet("テストシート")

cell = {row, col -> sh.getCell(row, col)}

println cell(3, 0).text

cell(3, 0).text = "テスト"
cell(10, 3).text = "checkdata"

outfile = new FileOutputStream("test_new.xls")

wb.write(outfile)
outfile.close()