2

BuilderSupport を拡張して、Groovy でカスタム ビルダーを構築しました。ほぼすべてのビルダー コード サンプルのように構成すると、うまく機能します。

def builder = new MyBuilder()
builder.foo {
    "Some Entry" (property1:value1, property2: value2)
}

もちろん、これは完全に機能します。問題は、私が構築している情報をコードに含めたくないということです。この情報を、ビルダーによって読み取られてオブジェクトに組み込まれるファイルに保存したいと考えています。これを行う方法がわかりません。

コード内で単純なエントリを移動しても、これを機能させることはできません。これは機能します:

def textClosure = { "Some Entry" (property1:value1, property2: value2) }
builder.foo(textClosure)

textClosure はクロージャーであるためです。

私がこれを行う場合:

def text = '"Some Entry" (property1:value1, property2: value2)'
def textClosure = { text }
builder.foo(textClosure)

ビルダーは「foo」ノードに対してのみ呼び出されます。テキストブロックをクロージャーでラップせずにビルダーに直接渡すなど、これの多くのバリエーションを試しました。それらはすべて同じ結果をもたらします。

任意のテキストを取得してビルダーに渡し、正しく解析してビルドできるようにする方法はありますか?

4

3 に答える 3

1

問題は、 String が Groovy コードではないことです。これを処理する方法は、テキストをusingConfigSlurperのインスタンスにコンパイルすることです。例えば、ScriptGroovyClassLoader#parseClass

// create a Binding subclass that delegates to the builder
class MyBinding extends Binding {
    def builder
    Object getVariable(String name) {
        return { Object... args ->  builder.invokeMethod(name,args) }
    }   
}

// parse the script and run it against the builder
new File("foo.groovy").withInputStream { input ->
    Script s = new GroovyClassLoader().parseClass(input).newInstance()
    s.binding = new MyBinding(builder:builder)
    s.run()
}

Bindingのサブクラスは、呼び出しをビルダーに委譲するすべての変数のクロージャーを返すだけです。したがって、foo.groovy に以下が含まれていると仮定します。

foo {
    "Some Entry" (property1:value1, property2: value2)
}

上記のコードと同等です。

于 2009-12-28T22:08:18.427 に答える
0

もともと指定できるようにしたかった

"Some Entry" (property1:value1, property2: value2)

外部ファイルで。私は特に、XMLやXMLに似た構文を避けて、これらのファイルを通常のユーザーが簡単に作成および変更できるようにしようとしています。私の現在のソリューションはを使用してConfigSlurperおり、ファイルは次のようになります。

"Some Entry"
{ 
   property1 = value1 
   property2 = value2 
}

ConfigSlurper私にこのような地図を与えます:

["Some Entry":[property1:value1,property2:value2]]

これらの値を使用してオブジェクトを作成するのは非常に簡単です。特に、プロパティ/値のマップをコンストラクターに渡すことができるためです。

于 2009-11-25T17:44:00.763 に答える
0

あなたが説明した問題は、スラーパーまたはパーサーでよりよく解決できると思います。

見る:

http://groovy.codehaus.org/Reading+XML+using+Groovy%27s+XmlSlurper http://groovy.codehaus.org/Reading+XML+using+Groovy%27s+XmlParser

XML ベースの例。

あなたの場合。XML ファイルを指定すると、次のようになります。

<foo>
    <entry name='Some Entry' property1="value1" property2="value2"/>
</foo>

あなたはそれを丸呑みすることができます:

def text = new File("test.xml").text
def foo = new XmlSlurper().parseText(text)
def allEntries = foo.entry
allEntries.each { 
    println it.@name
    println it.@property1
    println it.@property2
}
于 2009-11-24T07:51:54.290 に答える