無意味にGrailsドメインクラスをHibernateの*.hbm.xmlファイルをスキャンしてザックリ生成してみる。
別に無意味というわけでないが、
4年ほど前にStruts+Hibernate+Springで開発したアプリケーションを作り直すために、
とりあえずドメインからと・・・・
意外とドメインが多い・・・そして各ドメインのフィールドも多い。。
Grailsでは、そのまま、*.hbm.xmlを使ってJavaのクラスを使用できるのだが、
拡張したり変更したりと、多分grailsのドメインクラスで作業したほうが楽なのかな?
ということで、かなりグダグダなザックリスクリプトを書いてみたので(ほしい人がいるかも・・ってことで)さらしてみる。
仕組みは単純です。
指定したパスにある"*.hbm.xml"ファイルを全てを、XmlSlurperでぐねぐねして、
ガチでドメインクラスファイルを書き出しているだけです。
#自分の必要な物しか取ってきていない・・・。
手順です。
1. create-scriptで新規スクリプト作成。
grails create-script hbm
2. Grailsプロジェクト以下の"scripts"ディレクトリ以下に"Hbm.groovy"ファイルが生成されるので、
以下のソースに入れかえる。=>保存する。
3. 使用方法:"-path"オプションに*.hbm.xmlが置いてあるパスをあたえる。
grails hbm -path /your/file/path/to/hbm
grailsHome = Ant.project.properties."environment.GRAILS_HOME" includeTargets << new File ( "${grailsHome}/scripts/Init.groovy" ) target('default': "scan *.hbm.xml and export domain.groovy") { parseArguments() if(!argsMap?.path){ println "[usage] grails hbm -path _PATH_TO_HBM_Files" System.exit(0) } def hbmDir = new File(argsMap.path) def pattern = ~/.*xml/ hbmDir.eachFileMatch(pattern){f-> def file = new File(""+f) def xml = new XmlSlurper().parse(file) def clsFullName = xml."class"."@name" def clsNameArr = "$clsFullName".split("\\.") //class name def clsName = clsNameArr[clsNameArr.length-1] //package def pkgArr = clsNameArr.getAt(new IntRange(0,clsNameArr.length-2) ) def table = xml."class"."@table" def idElm = xml."class"."id" def idFieldName = idElm."@name" def idColumnName = idElm."@column" def idColumnType = idElm."@type" def idGenerator = idElm."generator"."@class" def idGeneratorSeqName = idElm."generator"."param".text() def fields=[:] def props = xml."class"."property" props.each{p-> def columnName="${p.'@column'}"?"${p.'@column'}":p.'column'.'@name' def map=[ "type":"${p.'@type'}", "column_name":"${columnName}", "column_type":"${p.'column'.'@sql-type'}", "len":"${p.'@length'}" ] fields[p."@name"]=map } def str=[] str<< "class ${clsName} {" str<< "\t"+"static mapping = {" str<< "\t\t"+"table '${table}'" str<< "\t\t"+"version false" str<< "\t\t"+"id column:'${idColumnName}' , type:'integer'" str<< "\t\t"+"id generator:'${idGenerator}', params:[sequence:'${idGeneratorSeqName}']" str<< "" def constrain=[:] fields.each{k,v-> def type = "" if(v.column_type){ type = ",type:'${v.column_type}'" }else if(v.type=="java.lang.Boolean"){ type = ",type:'boolean'" }else if(v.type=="java.lang.Integer"){ def len=v.len?:"4" def intype=len=="4"?"integer":"bigint" type = ",type:'${intype}'" }else if(v.type=="java.lang.String" && v.len!=''){ constrain[k]="maxSize:${v.len}" } str<< "\t\t${k} column:'${v.column_name}' ${type}" } str<< "\t}" str<<"\tInteger id" fields.each{k,v-> str<< "\t${v.type.replace('java.lang.','')} ${k}" } str<< "" str<< "\t"+"static constraints = {" fields.each{k,v-> str<< "\t\t"+"${k}(nullable:true${constrain[k]?' ,'+constrain[k]:''})" } str<< "\t"+"}" str<< "}" def outFile = new File("grails-app/domain","${clsName}.groovy") new FileOutputStream(outFile).withWriter('UTF8'){w-> w << str.join("\n") } } }
Grailsで"script"を活用すると、意外と開発時に便利!