Синтаксическая ошибка в моем скрипте Groovy?

Я использую GroovyShell (2.1.7) для динамической оценки кода Groovy. который я сохранил в виде строки.

GroovyShell shell = magicallyInstantiateAndBindGroovyShell();

Вышеупомянутый метод заботится о создании экземпляра оболочки и привязке к ней всех необходимых переменных. Поскольку я считаю, что это синтаксическая ошибка, я не буду загромождать этот вопрос всеми переменными, с которыми связана оболочка, и тем, что на самом деле делает код, который я пытаюсь оценить. Если выяснится, что мне нужно добавить дополнительную информацию к вопросу, чтобы помочь решить мою проблему, я с радостью обязуюсь!

Затем у меня есть строка кода Groovy, которую я пытаюсь оценить:

com.me.myorg.myapp.ExpressionUtils.metaClass.filterMetadata = {
        com.me.myorg.myapp.model.WidgetVO widget, List<String> properties ->
    WidgetVO toReturn = new WidgetVO();

    toReturn.setFizz(widget.getFizz());

    if(widget.getBuzz().equalsIgnoreCase("BIMDER")) {
        toReturn.setMode(widget.getMode());
    }

    for(String property : properties) {
        if("some.prop".equals(property)) {
            Preconditions.checkNotNull(widget.getDescriptions());
            toReturn.setDescriptions(new ArrayList<DescriptionVO>());
            DescriptionVO description = widget.getDescriptions().get(0);
            toReturn.getDescriptions().add(description);
        } else if("another.prop".equals(property)) {
            Preconditions.checkNotNull(widget.getTitles().get(0));
            toReturn.setTitles(new ArrayList<TitleVO>());
            TitleVO title = widget.getTitles().get(0);
            toReturn.getTitles().add(title);
        }
    }

    return toReturn;
};

Который я фактически сохранил как строковую переменную:

String code = "com.me.myorg.myapp.ExpressionUtils.metaClass.filterMetadata = { com.me.myorg.myapp.model.WidgetVO widget, List<String> properties -> WidgetVO toReturn = new WidgetVO(); toReturn.setFizz(widget.getFizz()); if(widget.getBuzz().equalsIgnoreCase(\"BIMDER\")) { toReturn.setMode(widget.getMode()); } for(String property : properties) { if(\"some.prop\".equals(property)) { Preconditions.checkNotNull(widget.getDescriptions()); toReturn.setDescriptions(new ArrayList<DescriptionVO>()); DescriptionVO description = widget.getDescriptions().get(0); toReturn.getDescriptions().add(description); } else if(\"another.prop\".equals(property)) { Preconditions.checkNotNull(widget.getTitles().get(0)); toReturn.setTitles(new ArrayList<TitleVO>()); TitleVO title = widget.getTitles().get(0); toReturn.getTitles().add(title); } } return toReturn; };

Когда я бегу:

shell.evaluate(code);

Я получаю следующее исключение:

startup failed, Script1.groovy: 1: unexpected token: for @ line 1, column 294.
1 error

No signature of method: com.me.myorg.myapp.ExpressionUtils.metaClass.filterMetadata() is applicable for argument types: (com.me.myorg.myapp.model.WidgetVO, java.util.ArrayList) values: {com.me.myorg.myapp.model.WidgetVO@9427908c, ["some.prop", "another.prop"]}

Столбец 294 — это начало цикла for... но мне кажется, что это идеальный код. Я где-нибудь забыл закрывающую скобку? Какая-то другая синтаксическая ошибка? Где я ошибаюсь? Заранее спасибо!


person Community    schedule 07.11.2013    source источник


Ответы (1)


У вас есть:

if(widget.getBuzz().equalsIgnoreCase(\"BIMDER\")) { toReturn.setMode(widget.getMode()); } for(String property : properties)

Вам нужна точка с запятой перед for...

Почему бы не использовать многострочную строку?

String code = """com.me.myorg.myapp.ExpressionUtils.metaClass.filterMetadata = { com.me.myorg.myapp.model.WidgetVO widget, List<String> properties ->
                |    WidgetVO toReturn = new WidgetVO()
                |    toReturn.setFizz(widget.getFizz())
                |    if( widget.getBuzz().equalsIgnoreCase( "BIMDER" ) ) {
                |        toReturn.setMode(widget.getMode())
                |    }
                |    for( String property : properties ) {
                |        if( "some.prop" == property ) { 
                |            Preconditions.checkNotNull( widget.descriptions )
                |            toReturn.descriptions = [ widget.descriptions[ 0 ] ]
                |        }
                |        else if( "another.prop" == property ) { 
                |            Preconditions.checkNotNull( widget.titles[ 0 ] )
                |            toReturn.titles = [ widget.titles[ 0 ] ]
                |        }
                |    }
                |    toReturn
                |}""".stripMargin()
person tim_yates    schedule 07.11.2013
comment
Спасибо @tim_yates (+1) - но я думаю, что вы неправильно скопировали мою строку. Если вы заметили, перед for стоит точка с запятой: toReturn.setMode(widget.getMode());. - person ; 07.11.2013
comment
@TicketMonster Да, но это внутри фигурных скобок оператора if перед for... У вас есть if( x ) { y ; } for..., НЕ if( x ) { y } ; for... - person tim_yates; 07.11.2013
comment
Ааа, понятно (снова +1!), поэтому я добавил точку с запятой сразу после закрывающей фигурной скобки оператора if, и теперь я получаю следующую ошибку: startup failed, Script1.groovy: 1: expecting '}', found 'return' @ line 1, column 810. 1 error. Я что-то сломал, или в моем коде 2 синтаксические ошибки? - person ; 07.11.2013
comment
Нужно ли добавлять точку с запятой после if и else if внутри цикла for? - person ; 07.11.2013
comment
@TicketMonster Вам понадобится точка с запятой перед return toReturn в конце ... Сделайте это как многострочную строку, у вас будет меньше головной боли ;-) - person tim_yates; 07.11.2013