Skip to content

Instantly share code, notes, and snippets.

@aonic
Created November 18, 2014 16:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aonic/d3bb1f092ed76e3d3e9d to your computer and use it in GitHub Desktop.
Save aonic/d3bb1f092ed76e3d3e9d to your computer and use it in GitHub Desktop.
import org.codehaus.groovy.grails.plugins.codecs.MD5Codec
import org.grails.plugin.resource.mapper.MapperPhase
class HashVersionResourceMapper {
static phase = MapperPhase.RENAMING
def cacheHeadersService
def resourceService
static defaultIncludes = [
"**/*.css",
"**/*.less",
"**/*.js"
]
/**
* Rename the file to a hash of it's contents, and set caching headers
*/
def map(resource, config) {
if (log.debugEnabled) {
log.debug "Hashing resources to unique version param..."
}
String versionHash = getHash(resource.processedFile, resource.processedFileExtension).toString()
resource.linkOverride = "${resource.linkUrl}?v=${versionHash}"
// Do all the horrible cache header stuff
resource.requestProcessors << { req, resp ->
if (log.debugEnabled) {
log.debug "Setting caching headers on ${req.requestURI}"
}
cacheHeadersService.cache resp, [neverExpires: true, shared: true]
}
}
/**
* Returns the config object under 'grails.resources'
*/
ConfigObject getConfig() {
grailsApplication.config.cached.resources
}
/**
* Used to retrieve a resources config param, or return the supplied
* default value if no explicit value was set in config
*/
def getConfigParamOrDefault(String key, defaultValue) {
def param = key.tokenize('.').inject(config) { conf, v -> conf[v] }
if (param instanceof ConfigObject) {
param.size() == 0 ? defaultValue : param
} else {
param
}
}
/**
* Renames the given input file in the same directory to be the MD5 hash of it's contents.
*/
def getHash(File input, String extension) {
MD5Codec.encode(getBytes(input))
}
/**
* File.getBytes() was added in Groovy 1.7.1 - so we roll our own for Grails 1.2 support.
*/
def getBytes(File f) {
def bytes = new ByteArrayOutputStream()
byte[] byteBuffer = new byte[8192]
def bytesRead
f.withInputStream {
while ((bytesRead = it.read(byteBuffer)) != -1) {
bytes.write(byteBuffer, 0, bytesRead)
}
bytes.toByteArray()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment