1717
1818import grails .util .Environment ;
1919
20- import java .util .concurrent .ConcurrentHashMap ;
20+ import org .codehaus .groovy .grails .plugins .support .aware .GrailsApplicationAware ;
21+
22+ import com .googlecode .concurrentlinkedhashmap .ConcurrentLinkedHashMap ;
2123
2224/**
25+ * Lookup controllers for uris.
26+ *
27+ * <p>This class is responsible for looking up controller classes for uris.</p>
28+ *
29+ * <p>Lookups are cached in non-development mode, and the cache size can be controlled using the grails.urlmapping.cache.maxsize config property.</p>
30+ *
2331 * @author Marc Palmer ([email protected] ) 2432*/
25- public class ControllerArtefactHandler extends ArtefactHandlerAdapter {
33+ public class ControllerArtefactHandler extends ArtefactHandlerAdapter implements GrailsApplicationAware {
2634
35+ private static final String URL_MAPPING_CACHE_MAX_SIZE = "grails.urlmapping.cache.maxsize" ;
36+ private static final GrailsClass NO_CONTROLLER = new AbstractGrailsClass (Object .class , "Controller" ) {};
37+
2738 public static final String TYPE = "Controller" ;
2839 public static final String PLUGIN_NAME = "controllers" ;
29- private ConcurrentHashMap <String , GrailsClass > uriToControllerClassCache ;
40+ private ConcurrentLinkedHashMap <String , GrailsClass > uriToControllerClassCache ;
3041 private ArtefactInfo artefactInfo ;
3142
43+ private GrailsApplication grailsApplication ;
44+
3245 public ControllerArtefactHandler () {
3346 super (TYPE , GrailsControllerClass .class , DefaultGrailsControllerClass .class ,
3447 DefaultGrailsControllerClass .CONTROLLER , false );
3548 }
3649
3750 @ Override
3851 public void initialize (ArtefactInfo artefacts ) {
39- uriToControllerClassCache = new ConcurrentHashMap <String , GrailsClass >();
52+ Object cacheSize = grailsApplication .getFlatConfig ().get (URL_MAPPING_CACHE_MAX_SIZE );
53+ if (cacheSize == null ) {
54+ cacheSize = 10000 ;
55+ }
56+
57+ uriToControllerClassCache = new ConcurrentLinkedHashMap .Builder <String , GrailsClass >()
58+ .initialCapacity (500 )
59+ .maximumWeightedCapacity (new Integer (cacheSize .toString ()))
60+ .build ();
61+
4062 artefactInfo = artefacts ;
4163 }
4264
@@ -63,13 +85,23 @@ public GrailsClass getArtefactForFeature(Object feature) {
6385 break ;
6486 }
6587 }
66- if (controllerClass != null ) {
67- // don't cache for dev environment
68- if (Environment .getCurrent () != Environment .DEVELOPMENT ) {
69- uriToControllerClassCache .putIfAbsent (uri , controllerClass );
70- }
88+ if (controllerClass == null ) {
89+ controllerClass = NO_CONTROLLER ;
7190 }
91+
92+ // don't cache for dev environment
93+ if (Environment .getCurrent () != Environment .DEVELOPMENT ) {
94+ uriToControllerClassCache .put (uri , controllerClass );
95+ }
96+ }
97+
98+ if (controllerClass == NO_CONTROLLER ) {
99+ controllerClass = null ;
72100 }
73101 return controllerClass ;
74102 }
103+
104+ public void setGrailsApplication (GrailsApplication grailsApplication ) {
105+ this .grailsApplication = grailsApplication ;
106+ }
75107}
0 commit comments