@@ -28,6 +28,7 @@ import org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptor
2828import org.codehaus.groovy.grails.web.pages.GroovyPagesTemplateEngine
2929
3030import org.springframework.core.io.ContextResource
31+ import org.springframework.core.io.Resource ;
3132import org.springframework.context.support.ReloadableResourceBundleMessageSource
3233import org.springframework.web.servlet.i18n.SessionLocaleResolver
3334import org.codehaus.groovy.grails.cli.logging.GrailsConsoleAntBuilder
@@ -112,7 +113,41 @@ class I18nGrailsPlugin {
112113
113114 localeResolver(SessionLocaleResolver )
114115 }
116+
117+ def isChildOfFile (File child , File parent ) {
118+ def currentFile = child. canonicalFile
119+ while (currentFile != null ) {
120+ if (currentFile == parent) {
121+ return true
122+ }
123+ currentFile = currentFile. parentFile
124+ }
125+ return false
126+ }
127+
128+ def relativePath (File relbase , File file ) {
129+ def pathParts = []
130+ def currentFile = file
131+ while (currentFile != null && currentFile != relbase) {
132+ pathParts + = currentFile. name
133+ currentFile = currentFile. parentFile
134+ }
135+ pathParts. reverse(). join(' /' )
136+ }
115137
138+ def findGrailsPluginDir (File propertiesFile ) {
139+ File currentFile = propertiesFile. canonicalFile
140+ File previousFile = null
141+ while (currentFile != null ) {
142+ if (currentFile. name== ' grails-app' && previousFile?. name== ' i18n' ) {
143+ return currentFile. parentFile
144+ }
145+ previousFile = currentFile
146+ currentFile = currentFile. parentFile
147+ }
148+ null
149+ }
150+
116151 def onChange = { event ->
117152 def context = event. ctx
118153 if (! context) {
@@ -121,22 +156,54 @@ class I18nGrailsPlugin {
121156 }
122157
123158 def resourcesDir = BuildSettingsHolder ?. settings?. resourcesDir?. path
124- if (resourcesDir) {
125- String i18nDir = " ${ resourcesDir} /grails-app/i18n"
126-
127- def ant = new GrailsConsoleAntBuilder ()
128-
159+ if (resourcesDir && event. source instanceof Resource ) {
160+ def eventFile = event. source. file. canonicalFile
129161 def nativeascii = event. application. config. grails. enable. native2ascii
130162 nativeascii = (nativeascii instanceof Boolean ) ? nativeascii : true
131- if (nativeascii) {
132- ant. native2ascii(src :" ./grails-app/i18n" ,
133- dest :i18nDir,
134- includes :" *.properties" ,
135- encoding :" UTF-8" )
136- }
137- else {
138- ant. copy(todir :i18nDir) {
139- fileset(dir :" ./grails-app/i18n" , includes :" *.properties" )
163+ def ant = new GrailsConsoleAntBuilder ()
164+ File appI18nDir = new File (" ./grails-app/i18n" ). canonicalFile
165+ if (isChildOfFile(eventFile, appI18nDir)) {
166+ String i18nDir = " ${ resourcesDir} /grails-app/i18n"
167+
168+ def eventFileRelative = relativePath(appI18nDir, eventFile)
169+
170+ if (nativeascii) {
171+ ant. native2ascii(src :" ./grails-app/i18n" ,
172+ dest :i18nDir,
173+ includes :eventFileRelative,
174+ encoding :" UTF-8" )
175+ }
176+ else {
177+ ant. copy(todir :i18nDir) {
178+ fileset(dir :" ./grails-app/i18n" , includes :eventFileRelative)
179+ }
180+ }
181+ } else {
182+ def pluginDir = findGrailsPluginDir(eventFile)
183+
184+ if (pluginDir) {
185+ def info = event. manager. userPlugins. find { plugin ->
186+ plugin. pluginDir?. file?. canonicalFile == pluginDir
187+ }
188+
189+ if (info) {
190+ def pluginI18nDir = new File (pluginDir, " grails-app/i18n" )
191+ def eventFileRelative = relativePath(pluginI18nDir, eventFile)
192+
193+ def destDir = " ${ resourcesDir} /plugins/${ info.fileSystemName} /grails-app/i18n"
194+
195+ ant. mkdir(dir : destDir)
196+ if (nativeascii) {
197+ ant. native2ascii(src : pluginI18nDir. absolutePath,
198+ dest : destDir,
199+ includes : eventFileRelative,
200+ encoding : " UTF-8" )
201+ } else {
202+ ant. copy(todir :destDir) {
203+ fileset(dir :pluginI18nDir. absolutePath, includes :eventFileRelative)
204+ }
205+ }
206+ }
140207 }
141208 }
142209 }
0 commit comments