Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CacheHeadersGrailsPlugin.groovy
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import org.codehaus.groovy.grails.commons.ConfigurationHolder
import groovy.util.ConfigObject
import com.grailsrocks.cacheheaders.ControllerAnnotationHelper

class CacheHeadersGrailsPlugin {
def version = "1.1.5"
Expand Down Expand Up @@ -29,7 +30,8 @@ Improve your application performance with browser caching, with easy ways to set
}

def doWithDynamicMethods = { ctx ->
addCacheMethods(application, log)
addCacheMethods(application, log)
ControllerAnnotationHelper.init()
}

void reloadConfig(svc, log) {
Expand Down
13 changes: 13 additions & 0 deletions grails-app/conf/UrlMappings.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class UrlMappings {

static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}

"/"(view:"/index")
"500"(view:'/error')
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.grailsrocks.cacheheaders

class ResponseCacheHeadersFilters {
CacheHeadersService cacheHeadersService

def filters = {
all(controller: '*', action: '*') {
before = {
if (ControllerAnnotationHelper.requiresAnnotation(NoCaching.class, controllerName, actionName)) {
cacheHeadersService.cache(response, false)
}
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.grailsrocks.cacheheaders

class TestAnnotationController {
@NoCaching
def annotations = {
println 'bar'
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.grailsrocks.cacheheaders

import java.text.SimpleDateFormat

class CacheHeadersService {

static transactional = false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.grailsrocks.cacheheaders

import org.codehaus.groovy.grails.commons.ApplicationHolder as ApplicationHolder

import org.apache.commons.lang.WordUtils

//http://burtbeckwith.com/blog/?p=80
class ControllerAnnotationHelper {
private static Map<String, Map<String, List<Class>>> _actionMap = [:]
private static Map<String, Class> _controllerAnnotationMap = [:]

/**
* Find controller annotation information.
*/
static void init() {
ApplicationHolder.application.controllerClasses.each { controllerClass ->
def clazz = controllerClass.clazz
String controllerName = WordUtils.uncapitalize(controllerClass.name)
mapClassAnnotation clazz, NoCaching, controllerName

Map<String, List<Class>> annotatedClosures = findAnnotatedClosures(
clazz, NoCaching)
if (annotatedClosures) {
_actionMap[controllerName] = annotatedClosures
}
}
}

public static boolean requiresAnnotation(Class annotationClass,
String controllerName, String actionName) {

// see if the controller has the annotation
def annotations = _controllerAnnotationMap[controllerName]
if (annotations && annotations.contains(annotationClass)) {
return true
}

// otherwise check the action
Map<String, List<Class>> controllerClosureAnnotations =
_actionMap[controllerName] ?: [:]
List<Class> annotationClasses = controllerClosureAnnotations[actionName]
return annotationClasses && annotationClasses.contains(annotationClass)
}

private static void mapClassAnnotation(clazz, annotationClass, controllerName) {
if (clazz.isAnnotationPresent(annotationClass)) {
def list = _controllerAnnotationMap[controllerName] ?: []
list << annotationClass
_controllerAnnotationMap[controllerName] = list
}
}

private static Map<String, List<Class>> findAnnotatedClosures(
Class clazz, Class... annotationClasses) {

// since action closures are defined as "def foo = ..." they're
// fields, but they end up private
def map = [:]
for (field in clazz.declaredFields) {
def fieldAnnotations = []
for (annotationClass in annotationClasses) {
if (field.isAnnotationPresent(annotationClass)) {
fieldAnnotations << annotationClass
}
}
if (fieldAnnotations) {
map[field.name] = fieldAnnotations
}
}

return map
}
}
11 changes: 11 additions & 0 deletions src/groovy/com/grailsrocks/cacheheaders/NoCaching.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.grailsrocks.cacheheaders

import java.lang.annotation.ElementType
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
import java.lang.annotation.Target

@Retention(RetentionPolicy.RUNTIME)
@Target([ElementType.METHOD, ElementType.TYPE, ElementType.FIELD])
public @interface NoCaching {
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package cacheheaders
package com.grailsrocks.cacheheaders

import java.text.SimpleDateFormat

Expand Down
42 changes: 42 additions & 0 deletions web-app/WEB-INF/applicationContext.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="grailsApplication" class="org.codehaus.groovy.grails.commons.GrailsApplicationFactoryBean">
<description>Grails application factory bean</description>
<property name="grailsDescriptor" value="/WEB-INF/grails.xml" />
<property name="grailsResourceLoader" ref="grailsResourceLoader" />
</bean>

<bean id="pluginManager" class="org.codehaus.groovy.grails.plugins.GrailsPluginManagerFactoryBean">
<description>A bean that manages Grails plugins</description>
<property name="grailsDescriptor" value="/WEB-INF/grails.xml" />
<property name="application" ref="grailsApplication" />
</bean>

<bean id="grailsConfigurator" class="org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator">
<constructor-arg>
<ref bean="grailsApplication" />
</constructor-arg>
<property name="pluginManager" ref="pluginManager" />
</bean>

<bean id="grailsResourceLoader" class="org.codehaus.groovy.grails.commons.GrailsResourceLoaderFactoryBean">
<property name="grailsResourceHolder" ref="grailsResourceHolder" />
</bean>

<bean id="grailsResourceHolder" scope="prototype" class="org.codehaus.groovy.grails.commons.spring.GrailsResourceHolder">
<property name="resources">
<value>classpath*:**/grails-app/**/*.groovy</value>
</property>
</bean>

<bean id="characterEncodingFilter"
class="org.springframework.web.filter.CharacterEncodingFilter">
<property name="encoding">
<value>utf-8</value>
</property>
</bean>
</beans>
14 changes: 14 additions & 0 deletions web-app/WEB-INF/sitemesh.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<sitemesh>
<page-parsers>
<parser content-type="text/html"
class="org.codehaus.groovy.grails.web.sitemesh.GrailsHTMLPageParser" />
<parser content-type="text/html;charset=ISO-8859-1"
class="org.codehaus.groovy.grails.web.sitemesh.GrailsHTMLPageParser" />
<parser content-type="text/html;charset=UTF-8"
class="org.codehaus.groovy.grails.web.sitemesh.GrailsHTMLPageParser" />
</page-parsers>

<decorator-mappers>
<mapper class="org.codehaus.groovy.grails.web.sitemesh.GrailsLayoutDecoratorMapper" />
</decorator-mappers>
</sitemesh>
Loading