private static GroovyObject lookupCachedTagLib( GrailsWebRequest webRequest, TagLibraryLookup gspTagLibraryLookup, String namespace, String tagName) { if (webRequest != null) { // caches the taglibs in request context. is this a good idea or not? String tagKey = namespace + ":" + tagName; Map<String, GroovyObject> tagLibCache = (Map<String, GroovyObject>) webRequest.getCurrentRequest().getAttribute(REQUEST_TAGLIB_CACHE); GroovyObject tagLib = null; if (tagLibCache == null) { tagLibCache = new HashMap<String, GroovyObject>(); webRequest.getCurrentRequest().setAttribute(REQUEST_TAGLIB_CACHE, tagLibCache); } else { tagLib = tagLibCache.get(tagKey); } if (tagLib == null) { tagLib = gspTagLibraryLookup.lookupTagLibrary(namespace, tagName); if (tagLib != null) { tagLibCache.put(tagKey, tagLib); } } return tagLib; } else { return gspTagLibraryLookup != null ? gspTagLibraryLookup.lookupTagLibrary(namespace, tagName) : null; } }
/** * Method missing implementation that handles tag invocation by method name * * @param instance The instance * @param methodName The method name * @param argsObject The arguments * @return The result */ public Object methodMissing(Object instance, String methodName, Object argsObject) { Object[] args = argsObject instanceof Object[] ? (Object[]) argsObject : new Object[] {argsObject}; TagLibraryLookup lookup = getTagLibraryLookup(); if (lookup != null) { GroovyObject tagLibrary = lookup.lookupTagLibrary(GroovyPage.DEFAULT_NAMESPACE, methodName); if (tagLibrary != null) { if (!developmentMode) { MetaClass controllerMc = GrailsMetaClassUtils.getMetaClass(instance); WebMetaUtils.registerMethodMissingForTags( controllerMc, lookup, GroovyPage.DEFAULT_NAMESPACE, methodName); } List<MetaMethod> respondsTo = tagLibrary.getMetaClass().respondsTo(tagLibrary, methodName, args); if (respondsTo.size() > 0) { return respondsTo.get(0).invoke(tagLibrary, args); } } } throw new MissingMethodException(methodName, instance.getClass(), args); }