заменить статическое поле - PullRequest
1 голос
/ 14 декабря 2011

CountryTagLib, предоставленный Grails, содержит (устаревший) список стран

class CountryTagLib {
    static final ISO3166_3 = [
        "scg":"Serbia and Montenegro",
        "zmb":"Zambia"
    ]
}

Я хочу обновить эту Карту, чтобы заменить запись "Сербия и Черногория" на запись для каждой из Сербии и Черногории.

Обновление

Я не могу просто обновить содержимое карты или использовать метапрограммирование , поскольку содержимое ISO3166_3 копируется в другие переменные в статическом инициализаторе

static {
    ISO3166_3.each { k, v ->
        COUNTRY_CODES_BY_NAME[v] = k
    }
}

Мне нужен код, который модифицирует ISO3166_3, чтобы он выполнялся до запуска этого статического инициализатора. Я не думаю, что есть какой-то способ добиться этого, поэтому у меня осталась только неприятная опция: скопировать весь CountryTagLib в пользовательский taglib и изменить в нем ISO3166_3. Мне также придется менять каждые <g:countrySelect>, чтобы использовать вместо этого мой тег. Я действительно не хочу этого делать ...

Ответы [ 2 ]

2 голосов
/ 14 декабря 2011

метод Яна является самым чистым ИМО, но для дальнейшего использования; Один способ вернуться к замененному методу в переопределении метакласса - это сохранить где-то старый метод, а затем вызвать его в новом методе:

class CountryTagLib {
    static final ISO3166_3 = [
        "scg":"Serbia and Montenegro",
        "zmb":"Zambia"
    ]
}

// Get a handle to our old static getISO3166_3 method
def originalGetter = CountryTagLib.metaClass.getStaticMetaMethod( 'getISO3166_3', [] as Object[] )
CountryTagLib.metaClass.static.getISO3166_3 = {
    // Call the old method, and manipulate the map it returns
    originalGetter.invoke( delegate, null ).with {
      remove('scg')
      put( 'srb', 'Serbia' )
      put( 'mon', 'Montenegro' )
      it
    }
}
2 голосов
/ 14 декабря 2011

Почему у вас нет прямого доступа к карте?Поле final означает, что вы не можете изменять само поле, но не его содержимое:

Вы не можете сделать:

CountryTagLib.ISO3166_3 = xxxx // this will fail (final)

, но это должно работать:

CountryTagLib.ISO3166_3.remove('scg')
..etc...
...