2009-11-24 4 views
2

저는 BuilderSupport를 확장하여 Groovy에서 사용자 정의 빌더를 빌드했습니다. 거의 모든 빌더 코드 샘플처럼 구성하면 잘 작동합니다.Groovy BuilderSupport로 외부 컨텐츠

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는"노드에 대해 호출되는 빌더. 필자는 클로저에서 텍스트 블록을 래핑하지 않고 빌더로 직접 전달하는 것을 포함하여 많은 변형을 시도했다. 그들은 모두 동일한 결과를 산출합니다.

임의의 텍스트 조각을 가져 와서 내 작성자에게 전달하면 올바르게 구문 분석하고 빌드 할 수 있습니까?

답변

0

당신이 묘사 한 문제가 슬러퍼 나 파서로 더 잘 해결된다고 생각합니다.

은 참조 :

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

XML 기반의 예제.

귀하의 경우.

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

당신은 그것을 후루룩 소리 내며 먹기 수 : XML 파일을 감안할 때 원래

def text = new File("test.xml").text 
def foo = new XmlSlurper().parseText(text) 
def allEntries = foo.entry 
allEntries.each { 
    println [email protected] 
    println [email protected] 
    println [email protected] 
} 
+0

이 예에서는 여전히 구문 분석 할 콘텐츠가 클래스 경로에 있다고 가정합니다. 이는 내 응용 프로그램에 해당하지 않습니다. 필자의 구성에 XML을 사용하고 싶지는 않습니다. XmlSlurper와 XmlParser의 소스를 살펴 보았고 두 XML 모두 매우 고유했습니다. BuilderSupport와 같은 일반적인 기반이 없기 때문에 처음부터 내 슬러퍼/파서를 작성해야합니다. – Chad

+0

솔기 나는 문제를 일으키지 않았다. 나는 그 의미를 분명히하기 위해 예제를 추가했다. 어쩌면 당신은 그 해결책에 대한 문제가 무엇인지 지적 할 수 있습니다. –

0

을, 나는 외부 파일에

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

를 지정할 수 있기를 원했다. 필자는 XML 및 XML과 같은 구문을 사용하지 않기 때문에 일반 사용자가이 파일을 쉽게 만들고 수정할 수 있습니다. 나의 현재 솔루션은 ConfigSlurper 사용하고 파일은 이제 다음과 같습니다 내가 할 수 있기 때문에 특히 그것은 내 개체를 만들려면 다음 값을 사용하기 아주 간단

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

:

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

ConfigSlurper 나에게 이런지도를 제공합니다 속성/값지도를 생성자에 전달하기 만하면됩니다.

1

문제는 String이 Groovy 코드가 아니라는 것입니다. ConfigSlurper이 처리하는 방법은 의 인스턴스로 텍스트를 컴파일하고 GroovyClassLoader#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) 
} 

위의 코드와 동일합니다.