asset.pipeline.i18n.I18nProcessor.groovy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of i18n-asset-pipeline-grails Show documentation
Show all versions of i18n-asset-pipeline-grails Show documentation
asset-pipeline plugin to use localized messages in JavaScript.
/*
* I18nProcessor.groovy
*
* Copyright (c) 2014-2016, Daniel Ellermann
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package asset.pipeline.i18n
import asset.pipeline.AbstractProcessor
import asset.pipeline.AssetCompiler
import asset.pipeline.AssetFile
import asset.pipeline.AssetPipelineConfigHolder
import asset.pipeline.fs.AssetResolver
import asset.pipeline.fs.JarAssetResolver
import grails.io.IOUtils
import grails.plugins.GrailsPlugin
import grails.plugins.Plugin
import grails.util.Environment
import grails.util.Holder
import grails.util.Holders
import groovy.transform.CompileStatic
import org.grails.plugins.BinaryGrailsPlugin
import org.springframework.core.io.FileSystemResource
import org.springframework.core.io.InputStreamResource
import org.springframework.core.io.UrlResource
import java.util.jar.JarEntry
import java.util.jar.JarFile
import java.util.regex.Matcher
import org.springframework.core.io.DefaultResourceLoader
import org.springframework.core.io.Resource
import org.springframework.core.io.ResourceLoader
import groovy.util.logging.Slf4j
import java.util.regex.Pattern
/**
* The class {@code I18nProcessor} represents an asset processor which converts
* i18n file consisting of code keys to localized messages and builds a
* JavaScript file containing the function {@code $L} to obtain localized
* strings on client side.
*
* I18n files must obey the following rules:
*
* - The file name (without extension) must end with the locale
* specification, e. g. {@code messages_de.i18n} or
* {@code msg_en_UK.i18n}.
* - The files are line based.
* - All lines are trimmed (that is, whitespaces are removed from beginning
* and end of lines.
* - Empty lines and lines starting with a hash {@code #} (comment lines)
* are ignored.
* - Lines starting with
@import path
are replaced by
* the content of the file with path path
. The suffix
* {@code .i18n} at path is optional and is appended automatically.
* - All other lines are treated as code keys which will be looked up in
* Grails message resources for the locale specified in the file.
*
*
* @author Daniel Ellermann
* @author David Estes
* @version 3.0
*/
@CompileStatic
@Slf4j
class I18nProcessor extends AbstractProcessor {
//-- Constants ------------------------------
protected static final String PROPERTIES_SUFFIX = '.properties'
protected static final String XML_SUFFIX = '.xml'
//-- Fields ---------------------------------
ResourceLoader resourceLoader = new DefaultResourceLoader()
//-- Constructors ---------------------------
/**
* Creates a new i18n resource processor within the given asset
* pre-compiler.
*
* @param precompiler the given asset pre-compiler
*/
I18nProcessor(AssetCompiler precompiler) {
super(precompiler)
}
//-- Public methods -------------------------
@Override
String process(String inputText, AssetFile assetFile) {
Matcher m = assetFile.name =~ /(\w+?)(_\w+)?\.i18n$/
def options = []
if(m){
def baseFile = m.group(1)
if (m.group(2)){
def locales = m.group(2).split('_')
def sb = new StringBuffer(baseFile)
for(locale in locales){
if(locale.empty){
options << sb.toString()
}
else{
sb.append('_').append(locale)
options << sb.toString()
}
}
}
else{
options << baseFile
}
}
else{
options << 'messages'
}
Properties props
if (assetFile.encoding != null) {
props = loadMessages(options, assetFile.encoding)
} else {
props = loadMessages(options)
}
// At this point, inputText has been pre-processed (I18nPreprocessor).
Map messages = [:]
inputText.toString()
.eachLine { String line ->
if (line != '') {
if(line.startsWith('regexp:')){
def p = Pattern.compile(line.substring('regexp:'.length()).trim())
Map