1

jaxb2-maven-pluginを使用していくつかのxsdファイルをコンパイルするMavenプロジェクトがあります。を使用して、参照されているもののいずれかが変更されているstaleFile かどうかを判別します。schemaFiles残念ながら、問題のxsdファイルは<xs:include schemaLocation="../relative/path.xsd"/>タグを使用して、schemaFile引数にリストされていない他のスキーマファイルを含めるためstaleFile、プラグインでの計算では、実際に再コンパイルする必要がある場合を正確に検出できません。これにより、含まれているスキーマが進化するにつれて、インクリメンタルビルドが中断されます。

明らかに、1つの解決策は、実行ので再帰的に参照されるすべてのファイルをリストすることschemaFileです。ただし、開発者がこれを行わず、ビルドを中断する場合があります。代わりに、このリストの生成を何らかの方法で自動化したいと思います。

頭に浮かぶアプローチの1つは、トップレベルのXSDファイルを何らかの方法で解析してから、プロパティを設定するか、ファイルを出力して、schemaFileパラメーターに渡すことができるようにすることschemaFilesです。Groovy gmavenプラグインは、その機能をPOMに直接埋め込む自然な方法のようです。しかし、私はGroovyを始めるのに十分な知識がありません。

誰かがサンプルコードを提供できますか?または、代替の実装/ソリューションを提供しますか?

ありがとう!

4

2 に答える 2

1

それをMavenビルドにどのように統合するかわからない-Mavenは本当に私のものではありません:-(

ただし、ファイルへのパスがある場合は、次のxsdようにすることで、ファイルが参照するファイルを取得できるはずです。

def rootXsd = new File( 'path/to/xsd' )
def refs = new XmlSlurper().parse( rootXsd ).depthFirst().findAll { it.name()=='include' }.@schemaLocation*.text()
println "$rootXsd references $refs"

含まれているxsdsrefsへのパスとなる文字列のリストも同様です。

于 2011-02-25T14:07:27.300 に答える
1

tim_yatesの回答に基づいて、以下は実行可能なソリューションです。これは、jaxb2プラグインの構成方法に基づいてカスタマイズする必要がある場合があります。

次の構成でgmaven-plugin実行される実行をライフサイクルの早い段階(初期化フェーズなど)で構成します。

参照されるスキーマのファイルオブジェクトを収集する関数から始めます(これはTimの答えを改良したものです)。

def findRefs { f ->
    def relPaths = new XmlSlurper().parse(f).depthFirst().findAll {
        it.name()=='include'
    }*.@schemaLocation*.text()
    relPaths.collect { new File(f.absoluteFile.parent + "/" + it).canonicalFile }
}

すべての子が見つかるまで結果を繰り返す関数でそれをラップします。

def recursiveFindRefs = { schemaFiles ->
    def outputs = [] as Set
    def inputs  = schemaFiles as Queue
    // Breadth-first examine all refs in all schema files
    while (xsd = inputs.poll()) {
        outputs << xsd
        findRefs(xsd).each {
            if (!outputs.contains(it)) inputs.add(it)
        }
    }
    outputs
}

Mavenプロジェクトを解析して何をすべきかを判断すると、本当の魔法が生まれます。まず、JAXBプラグインを見つけます。

jaxb = project.build.plugins.find { it.artifactId == 'jaxb2-maven-plugin' }

次に、そのプラグインの各実行を解析します(複数ある場合)。schemaDirectoryこのコードは、各実行が、を設定schemaFilesstaleFile(つまり、デフォルトを使用しない!)、使用していないことを前提としていschemaListFileNameます。

jaxb.executions.each { ex ->
    log.info("Processing jaxb execution $ex")
    // Extract the schema locations; the configuration is an Xpp3Dom
    ex.configuration.children.each { conf ->
        switch (conf.name) {
            case "schemaDirectory":
                schemaDirectory = conf.value
                break
            case "schemaFiles":
                schemaFiles = conf.value.split(/,\s*/)
                break
            case "staleFile":
                staleFile = conf.value
                break
        }
    }

最後に、schemaFilesを開き、前に定義した関数を使用してそれらを解析できます。

    def schemaHandles = schemaFiles.collect { new File("${project.basedir}/${schemaDirectory}", it) }
    def allSchemaHandles = recursiveFindRefs(schemaHandles)

...最後に変更された時刻を古いファイルの変更時刻と比較し、必要に応じて古いファイルのリンクを解除します。

    def maxLastModified = allSchemaHandles.collect {
            it.lastModified()
        }.max()
    def staleHandle = new File(staleFile)
    if (staleHandle.lastModified() < maxLastModified) {
        log.info("  New schemas detected; unlinking $staleFile.")
        staleHandle.delete()
    }
}
于 2011-02-28T19:00:28.750 に答える