diff --git a/grails-gsp/core/src/main/groovy/org/apache/grails/gsp/aot/PrecompiledPageRuntimeHints.java b/grails-gsp/core/src/main/groovy/org/apache/grails/gsp/aot/PrecompiledPageRuntimeHints.groovy similarity index 69% rename from grails-gsp/core/src/main/groovy/org/apache/grails/gsp/aot/PrecompiledPageRuntimeHints.java rename to grails-gsp/core/src/main/groovy/org/apache/grails/gsp/aot/PrecompiledPageRuntimeHints.groovy index 857ab6478af..4ee67435e7e 100644 --- a/grails-gsp/core/src/main/groovy/org/apache/grails/gsp/aot/PrecompiledPageRuntimeHints.java +++ b/grails-gsp/core/src/main/groovy/org/apache/grails/gsp/aot/PrecompiledPageRuntimeHints.groovy @@ -16,14 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.grails.gsp.aot; +package org.apache.grails.gsp.aot -import org.jspecify.annotations.Nullable; +import groovy.transform.CompileStatic +import org.jspecify.annotations.Nullable +import org.springframework.aot.hint.RuntimeHints +import org.springframework.aot.hint.RuntimeHintsRegistrar -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.RuntimeHintsRegistrar; - -import org.grails.gsp.GroovyPageMetaInfo; +import org.grails.gsp.GroovyPageMetaInfo /** * Registers what a page compiled at build time is read from. @@ -38,15 +38,17 @@ * * @since 8.0 */ -public class PrecompiledPageRuntimeHints implements RuntimeHintsRegistrar { +@CompileStatic +class PrecompiledPageRuntimeHints implements RuntimeHintsRegistrar { /** Where the pages compiled at build time are listed, read to find them at all. */ - private static final String VIEWS = "gsp/views.properties"; + private static final String VIEWS = 'gsp/views.properties' @Override - public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { - hints.resources().registerPattern(VIEWS); - hints.resources().registerPattern("*" + GroovyPageMetaInfo.HTML_DATA_POSTFIX); - hints.resources().registerPattern("*" + GroovyPageMetaInfo.LINENUMBERS_DATA_POSTFIX); + void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { + hints.resources().registerPattern(VIEWS) + hints.resources().registerPattern('*' + GroovyPageMetaInfo.HTML_DATA_POSTFIX) + hints.resources().registerPattern('*' + GroovyPageMetaInfo.LINENUMBERS_DATA_POSTFIX) } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPage.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPage.groovy similarity index 53% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPage.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPage.groovy index db19c7a9928..f3e3f07caad 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPage.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPage.groovy @@ -16,50 +16,37 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp; - -import java.io.Writer; -import java.lang.reflect.Field; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import groovy.lang.Binding; -import groovy.lang.Closure; -import groovy.lang.GroovyObject; -import groovy.lang.MissingMethodException; -import groovy.lang.Script; -import org.codehaus.groovy.runtime.InvokerHelper; -import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import grails.core.GrailsApplication; -import grails.util.CollectionUtils; -import org.grails.buffer.GrailsPrintWriter; -import org.grails.encoder.Encoder; -import org.grails.exceptions.ExceptionUtils; -import org.grails.gsp.jsp.JspTag; -import org.grails.gsp.jsp.JspTagLib; -import org.grails.gsp.jsp.TagLibraryResolver; -import org.grails.taglib.AbstractTemplateVariableBinding; -import org.grails.taglib.GrailsTagException; -import org.grails.taglib.GroovyPageAttributes; -import org.grails.taglib.TagBodyClosure; -import org.grails.taglib.TagLibraryLookup; -import org.grails.taglib.TagLibraryMetaUtils; -import org.grails.taglib.TagMethodContext; -import org.grails.taglib.TagMethodInvoker; -import org.grails.taglib.TagOutput; -import org.grails.taglib.encoder.OutputContext; -import org.grails.taglib.encoder.OutputEncodingStack; -import org.grails.taglib.encoder.OutputEncodingStackAttributes; -import org.grails.taglib.encoder.WithCodecHelper; +package org.grails.gsp + +import java.lang.reflect.Field + +import groovy.transform.CompileStatic +import org.apache.commons.logging.Log +import org.apache.commons.logging.LogFactory +import org.codehaus.groovy.runtime.InvokerHelper +import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation + +import grails.core.GrailsApplication +import grails.util.CollectionUtils +import org.grails.buffer.GrailsPrintWriter +import org.grails.encoder.Encoder +import org.grails.exceptions.ExceptionUtils +import org.grails.gsp.jsp.JspTag +import org.grails.gsp.jsp.JspTagLib +import org.grails.gsp.jsp.TagLibraryResolver +import org.grails.taglib.AbstractTemplateVariableBinding +import org.grails.taglib.GrailsTagException +import org.grails.taglib.GroovyPageAttributes +import org.grails.taglib.TagBodyClosure +import org.grails.taglib.TagLibraryLookup +import org.grails.taglib.TagLibraryMetaUtils +import org.grails.taglib.TagMethodContext +import org.grails.taglib.TagMethodInvoker +import org.grails.taglib.TagOutput +import org.grails.taglib.encoder.OutputContext +import org.grails.taglib.encoder.OutputEncodingStack +import org.grails.taglib.encoder.OutputEncodingStackAttributes +import org.grails.taglib.encoder.WithCodecHelper /** *

NOTE: Based on work done by on the GSP standalone project (https://gsp.dev.java.net/) @@ -71,137 +58,140 @@ * @author Graeme Rocher * @author Lari Hotari */ -public abstract class GroovyPage extends Script { - private static final String APPLY_CODEC_TAG_NAME = "applyCodec"; - public static final String ENCODE_AS_ATTRIBUTE_NAME = "encodeAs"; - public static final Closure EMPTY_BODY_CLOSURE = TagOutput.EMPTY_BODY_CLOSURE; - - private static final Log LOG = LogFactory.getLog(GroovyPage.class); - - public static final String OUT = "out"; - public static final String EXPRESSION_OUT = "expressionOut"; - public static final String EXPRESSION_OUT_STATEMENT = EXPRESSION_OUT; // "getCodecOut()"; - public static final String OUT_STATEMENT = OUT; // "getOut()"; - public static final String CODEC_VARNAME = "Codec"; - public static final String PLUGIN_CONTEXT_PATH = "pluginContextPath"; - public static final String EXTENSION = ".gsp"; - public static final String DEFAULT_NAMESPACE = "g"; - public static final String LINK_NAMESPACE = "link"; - public static final String TEMPLATE_NAMESPACE = "tmpl"; - public static final String PAGE_SCOPE = "pageScope"; - private OutputEncodingStackAttributes.Builder attributesBuilder; +@CompileStatic +abstract class GroovyPage extends Script { + + private static final String APPLY_CODEC_TAG_NAME = 'applyCodec' + public static final String ENCODE_AS_ATTRIBUTE_NAME = 'encodeAs' + public static final Closure EMPTY_BODY_CLOSURE = TagOutput.EMPTY_BODY_CLOSURE + + private static final Log LOG = LogFactory.getLog(GroovyPage) + + public static final String OUT = 'out' + public static final String EXPRESSION_OUT = 'expressionOut' + public static final String EXPRESSION_OUT_STATEMENT = EXPRESSION_OUT // "getCodecOut()"; + public static final String OUT_STATEMENT = OUT // "getOut()"; + public static final String CODEC_VARNAME = 'Codec' + public static final String PLUGIN_CONTEXT_PATH = 'pluginContextPath' + public static final String EXTENSION = '.gsp' + public static final String DEFAULT_NAMESPACE = 'g' + public static final String LINK_NAMESPACE = 'link' + public static final String TEMPLATE_NAMESPACE = 'tmpl' + public static final String PAGE_SCOPE = 'pageScope' + private OutputEncodingStackAttributes.Builder attributesBuilder public static final Collection RESERVED_NAMES = CollectionUtils.newSet( OUT, EXPRESSION_OUT, CODEC_VARNAME, PLUGIN_CONTEXT_PATH, - PAGE_SCOPE); - - private static final String BINDING = "binding"; - private static final String BLANK_STRING = ""; - @SuppressWarnings("rawtypes") - private Map jspTags = Collections.emptyMap(); - private TagLibraryResolver jspTagLibraryResolver; - protected TagLibraryLookup gspTagLibraryLookup; - private String[] htmlParts; - private Set htmlPartsSet; - private GrailsPrintWriter out; - private GrailsPrintWriter staticOut; - private GrailsPrintWriter expressionOut; - private OutputEncodingStack outputStack; - protected OutputContext outputContext; - private String pluginContextPath; - private Encoder rawEncoder; - - private final List> bodyClosures = new ArrayList<>(15); - - public GroovyPage() { - init(); + PAGE_SCOPE) + + private static final String BINDING = 'binding' + private static final String BLANK_STRING = '' + + @SuppressWarnings('rawtypes') + private Map jspTags = Collections.emptyMap() + private TagLibraryResolver jspTagLibraryResolver + protected TagLibraryLookup gspTagLibraryLookup + private String[] htmlParts + private Set htmlPartsSet + private GrailsPrintWriter out + private GrailsPrintWriter staticOut + private GrailsPrintWriter expressionOut + private OutputEncodingStack outputStack + protected OutputContext outputContext + private String pluginContextPath + private Encoder rawEncoder + + private final List> bodyClosures = new ArrayList<>(15) + + GroovyPage() { + init() } protected void init() { // do nothing } - public final Writer getOut() { - return out; + final Writer getOut() { + return out } - public final Writer getExpressionOut() { - return expressionOut; + final Writer getExpressionOut() { + return expressionOut } - public void setOut(Writer newWriter) { - throw new IllegalStateException("Setting out in page isn't allowed."); + void setOut(Writer newWriter) { + throw new IllegalStateException("Setting out in page isn't allowed.") } - public void initCommonRun(GroovyPageMetaInfo metaInfo) { - attributesBuilder = new OutputEncodingStackAttributes.Builder(); + void initCommonRun(GroovyPageMetaInfo metaInfo) { + attributesBuilder = new OutputEncodingStackAttributes.Builder() if (metaInfo != null) { - attributesBuilder.outEncoder(metaInfo.getOutEncoder()); - attributesBuilder.staticEncoder(metaInfo.getStaticEncoder()); - attributesBuilder.expressionEncoder(metaInfo.getExpressionEncoder()); - attributesBuilder.defaultTaglibEncoder(metaInfo.getTaglibEncoder()); - setHtmlParts(metaInfo.getHtmlParts()); - setHtmlPartsSet(metaInfo.getHtmlPartsSet()); - setJspTags(metaInfo.getJspTags()); - setJspTagLibraryResolver(metaInfo.getJspTagLibraryResolver()); - setGspTagLibraryLookup(metaInfo.getTagLibraryLookup()); - setPluginContextPath(metaInfo.getPluginPath()); + attributesBuilder.outEncoder(metaInfo.getOutEncoder()) + attributesBuilder.staticEncoder(metaInfo.getStaticEncoder()) + attributesBuilder.expressionEncoder(metaInfo.getExpressionEncoder()) + attributesBuilder.defaultTaglibEncoder(metaInfo.getTaglibEncoder()) + setHtmlParts(metaInfo.getHtmlParts()) + setHtmlPartsSet(metaInfo.getHtmlPartsSet()) + setJspTags(metaInfo.getJspTags()) + setJspTagLibraryResolver(metaInfo.getJspTagLibraryResolver()) + setGspTagLibraryLookup(metaInfo.getTagLibraryLookup()) + setPluginContextPath(metaInfo.getPluginPath()) } - attributesBuilder.allowCreate(true).autoSync(false).pushTop(true); - attributesBuilder.inheritPreviousEncoders(false); + attributesBuilder.allowCreate(true).autoSync(false).pushTop(true) + attributesBuilder.inheritPreviousEncoders(false) } - public void initRun(Writer target, OutputContext outputContext, GroovyPageMetaInfo metaInfo) { + void initRun(Writer target, OutputContext outputContext, GroovyPageMetaInfo metaInfo) { if (metaInfo != null) { - applyModelFieldsFromBinding(metaInfo.getModelFields()); + applyModelFieldsFromBinding(metaInfo.getModelFields()) } - attributesBuilder.outputContext(outputContext); - attributesBuilder.topWriter(target); - outputStack = OutputEncodingStack.currentStack(attributesBuilder.build()); + attributesBuilder.outputContext(outputContext) + attributesBuilder.topWriter(target) + outputStack = OutputEncodingStack.currentStack(attributesBuilder.build()) - out = outputStack.getOutWriter(); - staticOut = outputStack.getStaticWriter(); - expressionOut = outputStack.getExpressionWriter(); + out = outputStack.getOutWriter() + staticOut = outputStack.getStaticWriter() + expressionOut = outputStack.getExpressionWriter() - this.outputContext = outputContext; + this.outputContext = outputContext if (outputContext != null) { - outputContext.setCurrentWriter(out); - GrailsApplication grailsApplication = outputContext.getGrailsApplication(); + outputContext.setCurrentWriter(out) + GrailsApplication grailsApplication = outputContext.getGrailsApplication() if (grailsApplication != null) { - rawEncoder = WithCodecHelper.lookupEncoder(grailsApplication, "Raw"); + rawEncoder = WithCodecHelper.lookupEncoder(grailsApplication, 'Raw') } } - setVariableDirectly(OUT, out); - setVariableDirectly(EXPRESSION_OUT, expressionOut); + setVariableDirectly(OUT, out) + setVariableDirectly(EXPRESSION_OUT, expressionOut) } private void applyModelFieldsFromBinding(Iterable modelFields) { - for (Field field : modelFields) { - Object value = getProperty(field.getName()); + for (Field field in modelFields) { + Object value = getProperty(field.getName()) if (value == null) { - continue; + continue } - Object converted; + Object converted try { - converted = DefaultTypeTransformation.castToType(value, field.getType()); + converted = DefaultTypeTransformation.castToType(value, field.getType()) } catch (RuntimeException e) { - throw new GroovyPagesException("Model field '" + field.getName() + "' is declared as " + - field.getType().getName() + " but the model supplied an instance of " + - value.getClass().getName() + ", which cannot be converted to it.", e, -1, getGroovyPageFileName()); + throw new GroovyPagesException("Model field '${field.getName()}' is declared as " + + "${field.getType().getName()} but the model supplied an instance of " + + "${value.getClass().getName()}, which cannot be converted to it.", e, -1, getGroovyPageFileName()) } if (value instanceof Number && converted instanceof Number && !sameNumericValue((Number) value, (Number) converted)) { - throw new GroovyPagesException("Model field '" + field.getName() + "' is declared as " + - field.getType().getName() + ", which cannot hold the " + value.getClass().getName() + " " + - value + " the model supplied without changing it.", null, -1, getGroovyPageFileName()); + throw new GroovyPagesException("Model field '${field.getName()}' is declared as " + + "${field.getType().getName()}, which cannot hold the ${value.getClass().getName()} " + + "${value} the model supplied without changing it.", null, -1, getGroovyPageFileName()) } try { - field.set(this, converted); + field.set(this, converted) } catch (IllegalAccessException e) { - throw new GroovyPagesException("Error setting model field '" + field.getName() + "'", e, -1, getGroovyPageFileName()); + throw new GroovyPagesException("Error setting model field '" + field.getName() + "'", e, -1, getGroovyPageFileName()) } } } @@ -209,7 +199,7 @@ private void applyModelFieldsFromBinding(Iterable modelFields) { private static boolean sameNumericValue(Number original, Number converted) { if (isFloatingPoint(original) && isFloatingPoint(converted)) { // Every float is exactly representable as a double, including NaN and infinities. - return Double.compare(original.doubleValue(), converted.doubleValue()) == 0; + return Double.compare(original.doubleValue(), converted.doubleValue()) == 0 } // A floating-point value prints as the shortest decimal that reads back to it, which is // also the decimal Groovy converts it to, so comparing the decimal forms accepts exactly @@ -217,64 +207,64 @@ private static boolean sameNumericValue(Number original, Number converted) { // BigDecimal. A decimal with more digits than the type can carry prints differently // once converted and is rejected. try { - return new BigDecimal(original.toString()).compareTo(new BigDecimal(converted.toString())) == 0; - } catch (NumberFormatException e) { + return new BigDecimal(original.toString()).compareTo(new BigDecimal(converted.toString())) == 0 + } catch (NumberFormatException ignored) { // A non-finite floating-point value cannot equal a finite decimal or integer. - return false; + return false } } private static boolean isFloatingPoint(Number number) { - return number instanceof Float || number instanceof Double; + return number instanceof Float || number instanceof Double } - public Object raw(Object value) { + Object raw(Object value) { if (rawEncoder == null) { - return InvokerHelper.invokeMethod(value, "encodeAsRaw", null); + return InvokerHelper.invokeMethod(value, 'encodeAsRaw', null) } - return rawEncoder.encode(value); + return rawEncoder.encode(value) } - @SuppressWarnings("unchecked") + @SuppressWarnings('unchecked') private void setVariableDirectly(String name, Object value) { - Binding binding = getBinding(); + Binding binding = getBinding() if (binding instanceof AbstractTemplateVariableBinding) { - ((AbstractTemplateVariableBinding) binding).setVariableDirectly(name, value); + ((AbstractTemplateVariableBinding) binding).setVariableDirectly(name, value) } else { - binding.getVariables().put(name, value); + binding.getVariables().put(name, value) } } - public String getPluginContextPath() { - return pluginContextPath != null ? pluginContextPath : BLANK_STRING; + String getPluginContextPath() { + return pluginContextPath != null ? pluginContextPath : BLANK_STRING } - public void setPluginContextPath(String pluginContextPath) { - this.pluginContextPath = pluginContextPath; + void setPluginContextPath(String pluginContextPath) { + this.pluginContextPath = pluginContextPath } - public void cleanup() { - outputStack.pop(true); + void cleanup() { + outputStack.pop(true) } - public final void createClosureForHtmlPart(int partNumber, int bodyClosureIndex) { - final String htmlPart = htmlParts[partNumber]; - setBodyClosure(bodyClosureIndex, new TagOutput.ConstantClosure(htmlPart)); + final void createClosureForHtmlPart(int partNumber, int bodyClosureIndex) { + final String htmlPart = htmlParts[partNumber] + setBodyClosure(bodyClosureIndex, new TagOutput.ConstantClosure(htmlPart)) } - public final void setBodyClosure(int index, Closure bodyClosure) { + final void setBodyClosure(int index, Closure bodyClosure) { while (index >= bodyClosures.size()) { - bodyClosures.add(null); + bodyClosures.add(null) } - bodyClosures.set(index, bodyClosure); + bodyClosures.set(index, bodyClosure) } - public final Closure getBodyClosure(int index) { + final Closure getBodyClosure(int index) { if (index >= 0) { - return bodyClosures.get(index); + return bodyClosures.get(index) } - return null; + return null } /** @@ -282,8 +272,8 @@ public final Closure getBodyClosure(int index) { * * @param jspTagLibraryResolver The JSP tag resolve */ - public void setJspTagLibraryResolver(TagLibraryResolver jspTagLibraryResolver) { - this.jspTagLibraryResolver = jspTagLibraryResolver; + void setJspTagLibraryResolver(TagLibraryResolver jspTagLibraryResolver) { + this.jspTagLibraryResolver = jspTagLibraryResolver } /** @@ -291,8 +281,8 @@ public void setJspTagLibraryResolver(TagLibraryResolver jspTagLibraryResolver) { * * @param gspTagLibraryLookup The class used to lookup a GSP tag library */ - public void setGspTagLibraryLookup(TagLibraryLookup gspTagLibraryLookup) { - this.gspTagLibraryLookup = gspTagLibraryLookup; + void setGspTagLibraryLookup(TagLibraryLookup gspTagLibraryLookup) { + this.gspTagLibraryLookup = gspTagLibraryLookup } /** @@ -304,8 +294,8 @@ public void setGspTagLibraryLookup(TagLibraryLookup gspTagLibraryLookup) { * @return the lookup, or {@code null} before the page has been initialised * @since 8.0.0 */ - public TagLibraryLookup getTagLibraryLookup() { - return this.gspTagLibraryLookup; + TagLibraryLookup getTagLibraryLookup() { + return this.gspTagLibraryLookup } /** @@ -314,7 +304,7 @@ public TagLibraryLookup getTagLibraryLookup() { * @return The JSP TagLibraryResolver instance */ TagLibraryResolver getTagLibraryResolver() { - return jspTagLibraryResolver; + return jspTagLibraryResolver } /** @@ -326,27 +316,27 @@ TagLibraryResolver getTagLibraryResolver() { * @param evaluator The expression evaluator * @return The result */ - public Object evaluate(String exprText, int lineNumber, Object outerIt, Closure evaluator) { + Object evaluate(String exprText, int lineNumber, Object outerIt, Closure evaluator) { try { - return evaluator.call(outerIt); + return evaluator.call(outerIt) } catch (Exception e) { - throw new GroovyPagesException("Error evaluating expression [" + exprText + "] on line [" + - lineNumber + "]: " + e.getMessage(), e, lineNumber, getGroovyPageFileName()); + throw new GroovyPagesException('Error evaluating expression [' + exprText + '] on line [' + + lineNumber + ']: ' + e.getMessage(), e, lineNumber, getGroovyPageFileName()) } } - public abstract String getGroovyPageFileName(); + abstract String getGroovyPageFileName() @Override - public Object getProperty(String property) { - if (OUT.equals(property)) return out; - if (EXPRESSION_OUT.equals(property)) return expressionOut; + Object getProperty(String property) { + if (OUT.equals(property)) return out + if (EXPRESSION_OUT.equals(property)) return expressionOut // in GSP we assume if a property doesn't exist that // it is null rather than throw an error this works nicely // with the Groovy Truth - if (BINDING.equals(property)) return getBinding(); + if (BINDING.equals(property)) return getBinding() - return resolveProperty(property); + return resolveProperty(property) } /** @@ -362,56 +352,56 @@ public Object getProperty(String property) { * @return whatever the tag produces * @throws MissingMethodException when there is no tag library lookup to resolve the name against */ - public Object methodMissing(String name, Object args) { + Object methodMissing(String name, Object args) { if (gspTagLibraryLookup == null) { // Without a lookup there is nothing to resolve the name against, which is a missing // method. Dispatching anyway arrives at the same answer, but only because a dynamic call // on a null receiver happens to yield no tag library rather than because anything says // so; this states the contract for a field documented as null before initialisation. - throw new MissingMethodException(name, getClass(), makeArgumentArray(args)); + throw new MissingMethodException(name, getClass(), makeArgumentArray(args)) } return TagLibraryMetaUtils.methodMissingForTagLib(getMetaClass(), getClass(), gspTagLibraryLookup, - DEFAULT_NAMESPACE, name, args, false); + DEFAULT_NAMESPACE, name, args, false) } private static Object[] makeArgumentArray(Object args) { if (args == null) { - return new Object[0]; + return new Object[0] } - return args instanceof Object[] ? (Object[]) args : new Object[] { args }; + return args instanceof Object[] ? (Object[]) args : [args] as Object[] } protected Object resolveProperty(String property) { - Object value = getBinding().getVariable(property); + Object value = getBinding().getVariable(property) if (value != null) { - return value; + return value } // check if a taglib can be found - value = lookupTagDispatcher(property); + value = lookupTagDispatcher(property) if (value == null) { - value = lookupJspTagLib(property); + value = lookupJspTagLib(property) } if (value != null) { // cache lookup for next execution - setVariableDirectly(property, value); + setVariableDirectly(property, value) } - return value; + return value } protected Object lookupTagDispatcher(String namespace) { - return gspTagLibraryLookup != null ? gspTagLibraryLookup.lookupNamespaceDispatcher(namespace) : null; + return gspTagLibraryLookup != null ? gspTagLibraryLookup.lookupNamespaceDispatcher(namespace) : null } protected JspTagLib lookupJspTagLib(String jspTagLibName) { - String uri = (String) jspTags.get(jspTagLibName); + String uri = (String) jspTags.get(jspTagLibName) if (uri != null) { - TagLibraryResolver tagResolver = getTagLibraryResolver(); - return tagResolver.resolveTagLibrary(uri); + TagLibraryResolver tagResolver = getTagLibraryResolver() + return tagResolver.resolveTagLibrary(uri) } - return null; + return null } /* Static call for jsp tags resolution @@ -420,13 +410,13 @@ protected JspTagLib lookupJspTagLib(String jspTagLibName) { * @param name tag name * @return resolved tag if any */ - public JspTag getJspTag(String uri, String name) { + JspTag getJspTag(String uri, String name) { if (jspTagLibraryResolver == null) { - return null; + return null } - JspTagLib tagLib = jspTagLibraryResolver.resolveTagLibrary(uri); - return tagLib != null ? tagLib.getTag(name) : null; + JspTagLib tagLib = jspTagLibraryResolver.resolveTagLibrary(uri) + return tagLib != null ? tagLib.getTag(name) : null } /** @@ -438,179 +428,179 @@ public JspTag getJspTag(String uri, String name) { * @param attrs The tags attributes * @param bodyClosureIndex The index of the body variable */ - @SuppressWarnings({"unchecked", "rawtypes"}) - public final void invokeTag(String tagName, String tagNamespace, int lineNumber, Map attrs, int bodyClosureIndex) { - Closure body = getBodyClosure(bodyClosureIndex); + @SuppressWarnings(['unchecked', 'rawtypes']) + final void invokeTag(String tagName, String tagNamespace, int lineNumber, Map attrs, int bodyClosureIndex) { + Closure body = getBodyClosure(bodyClosureIndex) // TODO custom namespace stuff needs to be generalized and pluggable if (tagNamespace.equals(TEMPLATE_NAMESPACE) || tagNamespace.equals(LINK_NAMESPACE)) { - final String tmpTagName = tagName; - final Map tmpAttrs = attrs; - Object encodeAs = tmpAttrs.remove(ENCODE_AS_ATTRIBUTE_NAME); + final String tmpTagName = tagName + final Map tmpAttrs = attrs + Object encodeAs = tmpAttrs.remove(ENCODE_AS_ATTRIBUTE_NAME) if (tagNamespace.equals(TEMPLATE_NAMESPACE)) { - tagName = "render"; - attrs = CollectionUtils.newMap("model", tmpAttrs, "template", tmpTagName); + tagName = 'render' + attrs = CollectionUtils.newMap('model', tmpAttrs, 'template', tmpTagName) } else if (tagNamespace.equals(LINK_NAMESPACE)) { - tagName = "link"; - attrs = CollectionUtils.newMap("mapping", tmpTagName); + tagName = 'link' + attrs = CollectionUtils.newMap('mapping', tmpTagName) if (!tmpAttrs.isEmpty()) { - attrs.put("params", tmpAttrs); + attrs.put('params', tmpAttrs) } } if (encodeAs != null) { - attrs.put(ENCODE_AS_ATTRIBUTE_NAME, encodeAs); + attrs.put(ENCODE_AS_ATTRIBUTE_NAME, encodeAs) } - tagNamespace = DEFAULT_NAMESPACE; + tagNamespace = DEFAULT_NAMESPACE } try { - GroovyObject tagLib = getTagLib(tagNamespace, tagName); + GroovyObject tagLib = getTagLib(tagNamespace, tagName) if (tagLib != null || (gspTagLibraryLookup != null && gspTagLibraryLookup.hasNamespace(tagNamespace))) { if (tagLib != null) { - boolean returnsObject = gspTagLibraryLookup.doesTagReturnObject(tagNamespace, tagName); - Object tagLibClosure = TagMethodInvoker.getClosureTagProperty(tagLib, tagName); + boolean returnsObject = gspTagLibraryLookup.doesTagReturnObject(tagNamespace, tagName) + Object tagLibClosure = TagMethodInvoker.getClosureTagProperty(tagLib, tagName) if (tagLibClosure instanceof Closure) { - Map encodeAsForTag = gspTagLibraryLookup.getEncodeAsForTag(tagNamespace, tagName); - invokeTagLibClosure(tagName, tagNamespace, (Closure) tagLibClosure, attrs, body, returnsObject, encodeAsForTag); + Map encodeAsForTag = gspTagLibraryLookup.getEncodeAsForTag(tagNamespace, tagName) + invokeTagLibClosure(tagName, tagNamespace, (Closure) tagLibClosure, attrs, body, returnsObject, encodeAsForTag) } else if (TagMethodInvoker.hasInvokableTagMethod(tagLib, tagName)) { - Map encodeAsForTag = gspTagLibraryLookup.getEncodeAsForTag(tagNamespace, tagName); - invokeTagLibMethod(tagName, tagNamespace, tagLib, attrs, body, returnsObject, encodeAsForTag); + Map encodeAsForTag = gspTagLibraryLookup.getEncodeAsForTag(tagNamespace, tagName) + invokeTagLibMethod(tagName, tagNamespace, tagLib, attrs, body, returnsObject, encodeAsForTag) } else { - throw new GrailsTagException("Tag [" + tagName + "] does not exist in tag library [" + tagLib.getClass().getName() + "]", getGroovyPageFileName(), lineNumber); + throw new GrailsTagException('Tag [' + tagName + '] does not exist in tag library [' + tagLib.getClass().getName() + ']', getGroovyPageFileName(), lineNumber) } } else { - throw new GrailsTagException("Tag [" + tagName + "] does not exist. No tag library found for namespace: " + tagNamespace, getGroovyPageFileName(), lineNumber); + throw new GrailsTagException('Tag [' + tagName + '] does not exist. No tag library found for namespace: ' + tagNamespace, getGroovyPageFileName(), lineNumber) } } else { - staticOut.append('<').append(tagNamespace).append(':').append(tagName); - for (Object o : attrs.entrySet()) { - Map.Entry entry = (Map.Entry) o; - staticOut.append(' '); - staticOut.append(entry.getKey()).append('='); - String value = String.valueOf(entry.getValue()); + staticOut.append('<').append(tagNamespace).append(':').append(tagName) + for (Object o in attrs.entrySet()) { + Map.Entry entry = (Map.Entry) o + staticOut.append(' ') + staticOut.append(entry.getKey()).append('=') + String value = String.valueOf(entry.getValue()) // handle attribute value quotes & possible escaping " -> " - boolean containsQuotes = (value.indexOf('"') > -1); - boolean containsSingleQuote = (value.indexOf('\'') > -1); + boolean containsQuotes = (value.indexOf('"') > -1) + boolean containsSingleQuote = (value.indexOf('\'') > -1) if (containsQuotes && !containsSingleQuote) { - staticOut.append('\'').append(value).append('\''); + staticOut.append('\'').append(value).append('\'') } else if (containsQuotes & containsSingleQuote) { - staticOut.append('\"').append(value.replaceAll("\"", """)).append('\"'); + staticOut.append('"').append(value.replaceAll('"', '"')).append('"') } else { - staticOut.append('\"').append(value).append('\"'); + staticOut.append('\"').append(value).append('\"') } } if (body == null) { - staticOut.append("/>"); + staticOut.append('/>') } else { - staticOut.append('>'); - Object bodyOutput = body.call(); - if (bodyOutput != null) staticOut.print(bodyOutput); - staticOut.append("'); + staticOut.append('>') + Object bodyOutput = ((Closure) body).call() + if (bodyOutput != null) staticOut.print(bodyOutput) + staticOut.append('') } } } catch (Throwable e) { if (LOG.isTraceEnabled()) { - LOG.trace("Full exception for problem at " + getGroovyPageFileName() + ":" + lineNumber, e); + LOG.trace('Full exception for problem at ' + getGroovyPageFileName() + ':' + lineNumber, e) } // The capture* tags are internal tags and not to be displayed to the user // hence we don't wrap the exception and simple rethrow it - if (tagName.matches("capture(Body|Head|Meta|Title|Component)")) { - RuntimeException rte = ExceptionUtils.getFirstRuntimeException(e); + if (tagName.matches('capture(Body|Head|Meta|Title|Component)')) { + RuntimeException rte = ExceptionUtils.getFirstRuntimeException(e) if (rte == null) { - throwRootCause(tagName, tagNamespace, lineNumber, e); + throwRootCause(tagName, tagNamespace, lineNumber, e) } else { - throw rte; + throw rte } } else { - throwRootCause(tagName, tagNamespace, lineNumber, e); + throwRootCause(tagName, tagNamespace, lineNumber, e) } } } private void invokeTagLibClosure(String tagName, String tagNamespace, Closure tagLibClosure, Map attrs, Closure body, boolean returnsObject, Map defaultEncodeAs) { - Closure tag = (Closure) tagLibClosure.clone(); + Closure tag = (Closure) tagLibClosure.clone() if (!(attrs instanceof GroovyPageAttributes)) { - attrs = new GroovyPageAttributes(attrs); + attrs = new GroovyPageAttributes(attrs) } - ((GroovyPageAttributes) attrs).setGspTagSyntaxCall(true); + ((GroovyPageAttributes) attrs).setGspTagSyntaxCall(true) - boolean encodeAsPushedToStack = false; + boolean encodeAsPushedToStack = false try { - Map codecSettings = TagOutput.createCodecSettings(tagNamespace, tagName, attrs, defaultEncodeAs); + Map codecSettings = TagOutput.createCodecSettings(tagNamespace, tagName, attrs, defaultEncodeAs) if (codecSettings != null) { - outputStack.push(WithCodecHelper.createOutputStackAttributesBuilder(codecSettings, outputContext.getGrailsApplication()).build()); - encodeAsPushedToStack = true; + outputStack.push(WithCodecHelper.createOutputStackAttributesBuilder(codecSettings, outputContext.getGrailsApplication()).build()) + encodeAsPushedToStack = true } - Object tagresult = null; + Object tagresult = null switch (tag.getParameterTypes().length) { case 1: - tagresult = tag.call(new Object[]{attrs}); - outputTagResult(returnsObject, tagresult); + tagresult = tag.call(attrs) + outputTagResult(returnsObject, tagresult) if (body != null && body != TagOutput.EMPTY_BODY_CLOSURE) { - body.call(); + body.call() } - break; + break case 2: - tagresult = tag.call(new Object[]{attrs, (body != null) ? body : TagOutput.EMPTY_BODY_CLOSURE}); - outputTagResult(returnsObject, tagresult); - break; + tagresult = tag.call(attrs, (body != null) ? body : TagOutput.EMPTY_BODY_CLOSURE) + outputTagResult(returnsObject, tagresult) + break } } finally { - if (encodeAsPushedToStack) outputStack.pop(); + if (encodeAsPushedToStack) outputStack.pop() } } private void invokeTagLibMethod(String tagName, String tagNamespace, GroovyObject tagLib, Map attrs, Closure body, boolean returnsObject, Map defaultEncodeAs) { if (!(attrs instanceof GroovyPageAttributes)) { - attrs = new GroovyPageAttributes(attrs); + attrs = new GroovyPageAttributes(attrs) } - ((GroovyPageAttributes) attrs).setGspTagSyntaxCall(true); - boolean encodeAsPushedToStack = false; + ((GroovyPageAttributes) attrs).setGspTagSyntaxCall(true) + boolean encodeAsPushedToStack = false try { - Map codecSettings = TagOutput.createCodecSettings(tagNamespace, tagName, attrs, defaultEncodeAs); + Map codecSettings = TagOutput.createCodecSettings(tagNamespace, tagName, attrs, defaultEncodeAs) if (codecSettings != null) { - outputStack.push(WithCodecHelper.createOutputStackAttributesBuilder(codecSettings, outputContext.getGrailsApplication()).build()); - encodeAsPushedToStack = true; + outputStack.push(WithCodecHelper.createOutputStackAttributesBuilder(codecSettings, outputContext.getGrailsApplication()).build()) + encodeAsPushedToStack = true } - Closure actualBody = body != null ? body : TagOutput.EMPTY_BODY_CLOSURE; - TagMethodContext.push(attrs, actualBody); - Object tagResult = TagMethodInvoker.invokeTagMethod(tagLib, tagName, attrs, actualBody); - outputTagResult(returnsObject, tagResult); + Closure actualBody = body != null ? body : TagOutput.EMPTY_BODY_CLOSURE + TagMethodContext.push(attrs, actualBody) + Object tagResult = TagMethodInvoker.invokeTagMethod(tagLib, tagName, attrs, actualBody) + outputTagResult(returnsObject, tagResult) } finally { - TagMethodContext.pop(); - if (encodeAsPushedToStack) outputStack.pop(); + TagMethodContext.pop() + if (encodeAsPushedToStack) outputStack.pop() } } private void outputTagResult(boolean returnsObject, Object tagresult) { if (returnsObject && tagresult != null && !(tagresult instanceof Writer)) { if (tagresult instanceof String && isHtmlPart((String) tagresult)) { - staticOut.print(tagresult); + staticOut.print(tagresult) } else { - outputStack.getTaglibWriter().print(tagresult); + outputStack.getTaglibWriter().print(tagresult) } } } private void throwRootCause(String tagName, String tagNamespace, int lineNumber, Throwable e) { - Throwable cause = ExceptionUtils.getRootCause(e); + Throwable cause = ExceptionUtils.getRootCause(e) if (cause instanceof GrailsTagException) { // catch and rethrow with context - throw new GrailsTagException(cause.getMessage(), getGroovyPageFileName(), lineNumber); + throw new GrailsTagException(cause.getMessage(), getGroovyPageFileName(), lineNumber) } - throw new GrailsTagException("Error executing tag <" + tagNamespace + ":" + tagName + - ">: " + e.getMessage(), e, getGroovyPageFileName(), lineNumber); + throw new GrailsTagException('Error executing tag <' + tagNamespace + ':' + tagName + + '>: ' + e.getMessage(), e, getGroovyPageFileName(), lineNumber) } private GroovyObject getTagLib(String namespace, String tagName) { - return TagOutput.lookupCachedTagLib(gspTagLibraryLookup, namespace, tagName); + return TagOutput.lookupCachedTagLib(gspTagLibraryLookup, namespace, tagName) } /** @@ -619,20 +609,20 @@ private GroovyObject getTagLib(String namespace, String tagName) { * @param name True if it can't * @return A boolean true or false */ - public final static boolean isReservedName(String name) { - return RESERVED_NAMES.contains(name); + static final boolean isReservedName(String name) { + return RESERVED_NAMES.contains(name) } - public final void printHtmlPart(final int partNumber) { - staticOut.write(htmlParts[partNumber]); + final void printHtmlPart(final int partNumber) { + staticOut.write(htmlParts[partNumber]) } /** * Shorthand for printHtmlPart to reduce class size * @param partNumber */ - public final void h(final int partNumber) { - staticOut.write(htmlParts[partNumber]); + final void h(final int partNumber) { + staticOut.write(htmlParts[partNumber]) } /** @@ -640,41 +630,42 @@ public final void h(final int partNumber) { * * @param jspTags The JSP tags used */ - @SuppressWarnings("rawtypes") - public void setJspTags(Map jspTags) { - this.jspTags = jspTags; + @SuppressWarnings('rawtypes') + void setJspTags(Map jspTags) { + this.jspTags = jspTags } - public String[] getHtmlParts() { - return htmlParts; + String[] getHtmlParts() { + return htmlParts } protected boolean isHtmlPart(String htmlPart) { - return htmlPartsSet != null && htmlPart != null && htmlPartsSet.contains(System.identityHashCode(htmlPart)); + return htmlPartsSet != null && htmlPart != null && htmlPartsSet.contains(System.identityHashCode(htmlPart)) } - public void setHtmlParts(String[] htmlParts) { - this.htmlParts = htmlParts; + void setHtmlParts(String[] htmlParts) { + this.htmlParts = htmlParts } - public void setHtmlPartsSet(Set htmlPartsSet) { - this.htmlPartsSet = htmlPartsSet; + void setHtmlPartsSet(Set htmlPartsSet) { + this.htmlPartsSet = htmlPartsSet } - public final OutputEncodingStack getOutputStack() { - return outputStack; + final OutputEncodingStack getOutputStack() { + return outputStack } - public OutputContext getOutputContext() { - return outputContext; + OutputContext getOutputContext() { + return outputContext } - public final void createTagBody(int bodyClosureIndex, Closure bodyClosure) { - TagBodyClosure tagBody = new TagBodyClosure(this, outputContext, bodyClosure, true); - setBodyClosure(bodyClosureIndex, tagBody); + final void createTagBody(int bodyClosureIndex, Closure bodyClosure) { + TagBodyClosure tagBody = new TagBodyClosure(this, outputContext, bodyClosure, true) + setBodyClosure(bodyClosureIndex, tagBody) } - public void changeItVariable(Object value) { - setVariableDirectly("it", value); + void changeItVariable(Object value) { + setVariableDirectly('it', value) } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageBinding.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageBinding.groovy similarity index 53% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageBinding.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageBinding.groovy index daae037d39a..df4860b4a5c 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageBinding.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageBinding.groovy @@ -16,86 +16,86 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp; +package org.grails.gsp -import java.util.Map; +import groovy.transform.CompileStatic +import org.apache.commons.logging.Log +import org.apache.commons.logging.LogFactory -import groovy.lang.Binding; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import grails.plugins.GrailsPlugin; -import org.grails.taglib.TemplateVariableBinding; +import grails.plugins.GrailsPlugin +import org.grails.taglib.TemplateVariableBinding /** * Script Binding that is used in GSP evaluation. * * @author Lari Hotari */ -public class GroovyPageBinding extends TemplateVariableBinding { - private static final Log log = LogFactory.getLog(GroovyPageBinding.class); +@CompileStatic +class GroovyPageBinding extends TemplateVariableBinding { - public GroovyPageBinding() { - super(); + private static final Log log = LogFactory.getLog(GroovyPageBinding) + + GroovyPageBinding() { + super() } - public GroovyPageBinding(Binding parent) { - super(parent); + GroovyPageBinding(Binding parent) { + super(parent) } - public GroovyPageBinding(String pluginContextPath) { - setPluginContextPath(pluginContextPath); + GroovyPageBinding(String pluginContextPath) { + setPluginContextPath(pluginContextPath) } - @SuppressWarnings("rawtypes") - public GroovyPageBinding(Map variables) { - super(variables); + @SuppressWarnings('rawtypes') + GroovyPageBinding(Map variables) { + super(variables) } - public GroovyPageBinding(String[] args) { - super(args); + GroovyPageBinding(String[] args) { + super(args) } - @SuppressWarnings("unchecked") + @SuppressWarnings('unchecked') @Override - public Object getVariable(String name) { - Object val = getVariablesMap().get(name); + Object getVariable(String name) { + Object val = getVariablesMap().get(name) if (val == null && !getVariablesMap().containsKey(name)) { - if (GroovyPage.PAGE_SCOPE.equals(name)) return this; - return super.getVariable(name); + if (GroovyPage.PAGE_SCOPE.equals(name)) return this + return super.getVariable(name) } - return val; + return val } protected boolean shouldUseChildBinding(TemplateVariableBinding childBinding) { - return isRoot() || hasSameOwnerClass(childBinding); + return isRoot() || hasSameOwnerClass(childBinding) } private boolean hasSameOwnerClass(TemplateVariableBinding otherBinding) { // owner class can be same in recursive rendering; in that case, the child binding should be used for setting variable values - return (getOwner() != null && otherBinding.getOwner() != null && getOwner().getClass() == otherBinding.getOwner().getClass()); + return (getOwner() != null && otherBinding.getOwner() != null && getOwner().getClass() == otherBinding.getOwner().getClass()) } - public String getPluginContextPath() { - return (String) getVariable(GroovyPage.PLUGIN_CONTEXT_PATH); + String getPluginContextPath() { + return (String) getVariable(GroovyPage.PLUGIN_CONTEXT_PATH) } - @SuppressWarnings("unchecked") - public void setPluginContextPath(String pluginContextPath) { - getVariablesMap().put(GroovyPage.PLUGIN_CONTEXT_PATH, pluginContextPath); + @SuppressWarnings('unchecked') + void setPluginContextPath(String pluginContextPath) { + getVariablesMap().put(GroovyPage.PLUGIN_CONTEXT_PATH, pluginContextPath) } - @SuppressWarnings("unchecked") - public void setPagePlugin(GrailsPlugin plugin) { - getVariablesMap().put("pagePlugin", plugin); + @SuppressWarnings('unchecked') + void setPagePlugin(GrailsPlugin plugin) { + getVariablesMap().put('pagePlugin', plugin) } - public GrailsPlugin getPagePlugin() { - return (GrailsPlugin) getVariable("pagePlugin"); + GrailsPlugin getPagePlugin() { + return (GrailsPlugin) getVariable('pagePlugin') } protected boolean isReservedName(String name) { - return GroovyPage.isReservedName(name); + return GroovyPage.isReservedName(name) } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageClassLoader.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageClassLoader.groovy similarity index 61% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageClassLoader.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageClassLoader.groovy index 9aea9869321..92210ca8dc6 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageClassLoader.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageClassLoader.groovy @@ -16,16 +16,16 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp; +package org.grails.gsp -import java.security.CodeSource; +import java.security.CodeSource -import groovy.lang.GroovyClassLoader; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.CompilerConfiguration; -import org.codehaus.groovy.control.Phases; +import groovy.transform.CompileStatic +import org.codehaus.groovy.control.CompilationUnit +import org.codehaus.groovy.control.CompilerConfiguration +import org.codehaus.groovy.control.Phases -import org.grails.gsp.compiler.transform.GroovyPageInjectionOperation; +import org.grails.gsp.compiler.transform.GroovyPageInjectionOperation /** * A class loader that is aware of Groovy Pages and injection operations. @@ -33,26 +33,27 @@ * @author Stephane Maldini * @since 2.0 */ -public class GroovyPageClassLoader extends GroovyClassLoader { +@CompileStatic +class GroovyPageClassLoader extends GroovyClassLoader { - public GroovyPageClassLoader() { + GroovyPageClassLoader() { // default } - public GroovyPageClassLoader(ClassLoader loader) { - super(loader); + GroovyPageClassLoader(ClassLoader loader) { + super(loader) } - public GroovyPageClassLoader(GroovyClassLoader parent) { - super(parent); + GroovyPageClassLoader(GroovyClassLoader parent) { + super(parent) } - public GroovyPageClassLoader(ClassLoader parent, CompilerConfiguration config, boolean useConfigurationClasspath) { - super(parent, config, useConfigurationClasspath); + GroovyPageClassLoader(ClassLoader parent, CompilerConfiguration config, boolean useConfigurationClasspath) { + super(parent, config, useConfigurationClasspath) } - public GroovyPageClassLoader(ClassLoader loader, CompilerConfiguration config) { - super(loader, config); + GroovyPageClassLoader(ClassLoader loader, CompilerConfiguration config) { + super(loader, config) } /** @@ -60,13 +61,14 @@ public GroovyPageClassLoader(ClassLoader loader, CompilerConfiguration config) { */ @Override protected CompilationUnit createCompilationUnit(CompilerConfiguration config, CodeSource source) { - CompilationUnit cu = super.createCompilationUnit(config, source); + CompilationUnit cu = super.createCompilationUnit(config, source) - GroovyPageInjectionOperation operation; + GroovyPageInjectionOperation operation - operation = new GroovyPageInjectionOperation(); + operation = new GroovyPageInjectionOperation() - cu.addPhaseOperation(operation, Phases.CANONICALIZATION); - return cu; + cu.addPhaseOperation(operation, Phases.CANONICALIZATION) + return cu } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageMetaInfo.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageMetaInfo.groovy similarity index 50% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageMetaInfo.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageMetaInfo.groovy index 48c2312d955..49a67806949 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageMetaInfo.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageMetaInfo.groovy @@ -14,49 +14,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.grails.gsp; - -import java.io.DataInputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.Writer; -import java.lang.ref.SoftReference; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; -import java.net.URL; -import java.net.URLConnection; -import java.security.PrivilegedAction; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Callable; - -import groovy.lang.GroovySystem; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.context.ApplicationContext; -import org.springframework.core.io.FileSystemResource; -import org.springframework.core.io.Resource; -import org.springframework.util.ReflectionUtils; - -import grails.core.GrailsApplication; -import grails.core.support.GrailsApplicationAware; -import grails.io.IOUtils; -import grails.plugins.GrailsPlugin; -import grails.plugins.GrailsPluginManager; -import grails.util.CacheEntry; -import org.grails.encoder.Encoder; -import org.grails.gsp.compiler.GroovyPageParser; -import org.grails.gsp.jsp.TagLibraryResolver; -import org.grails.taglib.TagLibraryLookup; -import org.grails.taglib.encoder.WithCodecHelper; +package org.grails.gsp + +import java.lang.ref.SoftReference +import java.lang.reflect.Constructor +import java.lang.reflect.Field +import java.lang.reflect.InvocationTargetException +import java.lang.reflect.Modifier +import java.security.PrivilegedAction +import java.util.concurrent.Callable + +import groovy.transform.CompileStatic +import org.apache.commons.logging.Log +import org.apache.commons.logging.LogFactory +import org.springframework.context.ApplicationContext +import org.springframework.core.io.FileSystemResource +import org.springframework.core.io.Resource +import org.springframework.util.ReflectionUtils + +import grails.core.GrailsApplication +import grails.core.support.GrailsApplicationAware +import grails.io.IOUtils +import grails.plugins.GrailsPlugin +import grails.plugins.GrailsPluginManager +import grails.util.CacheEntry +import org.grails.encoder.Encoder +import org.grails.gsp.compiler.GroovyPageParser +import org.grails.gsp.jsp.TagLibraryResolver +import org.grails.taglib.TagLibraryLookup +import org.grails.taglib.encoder.WithCodecHelper /** * Encapsulates the information necessary to describe a GSP. @@ -65,148 +51,150 @@ * @author Lari Hotari * @since 0.5 */ -public class GroovyPageMetaInfo implements GrailsApplicationAware { - - private static final Log LOG = LogFactory.getLog(GroovyPageMetaInfo.class); - private TagLibraryLookup tagLibraryLookup; - private TagLibraryResolver jspTagLibraryResolver; - private ThreadLocal> pageInstance = new ThreadLocal<>(); - - private boolean precompiledMode = false; - private Class pageClass; - private Constructor pageClassConstructor; - private String sourceChecksum; - private volatile SourceStamp checksumStamp; - private InputStream groovySource; - private String contentType; - private int[] lineNumbers; - private String[] htmlParts; - private Set htmlPartsSet; - @SuppressWarnings("rawtypes") - private Map jspTags = Collections.emptyMap(); - private GroovyPagesException compilationException; - private Encoder expressionEncoder; - private Encoder staticEncoder; - private Encoder outEncoder; - private Encoder taglibEncoder; - private String expressionCodecName; - private String staticCodecName; - private String outCodecName; - private String taglibCodecName; - private boolean compileStaticMode; - private boolean modelFieldsMode; - private Set modelFields; - - public static final String HTML_DATA_POSTFIX = "_html.data"; - public static final String LINENUMBERS_DATA_POSTFIX = "_linenumbers.data"; - - public static final long LASTMODIFIED_CHECK_INTERVAL = Long.getLong("grails.gsp.reload.interval", 5000).longValue(); - private GrailsApplication grailsApplication; - - private String pluginPath; - private GrailsPlugin pagePlugin; - private boolean initialized = false; - - private CacheEntry shouldReloadCacheEntry = new CacheEntry<>(); - public static String DEFAULT_PLUGIN_PATH = ""; - - volatile boolean metaClassShouldBeRemoved = false; - - public GroovyPageMetaInfo() { - - } - - @SuppressWarnings("rawtypes") - public GroovyPageMetaInfo(Class pageClass) { - this(); - precompiledMode = true; - this.pageClass = pageClass; +@CompileStatic +class GroovyPageMetaInfo implements GrailsApplicationAware { + + private static final Log LOG = LogFactory.getLog(GroovyPageMetaInfo) + private TagLibraryLookup tagLibraryLookup + private TagLibraryResolver jspTagLibraryResolver + private ThreadLocal> pageInstance = new ThreadLocal<>() + + private boolean precompiledMode = false + private Class pageClass + private Constructor pageClassConstructor + private String sourceChecksum + private volatile SourceStamp checksumStamp + private InputStream groovySource + private String contentType + private int[] lineNumbers + private String[] htmlParts + private Set htmlPartsSet + + @SuppressWarnings('rawtypes') + private Map jspTags = Collections.emptyMap() + private GroovyPagesException compilationException + private Encoder expressionEncoder + private Encoder staticEncoder + private Encoder outEncoder + private Encoder taglibEncoder + private String expressionCodecName + private String staticCodecName + private String outCodecName + private String taglibCodecName + private boolean compileStaticMode + private boolean modelFieldsMode + private Set modelFields + + public static final String HTML_DATA_POSTFIX = '_html.data' + public static final String LINENUMBERS_DATA_POSTFIX = '_linenumbers.data' + + public static final long LASTMODIFIED_CHECK_INTERVAL = Long.getLong('grails.gsp.reload.interval', 5000).longValue() + private GrailsApplication grailsApplication + + private String pluginPath + private GrailsPlugin pagePlugin + private boolean initialized = false + + private CacheEntry shouldReloadCacheEntry = new CacheEntry<>() + public static String DEFAULT_PLUGIN_PATH = '' + + volatile boolean metaClassShouldBeRemoved = false + + GroovyPageMetaInfo() { + + } + + @SuppressWarnings('rawtypes') + GroovyPageMetaInfo(Class pageClass) { + this() + precompiledMode = true + this.pageClass = pageClass try { - this.pageClassConstructor = pageClass.getConstructor(); + this.pageClassConstructor = pageClass.getConstructor() } catch (NoSuchMethodException e) { - throw new RuntimeException(e); + throw new RuntimeException(e) } - contentType = (String) ReflectionUtils.getField(ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_CONTENT_TYPE), null); - jspTags = (Map) ReflectionUtils.getField(ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_JSP_TAGS), null); - Field sourceChecksumField = ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_SOURCE_CHECKSUM); + contentType = (String) ReflectionUtils.getField(ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_CONTENT_TYPE), null) + jspTags = (Map) ReflectionUtils.getField(ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_JSP_TAGS), null) + Field sourceChecksumField = ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_SOURCE_CHECKSUM) if (sourceChecksumField != null) { - sourceChecksum = (String) ReflectionUtils.getField(sourceChecksumField, null); + sourceChecksum = (String) ReflectionUtils.getField(sourceChecksumField, null) } - expressionCodecName = (String) ReflectionUtils.getField(ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_EXPRESSION_CODEC), null); - staticCodecName = (String) ReflectionUtils.getField(ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_STATIC_CODEC), null); - outCodecName = (String) ReflectionUtils.getField(ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_OUT_CODEC), null); - taglibCodecName = (String) ReflectionUtils.getField(ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_TAGLIB_CODEC), null); - Field compileStaticModeField = ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_COMPILE_STATIC_MODE); + expressionCodecName = (String) ReflectionUtils.getField(ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_EXPRESSION_CODEC), null) + staticCodecName = (String) ReflectionUtils.getField(ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_STATIC_CODEC), null) + outCodecName = (String) ReflectionUtils.getField(ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_OUT_CODEC), null) + taglibCodecName = (String) ReflectionUtils.getField(ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_TAGLIB_CODEC), null) + Field compileStaticModeField = ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_COMPILE_STATIC_MODE) if (compileStaticModeField != null) { - compileStaticMode = (Boolean) ReflectionUtils.getField(compileStaticModeField, null); + compileStaticMode = (Boolean) ReflectionUtils.getField(compileStaticModeField, null) } - Field modelFieldsModeField = ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_MODEL_FIELDS_MODE); + Field modelFieldsModeField = ReflectionUtils.findField(pageClass, GroovyPageParser.CONSTANT_NAME_MODEL_FIELDS_MODE) if (modelFieldsModeField != null) { - modelFieldsMode = (Boolean) ReflectionUtils.getField(modelFieldsModeField, null); + modelFieldsMode = (Boolean) ReflectionUtils.getField(modelFieldsModeField, null) } try { - readHtmlData(); + readHtmlData() } catch (IOException e) { - throw new RuntimeException("Problem reading html data for page class " + pageClass, e); + throw new RuntimeException('Problem reading html data for page class ' + pageClass, e) } } static interface GroovyPageMetaInfoInitializer { - public void initialize(GroovyPageMetaInfo metaInfo); + void initialize(GroovyPageMetaInfo metaInfo) } synchronized void initializeOnDemand(GroovyPageMetaInfoInitializer initializer) { if (!initialized) { - initializer.initialize(this); + initializer.initialize(this) } } - public void initialize() { - expressionEncoder = getCodec(expressionCodecName); - staticEncoder = getCodec(staticCodecName); - outEncoder = getCodec(outCodecName); - taglibEncoder = getCodec(taglibCodecName); + void initialize() { + expressionEncoder = getCodec(expressionCodecName) + staticEncoder = getCodec(staticCodecName) + outEncoder = getCodec(outCodecName) + taglibEncoder = getCodec(taglibCodecName) - initializePluginPath(); - initializeModelFields(); + initializePluginPath() + initializeModelFields() - initialized = true; + initialized = true } private synchronized void initializeModelFields() { if (getPageClass() != null) { - Set modelFields = new HashSet<>(); + Set modelFields = new HashSet<>() if (modelFieldsMode) { - for (Field field : getPageClass().getDeclaredFields()) { + for (Field field in getPageClass().getDeclaredFields()) { if (!Modifier.isStatic(field.getModifiers()) && !field.isSynthetic()) { - ReflectionUtils.makeAccessible(field); - modelFields.add(field); + ReflectionUtils.makeAccessible(field) + modelFields.add(field) } } } - this.modelFields = Collections.unmodifiableSet(modelFields); + this.modelFields = Collections.unmodifiableSet(modelFields) } } private Encoder getCodec(String codecName) { - return WithCodecHelper.lookupEncoder(grailsApplication, codecName); + return WithCodecHelper.lookupEncoder(grailsApplication, codecName) } private void initializePluginPath() { if (grailsApplication == null || pageClass == null) { - return; + return } - final ApplicationContext applicationContext = grailsApplication.getMainContext(); + final ApplicationContext applicationContext = grailsApplication.getMainContext() if (applicationContext == null || !applicationContext.containsBean(GrailsPluginManager.BEAN_NAME)) { - return; + return } - GrailsPluginManager pluginManager = applicationContext.getBean(GrailsPluginManager.BEAN_NAME, GrailsPluginManager.class); - pluginPath = pluginManager.getPluginPathForClass(pageClass); - if (pluginPath == null) pluginPath = DEFAULT_PLUGIN_PATH; - pagePlugin = pluginManager.getPluginForClass(pageClass); + GrailsPluginManager pluginManager = applicationContext.getBean(GrailsPluginManager.BEAN_NAME, GrailsPluginManager) + pluginPath = pluginManager.getPluginPathForClass(pageClass) + if (pluginPath == null) pluginPath = DEFAULT_PLUGIN_PATH + pagePlugin = pluginManager.getPluginForClass(pageClass) } /** @@ -215,23 +203,23 @@ private void initializePluginPath() { * @throws IOException */ private void readHtmlData() throws IOException { - String dataResourceName = resolveDataResourceName(HTML_DATA_POSTFIX); + String dataResourceName = resolveDataResourceName(HTML_DATA_POSTFIX) - DataInputStream input = null; + DataInputStream input = null try { - InputStream resourceStream = pageClass.getResourceAsStream(dataResourceName); + InputStream resourceStream = pageClass.getResourceAsStream(dataResourceName) if (resourceStream != null) { - input = new DataInputStream(resourceStream); - int arrayLen = input.readInt(); - htmlParts = new String[arrayLen]; + input = new DataInputStream(resourceStream) + int arrayLen = input.readInt() + htmlParts = new String[arrayLen] for (int i = 0; i < arrayLen; i++) { - htmlParts[i] = input.readUTF(); + htmlParts[i] = input.readUTF() } } } finally { - IOUtils.closeQuietly(input); + IOUtils.closeQuietly(input) } } @@ -241,18 +229,18 @@ private void readHtmlData() throws IOException { * @throws IOException */ private void readLineNumbers() throws IOException { - String dataResourceName = resolveDataResourceName(LINENUMBERS_DATA_POSTFIX); + String dataResourceName = resolveDataResourceName(LINENUMBERS_DATA_POSTFIX) - DataInputStream input = null; + DataInputStream input = null try { - input = new DataInputStream(pageClass.getResourceAsStream(dataResourceName)); - int arrayLen = input.readInt(); - lineNumbers = new int[arrayLen]; + input = new DataInputStream(pageClass.getResourceAsStream(dataResourceName)) + int arrayLen = input.readInt() + lineNumbers = new int[arrayLen] for (int i = 0; i < arrayLen; i++) { - lineNumbers[i] = input.readInt(); + lineNumbers[i] = input.readInt() } } finally { - IOUtils.closeQuietly(input); + IOUtils.closeQuietly(input) } } @@ -264,157 +252,157 @@ private void readLineNumbers() throws IOException { * @return The data resource name */ private String resolveDataResourceName(String postfix) { - String dataResourceName = pageClass.getName(); - int pos = dataResourceName.lastIndexOf('.'); + String dataResourceName = pageClass.getName() + int pos = dataResourceName.lastIndexOf('.') if (pos > -1) { - dataResourceName = dataResourceName.substring(pos + 1); + dataResourceName = dataResourceName.substring(pos + 1) } - dataResourceName += postfix; - return dataResourceName; + dataResourceName += postfix + return dataResourceName } - public TagLibraryLookup getTagLibraryLookup() { - return tagLibraryLookup; + TagLibraryLookup getTagLibraryLookup() { + return tagLibraryLookup } - public void setTagLibraryLookup(TagLibraryLookup tagLibraryLookup) { - this.tagLibraryLookup = tagLibraryLookup; + void setTagLibraryLookup(TagLibraryLookup tagLibraryLookup) { + this.tagLibraryLookup = tagLibraryLookup } - public TagLibraryResolver getJspTagLibraryResolver() { - return jspTagLibraryResolver; + TagLibraryResolver getJspTagLibraryResolver() { + return jspTagLibraryResolver } - public void setJspTagLibraryResolver(TagLibraryResolver jspTagLibraryResolver) { - this.jspTagLibraryResolver = jspTagLibraryResolver; + void setJspTagLibraryResolver(TagLibraryResolver jspTagLibraryResolver) { + this.jspTagLibraryResolver = jspTagLibraryResolver } - public Class getPageClass() { - return pageClass; + Class getPageClass() { + return pageClass } - public GroovyPage getPageClassInstance() throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { - SoftReference pageSoftRef = pageInstance.get(); - GroovyPage pageCacheEntry = pageSoftRef != null ? pageSoftRef.get() : null; + GroovyPage getPageClassInstance() throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { + SoftReference pageSoftRef = pageInstance.get() + GroovyPage pageCacheEntry = pageSoftRef != null ? pageSoftRef.get() : null if (pageCacheEntry == null) { - pageCacheEntry = (GroovyPage) pageClassConstructor.newInstance(); - pageCacheEntry.initCommonRun(this); + pageCacheEntry = (GroovyPage) pageClassConstructor.newInstance() + pageCacheEntry.initCommonRun(this) if (!isModelFieldsMode()) { - pageInstance.set(new SoftReference<>(pageCacheEntry)); + pageInstance.set(new SoftReference<>(pageCacheEntry)) } } - return pageCacheEntry; + return pageCacheEntry } - public void setPageClass(Class pageClass) { - this.pageClass = pageClass; + void setPageClass(Class pageClass) { + this.pageClass = pageClass try { - this.pageClassConstructor = pageClass.getConstructor(); + this.pageClassConstructor = pageClass.getConstructor() } catch (NoSuchMethodException e) { - throw new RuntimeException(e); + throw new RuntimeException(e) } - pageInstance.set(null); - initializePluginPath(); + pageInstance.set(null) + initializePluginPath() } /** * @return the checksum of the GSP source this page was compiled from, or {@code null} if none was recorded * @since 8.0.0 */ - public String getSourceChecksum() { - return this.sourceChecksum; + String getSourceChecksum() { + return this.sourceChecksum } /** * @param sourceChecksum the checksum of the GSP source this page was compiled from * @since 8.0.0 */ - public void setSourceChecksum(String sourceChecksum) { - this.sourceChecksum = sourceChecksum; + void setSourceChecksum(String sourceChecksum) { + this.sourceChecksum = sourceChecksum } - public InputStream getGroovySource() { - return groovySource; + InputStream getGroovySource() { + return groovySource } - public void setGroovySource(InputStream groovySource) { - this.groovySource = groovySource; + void setGroovySource(InputStream groovySource) { + this.groovySource = groovySource } - public String getContentType() { - return contentType; + String getContentType() { + return contentType } - public void setContentType(String contentType) { - this.contentType = contentType; + void setContentType(String contentType) { + this.contentType = contentType } - public int[] getLineNumbers() { + int[] getLineNumbers() { if (precompiledMode) { - return getPrecompiledLineNumbers(); + return getPrecompiledLineNumbers() } - return lineNumbers; + return lineNumbers } private synchronized int[] getPrecompiledLineNumbers() { if (lineNumbers == null) { try { - readLineNumbers(); + readLineNumbers() } catch (IOException e) { - LOG.warn("Problem reading precompiled linenumbers", e); + LOG.warn('Problem reading precompiled linenumbers', e) } } - return lineNumbers; + return lineNumbers } - public void setLineNumbers(int[] lineNumbers) { - this.lineNumbers = lineNumbers; + void setLineNumbers(int[] lineNumbers) { + this.lineNumbers = lineNumbers } - @SuppressWarnings("rawtypes") - public void setJspTags(Map jspTags) { - this.jspTags = jspTags != null ? jspTags : Collections.emptyMap(); + @SuppressWarnings('rawtypes') + void setJspTags(Map jspTags) { + this.jspTags = jspTags != null ? jspTags : Collections.emptyMap() } - @SuppressWarnings("rawtypes") - public Map getJspTags() { - return jspTags; + @SuppressWarnings('rawtypes') + Map getJspTags() { + return jspTags } - public void setCompilationException(GroovyPagesException e) { - compilationException = e; + void setCompilationException(GroovyPagesException e) { + compilationException = e } - public GroovyPagesException getCompilationException() { - return compilationException; + GroovyPagesException getCompilationException() { + return compilationException } - public String[] getHtmlParts() { - return htmlParts; + String[] getHtmlParts() { + return htmlParts } - public void setHtmlParts(String[] htmlParts) { - this.htmlParts = htmlParts; - this.htmlPartsSet = new HashSet<>(); + void setHtmlParts(String[] htmlParts) { + this.htmlParts = htmlParts + this.htmlPartsSet = new HashSet<>() if (htmlParts != null) { - for (String htmlPart : htmlParts) { + for (String htmlPart in htmlParts) { if (htmlPart != null) { - htmlPartsSet.add(System.identityHashCode(htmlPart)); + htmlPartsSet.add(System.identityHashCode(htmlPart)) } } } } Set getHtmlPartsSet() { - return this.htmlPartsSet; + return this.htmlPartsSet } /** * The modification time and length a page's source had when it last matched the recorded checksum. */ - private record SourceStamp(long lastModified, long contentLength) { + private static record SourceStamp(long lastModified, long contentLength) { } /** @@ -435,19 +423,19 @@ private record SourceStamp(long lastModified, long contentLength) { * @return true if the source no longer matches */ private boolean hasSourceChecksumChanged(Resource resource) { - SourceStamp stamp = readSourceStamp(resource); + SourceStamp stamp = readSourceStamp(resource) if (stamp != null && stamp.equals(this.checksumStamp)) { - return false; + return false } - String currentChecksum = establishChecksum(resource); + String currentChecksum = establishChecksum(resource) if (currentChecksum == null) { - return false; + return false } if (this.sourceChecksum.equals(currentChecksum)) { - this.checksumStamp = stamp; - return false; + this.checksumStamp = stamp + return false } - return true; + return true } /** @@ -456,16 +444,16 @@ private boolean hasSourceChecksumChanged(Resource resource) { * caller must hash rather than assume the source is unchanged */ private SourceStamp readSourceStamp(Resource resource) { - long modified = establishLastModified(resource); + long modified = establishLastModified(resource) if (modified <= 0) { - return null; + return null } try { - long length = resource.contentLength(); - return length >= 0 ? new SourceStamp(modified, length) : null; + long length = resource.contentLength() + return length >= 0 ? new SourceStamp(modified, length) : null } catch (IOException e) { - return null; + return null } } @@ -479,16 +467,16 @@ private SourceStamp readSourceStamp(Resource resource) { */ private String establishChecksum(Resource resource) { if (resource == null) { - return null; + return null } try { - return GroovyPageParser.checksumOf(resource.getContentAsByteArray()); + return GroovyPageParser.checksumOf(resource.getContentAsByteArray()) } catch (IOException e) { if (LOG.isDebugEnabled()) { - LOG.debug("Unable to checksum GSP source [" + resource + "], leaving the compiled page in place", e); + LOG.debug('Unable to checksum GSP source [' + resource + '], leaving the compiled page in place', e) } - return null; + return null } } @@ -500,45 +488,45 @@ private String establishChecksum(Resource resource) { * @return The last modified date or -1 */ private long establishLastModified(Resource resource) { - if (resource == null) return -1; + if (resource == null) return -1 if (resource instanceof FileSystemResource) { - return ((FileSystemResource) resource).getFile().lastModified(); + return ((FileSystemResource) resource).getFile().lastModified() } - long last; - URLConnection urlc = null; + long last + URLConnection urlc = null try { - URL url = resource.getURL(); - if ("file".equals(url.getProtocol())) { - File file = new File(url.getFile()); + URL url = resource.getURL() + if ('file'.equals(url.getProtocol())) { + File file = new File(url.getFile()) if (file.exists()) { - return file.lastModified(); + return file.lastModified() } } - urlc = url.openConnection(); - urlc.setDoInput(false); - urlc.setDoOutput(false); - last = urlc.getLastModified(); + urlc = url.openConnection() + urlc.setDoInput(false) + urlc.setDoOutput(false) + last = urlc.getLastModified() } catch (FileNotFoundException fnfe) { - last = -1; + last = -1 } catch (IOException e) { - last = -1; + last = -1 } finally { if (urlc != null) { try { - InputStream is = urlc.getInputStream(); + InputStream is = urlc.getInputStream() if (is != null) { - is.close(); + is.close() } - } catch (IOException e) { + } catch (IOException ignored) { // ignore } } } - return last; + return last } /** @@ -551,112 +539,113 @@ private long establishLastModified(Resource resource) { * @param resourceCallable call back that resolves the source gsp lazily * @return true if the available gsp source file is newer than the loaded one. */ - public boolean shouldReload(final PrivilegedAction resourceCallable) { - if (resourceCallable == null) return false; - Resource resource = checkIfReloadableResourceHasChanged(resourceCallable); - return (resource != null); + boolean shouldReload(final PrivilegedAction resourceCallable) { + if (resourceCallable == null) return false + Resource resource = checkIfReloadableResourceHasChanged(resourceCallable) + return (resource != null) } - public Resource checkIfReloadableResourceHasChanged(final PrivilegedAction resourceCallable) { - Callable checkerCallable = new Callable<>() { - public Resource call() { - Resource resource = resourceCallable.run(); + Resource checkIfReloadableResourceHasChanged(final PrivilegedAction resourceCallable) { + Callable checkerCallable = new Callable() { + Resource call() { + Resource resource = resourceCallable.run() if (resource != null && resource.exists() && sourceChecksum != null) { // Staleness is decided by comparing content. A page that was merely touched is not stale, // and an edit is caught however close together the writes fall. - return hasSourceChecksumChanged(resource) ? resource : null; + return hasSourceChecksumChanged(resource) ? resource : null } - return null; + return null } - }; - return shouldReloadCacheEntry.getValue(LASTMODIFIED_CHECK_INTERVAL, checkerCallable, true, null); + } + return shouldReloadCacheEntry.getValue(LASTMODIFIED_CHECK_INTERVAL, checkerCallable, true, null) } - public boolean isPrecompiledMode() { - return precompiledMode; + boolean isPrecompiledMode() { + return precompiledMode } - public GrailsApplication getGrailsApplication() { - return grailsApplication; + GrailsApplication getGrailsApplication() { + return grailsApplication } - public void setGrailsApplication(GrailsApplication grailsApplication) { - this.grailsApplication = grailsApplication; + void setGrailsApplication(GrailsApplication grailsApplication) { + this.grailsApplication = grailsApplication } - public String getPluginPath() { - return pluginPath; + String getPluginPath() { + return pluginPath } - public GrailsPlugin getPagePlugin() { - return pagePlugin; + GrailsPlugin getPagePlugin() { + return pagePlugin } - public Encoder getOutEncoder() { - return outEncoder; + Encoder getOutEncoder() { + return outEncoder } - public Encoder getStaticEncoder() { - return staticEncoder; + Encoder getStaticEncoder() { + return staticEncoder } - public Encoder getExpressionEncoder() { - return expressionEncoder; + Encoder getExpressionEncoder() { + return expressionEncoder } - public Encoder getTaglibEncoder() { - return taglibEncoder; + Encoder getTaglibEncoder() { + return taglibEncoder } - public void setExpressionCodecName(String expressionCodecName) { - this.expressionCodecName = expressionCodecName; + void setExpressionCodecName(String expressionCodecName) { + this.expressionCodecName = expressionCodecName } - public void setStaticCodecName(String staticCodecName) { - this.staticCodecName = staticCodecName; + void setStaticCodecName(String staticCodecName) { + this.staticCodecName = staticCodecName } - public void setOutCodecName(String pageCodecName) { - this.outCodecName = pageCodecName; + void setOutCodecName(String pageCodecName) { + this.outCodecName = pageCodecName } - public void setTaglibCodecName(String taglibCodecName) { - this.taglibCodecName = taglibCodecName; + void setTaglibCodecName(String taglibCodecName) { + this.taglibCodecName = taglibCodecName } - public boolean isCompileStaticMode() { - return compileStaticMode; + boolean isCompileStaticMode() { + return compileStaticMode } - public void setCompileStaticMode(boolean compileStaticMode) { - this.compileStaticMode = compileStaticMode; + void setCompileStaticMode(boolean compileStaticMode) { + this.compileStaticMode = compileStaticMode } - public boolean isModelFieldsMode() { - return modelFieldsMode; + boolean isModelFieldsMode() { + return modelFieldsMode } - public void setModelFieldsMode(boolean modelFieldsMode) { - this.modelFieldsMode = modelFieldsMode; + void setModelFieldsMode(boolean modelFieldsMode) { + this.modelFieldsMode = modelFieldsMode } - public Set getModelFields() { + Set getModelFields() { if (modelFields == null) { - initializeModelFields(); + initializeModelFields() } - return modelFields; + return modelFields } - public void removePageMetaClass() { - metaClassShouldBeRemoved = true; + void removePageMetaClass() { + metaClassShouldBeRemoved = true if (pageClass != null) { - GroovySystem.getMetaClassRegistry().removeMetaClass(pageClass); + GroovySystem.getMetaClassRegistry().removeMetaClass(pageClass) } } - public void writeToFinished(Writer out) { + void writeToFinished(Writer out) { if (metaClassShouldBeRemoved) { - removePageMetaClass(); + removePageMetaClass() } } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageResourceLoader.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageResourceLoader.groovy similarity index 54% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageResourceLoader.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageResourceLoader.groovy index e9e23c9ee3c..efac8ea2453 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageResourceLoader.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageResourceLoader.groovy @@ -16,15 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp; +package org.grails.gsp -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import groovy.transform.CompileStatic +import org.apache.commons.logging.Log +import org.apache.commons.logging.LogFactory +import org.springframework.core.io.Resource +import org.springframework.util.Assert -import org.springframework.core.io.Resource; -import org.springframework.util.Assert; - -import org.grails.core.io.StaticResourceLoader; +import org.grails.core.io.StaticResourceLoader /** * A StaticResourceLoader that loads GSPs from a local grails-app folder instead of from WEB-INF in @@ -35,34 +35,36 @@ * @author Graeme Rocher * @since 0.5 */ -public class GroovyPageResourceLoader extends StaticResourceLoader { +@CompileStatic +class GroovyPageResourceLoader extends StaticResourceLoader { /** * The id of the instance of this bean to be used in the Spring context */ - public static final String BEAN_ID = "groovyPageResourceLoader"; + public static final String BEAN_ID = 'groovyPageResourceLoader' - private static final Log LOG = LogFactory.getLog(GroovyPageResourceLoader.class); - private static final String PLUGINS_PATH = "/plugins/"; + private static final Log LOG = LogFactory.getLog(GroovyPageResourceLoader) + private static final String PLUGINS_PATH = '/plugins/' - private Resource localBaseResource; + private Resource localBaseResource @Override - public void setBaseResource(Resource baseResource) { - localBaseResource = baseResource; - super.setBaseResource(baseResource); + void setBaseResource(Resource baseResource) { + localBaseResource = baseResource + super.setBaseResource(baseResource) } @Override - public Resource getResource(String location) { - Assert.hasLength(location, "Argument [location] cannot be null or blank"); + Resource getResource(String location) { + Assert.hasLength(location, 'Argument [location] cannot be null or blank') - Resource resource = super.getResource(location); + Resource resource = super.getResource(location) if (LOG.isDebugEnabled()) { - LOG.debug("Resolved GSP location [" + location + "] to resource [" + resource + - "] (exists? [" + resource.exists() + "]) using base resource [" + localBaseResource + "]"); + LOG.debug('Resolved GSP location [' + location + '] to resource [' + resource + + '] (exists? [' + resource.exists() + ']) using base resource [' + localBaseResource + ']') } - return resource; + return resource } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageSourceDecorator.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageSourceDecorator.groovy similarity index 87% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageSourceDecorator.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageSourceDecorator.groovy index fdda7fa7106..207a24e4242 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageSourceDecorator.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageSourceDecorator.groovy @@ -16,8 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp; +package org.grails.gsp + +interface GroovyPageSourceDecorator { + + StringBuilder decorate(StringBuilder source) -public interface GroovyPageSourceDecorator { - StringBuilder decorate(StringBuilder source); } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageTemplate.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageTemplate.groovy similarity index 50% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageTemplate.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageTemplate.groovy index 9f11e4ecef3..3b5d9497518 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageTemplate.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageTemplate.groovy @@ -16,15 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp; +package org.grails.gsp -import java.util.Map; +import groovy.text.Template +import groovy.transform.CompileStatic -import groovy.lang.Writable; -import groovy.text.Template; - -import org.grails.taglib.encoder.OutputContextLookup; -import org.grails.taglib.encoder.OutputContextLookupHelper; +import org.grails.taglib.encoder.OutputContextLookup +import org.grails.taglib.encoder.OutputContextLookupHelper /** * Knows how to make in instance of GroovyPageWritable. @@ -32,47 +30,50 @@ * @author Graeme Rocher * @since 0.5 */ -public class GroovyPageTemplate implements Template, Cloneable { - private final OutputContextLookup outputContextLookup; - private GroovyPageMetaInfo metaInfo; - private boolean allowSettingContentType = false; +@CompileStatic +class GroovyPageTemplate implements Template, Cloneable { + + private final OutputContextLookup outputContextLookup + private GroovyPageMetaInfo metaInfo + private boolean allowSettingContentType = false - public GroovyPageTemplate(GroovyPageMetaInfo metaInfo) { - this(metaInfo, OutputContextLookupHelper.getOutputContextLookup()); + GroovyPageTemplate(GroovyPageMetaInfo metaInfo) { + this(metaInfo, OutputContextLookupHelper.getOutputContextLookup()) } - public GroovyPageTemplate(GroovyPageMetaInfo metaInfo, OutputContextLookup outputContextLookup) { - this.metaInfo = metaInfo; - this.outputContextLookup = outputContextLookup; + GroovyPageTemplate(GroovyPageMetaInfo metaInfo, OutputContextLookup outputContextLookup) { + this.metaInfo = metaInfo + this.outputContextLookup = outputContextLookup } - public Writable make() { - return new GroovyPageWritable(metaInfo, outputContextLookup, allowSettingContentType); + Writable make() { + return new GroovyPageWritable(metaInfo, outputContextLookup, allowSettingContentType) } - @SuppressWarnings("rawtypes") - public GroovyPageWritable make(Map binding) { - GroovyPageWritable gptw = new GroovyPageWritable(metaInfo, outputContextLookup, allowSettingContentType); - gptw.setBinding(binding); - return gptw; + @SuppressWarnings('rawtypes') + GroovyPageWritable make(Map binding) { + GroovyPageWritable gptw = new GroovyPageWritable(metaInfo, outputContextLookup, allowSettingContentType) + gptw.setBinding(binding) + return gptw } - public GroovyPageMetaInfo getMetaInfo() { - return metaInfo; + GroovyPageMetaInfo getMetaInfo() { + return metaInfo } - public boolean isAllowSettingContentType() { - return allowSettingContentType; + boolean isAllowSettingContentType() { + return allowSettingContentType } - public void setAllowSettingContentType(boolean allowSettingContentType) { - this.allowSettingContentType = allowSettingContentType; + void setAllowSettingContentType(boolean allowSettingContentType) { + this.allowSettingContentType = allowSettingContentType } @Override - public Object clone() { - GroovyPageTemplate cloned = new GroovyPageTemplate(metaInfo); - cloned.setAllowSettingContentType(allowSettingContentType); - return cloned; + Object clone() { + GroovyPageTemplate cloned = new GroovyPageTemplate(metaInfo) + cloned.setAllowSettingContentType(allowSettingContentType) + return cloned } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageWritable.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageWritable.groovy similarity index 57% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageWritable.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageWritable.groovy index 522010a4173..7f5b5c66f74 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageWritable.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPageWritable.groovy @@ -16,28 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp; +package org.grails.gsp -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.Writer; -import java.util.LinkedHashMap; -import java.util.Map; +import groovy.transform.CompileStatic +import org.slf4j.Logger +import org.slf4j.LoggerFactory -import groovy.lang.Binding; -import groovy.lang.Writable; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import grails.util.Environment; -import org.grails.taglib.AbstractTemplateVariableBinding; -import org.grails.taglib.TemplateVariableBinding; -import org.grails.taglib.encoder.OutputContext; -import org.grails.taglib.encoder.OutputContextLookup; +import grails.util.Environment +import org.grails.taglib.AbstractTemplateVariableBinding +import org.grails.taglib.TemplateVariableBinding +import org.grails.taglib.encoder.OutputContext +import org.grails.taglib.encoder.OutputContextLookup /** * Writes itself to the specified writer, typically the response writer. @@ -46,22 +35,25 @@ * @author Lari Hotari * @since 0.5 */ -public class GroovyPageWritable implements Writable { - private static final Logger LOG = LoggerFactory.getLogger(GroovyPageWritable.class); - private static final String GSP_NONE_CODEC_NAME = "none"; - private GroovyPageMetaInfo metaInfo; - private OutputContextLookup outputContextLookup; - private boolean allowSettingContentType; - @SuppressWarnings("rawtypes") - private Map additionalBinding = new LinkedHashMap(); - private boolean showSource; - - private static final String GROOVY_SOURCE_CONTENT_TYPE = "text/plain"; - - public GroovyPageWritable(GroovyPageMetaInfo metaInfo, OutputContextLookup outputContextLookup, boolean allowSettingContentType) { - this.metaInfo = metaInfo; - this.outputContextLookup = outputContextLookup; - this.allowSettingContentType = allowSettingContentType; +@CompileStatic +class GroovyPageWritable implements Writable { + + private static final Logger LOG = LoggerFactory.getLogger(GroovyPageWritable) + private static final String GSP_NONE_CODEC_NAME = 'none' + private GroovyPageMetaInfo metaInfo + private OutputContextLookup outputContextLookup + private boolean allowSettingContentType + + @SuppressWarnings('rawtypes') + private Map additionalBinding = new LinkedHashMap() + private boolean showSource + + private static final String GROOVY_SOURCE_CONTENT_TYPE = 'text/plain' + + GroovyPageWritable(GroovyPageMetaInfo metaInfo, OutputContextLookup outputContextLookup, boolean allowSettingContentType) { + this.metaInfo = metaInfo + this.outputContextLookup = outputContextLookup + this.allowSettingContentType = allowSettingContentType } /** @@ -69,10 +61,10 @@ public GroovyPageWritable(GroovyPageMetaInfo metaInfo, OutputContextLookup outpu * * @param binding The additional variables */ - @SuppressWarnings("rawtypes") - public void setBinding(Map binding) { + @SuppressWarnings('rawtypes') + void setBinding(Map binding) { if (binding != null) { - additionalBinding = binding; + additionalBinding = binding } } @@ -83,130 +75,130 @@ public void setBinding(Map binding) { * @return Returns the passed Writer * @throws IOException */ - public Writer writeTo(Writer out) throws IOException { - OutputContext outputContext = outputContextLookup.lookupOutputContext(); + Writer writeTo(Writer out) throws IOException { + OutputContext outputContext = outputContextLookup.lookupOutputContext() try { - return doWriteTo(outputContext, out); + return doWriteTo(outputContext, out) } finally { - doCleanUp(outputContext, out); + doCleanUp(outputContext, out) } } protected void doCleanUp(OutputContext outputContext, Writer out) { - metaInfo.writeToFinished(out); + metaInfo.writeToFinished(out) } protected Writer doWriteTo(OutputContext outputContext, Writer out) throws IOException { if (shouldShowGroovySource(outputContext)) { // Set it to TEXT - outputContext.setContentType(GROOVY_SOURCE_CONTENT_TYPE); // must come before response.getOutputStream() - writeGroovySourceToResponse(metaInfo, out); + outputContext.setContentType(GROOVY_SOURCE_CONTENT_TYPE) // must come before response.getOutputStream() + writeGroovySourceToResponse(metaInfo, out) } else { // Set it to HTML by default if (metaInfo.getCompilationException() != null) { - throw metaInfo.getCompilationException(); + throw metaInfo.getCompilationException() } // Set up the script context - AbstractTemplateVariableBinding parentBinding = null; - boolean hasRequest = outputContext != null; - boolean newParentCreated = false; + AbstractTemplateVariableBinding parentBinding = null + boolean hasRequest = outputContext != null + boolean newParentCreated = false if (hasRequest) { - parentBinding = outputContext.getBinding(); + parentBinding = outputContext.getBinding() if (parentBinding == null) { - parentBinding = outputContext.createAndRegisterRootBinding(); - newParentCreated = true; + parentBinding = outputContext.createAndRegisterRootBinding() + newParentCreated = true } } if (allowSettingContentType && hasRequest) { // only try to set content type when evaluating top level GSP - boolean contentTypeAlreadySet = outputContext.isContentTypeAlreadySet(); + boolean contentTypeAlreadySet = outputContext.isContentTypeAlreadySet() if (!contentTypeAlreadySet) { - LOG.debug("Writing output with content type: {}", metaInfo.getContentType()); - outputContext.setContentType(metaInfo.getContentType()); // must come before response.getWriter() + LOG.debug('Writing output with content type: {}', metaInfo.getContentType()) + outputContext.setContentType(metaInfo.getContentType()) // must come before response.getWriter() } } - GroovyPageBinding binding = createBinding(parentBinding); + GroovyPageBinding binding = createBinding(parentBinding) if (hasRequest) { - outputContext.setBinding(binding); + outputContext.setBinding(binding) } - Binding existingBinding = null; - GroovyPage page = null; + Binding existingBinding = null + GroovyPage page = null try { - page = metaInfo.getPageClassInstance(); - existingBinding = page.getBinding(); + page = metaInfo.getPageClassInstance() + existingBinding = page.getBinding() } catch (Exception e) { - throw new GroovyPagesException("Problem instantiating page class", e); + throw new GroovyPagesException('Problem instantiating page class', e) } - page.setBinding(binding); - binding.setOwner(page); + page.setBinding(binding) + binding.setOwner(page) - page.initRun(out, outputContext, metaInfo); + page.initRun(out, outputContext, metaInfo) try { - page.run(); + page.run() } finally { if (existingBinding != null) { - page.setBinding(existingBinding); + page.setBinding(existingBinding) } - page.cleanup(); + page.cleanup() if (hasRequest) { if (newParentCreated) { - outputContext.setBinding(null); + outputContext.setBinding(null) } else { - outputContext.setBinding(parentBinding); + outputContext.setBinding(parentBinding) } } } } - return out; + return out } private int incrementAndGetDebugTemplatesIdCounter(OutputContext outputContext) { //debugTemplatesIdCounter.incrementAndGet() - return 0; + return 0 } private boolean shouldShowGroovySource(OutputContext outputContext) { - return isShowSource() && Environment.getCurrent() == Environment.DEVELOPMENT && metaInfo.getGroovySource() != null; + return isShowSource() && Environment.getCurrent() == Environment.DEVELOPMENT && metaInfo.getGroovySource() != null } - private static final GspNoneCodec gspNoneCodeInstance = new GspNoneCodec(); + private static final GspNoneCodec gspNoneCodeInstance = new GspNoneCodec() - public boolean isShowSource() { - return showSource; + boolean isShowSource() { + return showSource } - public void setShowSource(boolean showSource) { - this.showSource = showSource; + void setShowSource(boolean showSource) { + this.showSource = showSource } private static final class GspNoneCodec { - @SuppressWarnings("unused") - public final Object encode(Object object) { - return object; + @SuppressWarnings('unused') + final Object encode(Object object) { + return object } } private GroovyPageBinding createBinding(Binding parent) { - GroovyPageBinding binding = new GroovyPageBinding(); - binding.setParent(parent); - binding.setVariableDirectly("it", null); + GroovyPageBinding binding = new GroovyPageBinding() + binding.setParent(parent) + binding.setVariableDirectly('it', null) if (additionalBinding != null) { - binding.addMap(additionalBinding); + binding.addMap(additionalBinding) } // set plugin context path for top level rendering, this means actual view + layout // view is top level when parent is GroovyPageRequestBinding // pluginContextPath is also resetted when a plugin template is overrided by an application view - if (parent == null || (parent instanceof TemplateVariableBinding && ((TemplateVariableBinding) parent).isRoot()) || "".equals(metaInfo.getPluginPath())) { - binding.setPluginContextPath(metaInfo.getPluginPath()); + if (parent == null || (parent instanceof TemplateVariableBinding && ((TemplateVariableBinding) parent).isRoot()) || ''.equals(metaInfo.getPluginPath())) { + binding.setPluginContextPath(metaInfo.getPluginPath()) } - binding.setPagePlugin(metaInfo.getPagePlugin()); - return binding; + binding.setPagePlugin(metaInfo.getPagePlugin()) + return binding } /** @@ -217,18 +209,18 @@ private GroovyPageBinding createBinding(Binding parent) { */ protected void writeInputStreamToResponse(InputStream in, Writer out) throws IOException { try { - in.reset(); - Reader reader = new InputStreamReader(in, "UTF-8"); - char[] buf = new char[8192]; - - for (; ; ) { - int read = reader.read(buf); - if (read <= 0) break; - out.write(buf, 0, read); + in.reset() + Reader reader = new InputStreamReader(in, 'UTF-8') + char[] buf = new char[8192] + + for (;;) { + int read = reader.read(buf) + if (read <= 0) break + out.write(buf, 0, read) } } finally { - out.close(); - in.close(); + out.close() + in.close() } } @@ -244,52 +236,53 @@ protected void writeInputStreamToResponse(InputStream in, Writer out) throws IOE * stream for the Groovy source, or the writer. */ protected void writeGroovySourceToResponse(GroovyPageMetaInfo info, Writer out) throws IOException { - InputStream in = info.getGroovySource(); - if (in == null) return; + InputStream in = info.getGroovySource() + if (in == null) return try { try { - in.reset(); - } catch (IOException e) { + in.reset() + } catch (IOException ignored) { // ignore } - BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8")); + BufferedReader reader = new BufferedReader(new InputStreamReader(in, 'UTF-8')) - int lineNum = 1; - int maxPaddingSize = 3; + int lineNum = 1 + int maxPaddingSize = 3 // Prepare the buffer containing the whitespace padding. // The padding is used to right-align the line numbers. - StringBuilder paddingBuffer = new StringBuilder(maxPaddingSize); + StringBuilder paddingBuffer = new StringBuilder(maxPaddingSize) for (int i = 0; i < maxPaddingSize; i++) { - paddingBuffer.append(' '); + paddingBuffer.append(' ') } // Set the initial padding. - String padding = paddingBuffer.toString(); + String padding = paddingBuffer.toString() // Read the Groovy source line by line and write it to the // response, prefixing each line with the line number. for (String line = reader.readLine(); line != null; line = reader.readLine(), lineNum++) { // Get the current line number as a string. - String numberText = String.valueOf(lineNum); + String numberText = String.valueOf(lineNum) // Decrease the padding if the current line number has // more digits than the previous one. if (padding.length() + numberText.length() > 4) { - paddingBuffer.deleteCharAt(padding.length() - 1); - padding = paddingBuffer.toString(); + paddingBuffer.deleteCharAt(padding.length() - 1) + padding = paddingBuffer.toString() } // Write out this line. - out.write(padding); - out.write(numberText); - out.write(": "); - out.write(line); - out.write('\n'); + out.write(padding) + out.write(numberText) + out.write(': ') + out.write(line) + out.write('\n') } } finally { - out.close(); - in.close(); + out.close() + in.close() } } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPagesException.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPagesException.groovy similarity index 59% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPagesException.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPagesException.groovy index a741e3e23ab..24f93521ce9 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPagesException.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPagesException.groovy @@ -16,10 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp; +package org.grails.gsp -import org.grails.core.exceptions.GrailsException; -import org.grails.exceptions.reporting.SourceCodeAware; +import groovy.transform.CompileStatic + +import org.grails.core.exceptions.GrailsException +import org.grails.exceptions.reporting.SourceCodeAware /** * Thrown when processing GSP pages. @@ -27,37 +29,39 @@ * @author Graeme Rocher * @since 0.5 */ -public class GroovyPagesException extends GrailsException implements SourceCodeAware { +@CompileStatic +class GroovyPagesException extends GrailsException implements SourceCodeAware { - private static final long serialVersionUID = 6142857809397583528L; - private int lineNumber; - private String fileName; + private static final long serialVersionUID = 6142857809397583528L + private int lineNumber + private String fileName - public GroovyPagesException(String message, Throwable e) { - super(message, e); + GroovyPagesException(String message, Throwable e) { + super(message, e) } - public GroovyPagesException(String message, Throwable exception, int lineNumber, String fileName) { - super(message, exception); - this.lineNumber = lineNumber; - this.fileName = fileName; + GroovyPagesException(String message, Throwable exception, int lineNumber, String fileName) { + super(message, exception) + this.lineNumber = lineNumber + this.fileName = fileName } - public GroovyPagesException(String message) { - super(message); + GroovyPagesException(String message) { + super(message) } - public String getFileName() { + String getFileName() { if (fileName == null && getCause() instanceof SourceCodeAware) { - return ((SourceCodeAware) getCause()).getFileName(); + return ((SourceCodeAware) getCause()).getFileName() } - return fileName; + return fileName } - public int getLineNumber() { + int getLineNumber() { if (lineNumber == -1 && getCause() instanceof SourceCodeAware) { - return ((SourceCodeAware) getCause()).getLineNumber(); + return ((SourceCodeAware) getCause()).getLineNumber() } - return lineNumber; + return lineNumber } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPagesTemplateEngine.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPagesTemplateEngine.groovy similarity index 58% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPagesTemplateEngine.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPagesTemplateEngine.groovy index 9932343c7bf..b901da2512a 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPagesTemplateEngine.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/GroovyPagesTemplateEngine.groovy @@ -16,68 +16,57 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicInteger; - -import groovy.lang.GroovyClassLoader; -import groovy.text.Template; -import org.codehaus.groovy.control.CompilationFailedException; -import org.codehaus.groovy.control.CompilerConfiguration; -import org.codehaus.groovy.runtime.IOGroovyMethods; - -import io.micrometer.observation.Observation; -import io.micrometer.observation.ObservationRegistry; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.ResourceLoaderAware; -import org.springframework.core.io.ByteArrayResource; -import org.springframework.core.io.FileSystemResource; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; -import org.springframework.core.io.UrlResource; -import org.springframework.scripting.ScriptSource; -import org.springframework.scripting.support.ResourceScriptSource; -import org.springframework.util.Assert; - -import grails.config.Config; -import grails.config.Settings; -import grails.core.GrailsApplication; -import grails.core.GrailsClass; -import grails.util.CacheEntry; -import grails.util.Environment; -import grails.util.GrailsUtil; -import org.grails.core.artefact.DomainClassArtefactHandler; -import org.grails.core.exceptions.DefaultErrorsPrinter; -import org.grails.exceptions.ExceptionUtils; -import org.grails.gsp.compiler.GroovyPageParser; -import org.grails.gsp.io.DefaultGroovyPageLocator; -import org.grails.gsp.io.GroovyPageCompiledScriptSource; -import org.grails.gsp.io.GroovyPageLocator; -import org.grails.gsp.io.GroovyPageResourceScriptSource; -import org.grails.gsp.io.GroovyPageScriptSource; -import org.grails.gsp.jsp.TagLibraryResolver; -import org.grails.taglib.TagLibraryLookup; +package org.grails.gsp + +import java.nio.charset.StandardCharsets +import java.security.PrivilegedAction +import java.util.concurrent.Callable +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.ConcurrentMap +import java.util.concurrent.atomic.AtomicInteger + +import groovy.text.Template +import groovy.transform.CompileStatic +import io.micrometer.observation.Observation +import io.micrometer.observation.ObservationRegistry +import org.apache.commons.logging.Log +import org.apache.commons.logging.LogFactory +import org.codehaus.groovy.control.CompilationFailedException +import org.codehaus.groovy.control.CompilerConfiguration +import org.codehaus.groovy.runtime.IOGroovyMethods +import org.springframework.beans.BeansException +import org.springframework.beans.factory.BeanClassLoaderAware +import org.springframework.beans.factory.InitializingBean +import org.springframework.context.ApplicationContext +import org.springframework.context.ApplicationContextAware +import org.springframework.context.ResourceLoaderAware +import org.springframework.core.io.ByteArrayResource +import org.springframework.core.io.FileSystemResource +import org.springframework.core.io.Resource +import org.springframework.core.io.ResourceLoader +import org.springframework.core.io.UrlResource +import org.springframework.scripting.ScriptSource +import org.springframework.scripting.support.ResourceScriptSource +import org.springframework.util.Assert + +import grails.config.Config +import grails.config.Settings +import grails.core.GrailsApplication +import grails.core.GrailsClass +import grails.util.CacheEntry +import grails.util.Environment +import grails.util.GrailsUtil +import org.grails.core.artefact.DomainClassArtefactHandler +import org.grails.core.exceptions.DefaultErrorsPrinter +import org.grails.exceptions.ExceptionUtils +import org.grails.gsp.compiler.GroovyPageParser +import org.grails.gsp.io.DefaultGroovyPageLocator +import org.grails.gsp.io.GroovyPageCompiledScriptSource +import org.grails.gsp.io.GroovyPageLocator +import org.grails.gsp.io.GroovyPageResourceScriptSource +import org.grails.gsp.io.GroovyPageScriptSource +import org.grails.gsp.jsp.TagLibraryResolver +import org.grails.taglib.TagLibraryLookup /** * Based on (but not extending) the existing TemplateEngine implementations @@ -95,140 +84,137 @@ * * @since 0.1 */ -public class GroovyPagesTemplateEngine extends ResourceAwareTemplateEngine implements ResourceLoaderAware, ApplicationContextAware, InitializingBean, BeanClassLoaderAware { +@CompileStatic +class GroovyPagesTemplateEngine extends ResourceAwareTemplateEngine implements ResourceLoaderAware, ApplicationContextAware, InitializingBean, BeanClassLoaderAware { - public static final String CONFIG_PROPERTY_DISABLE_CACHING_RESOURCES = Settings.GSP_DISABLE_CACHING_RESOURCES; - public static final String CONFIG_PROPERTY_GSP_ENABLE_RELOAD = Settings.GSP_ENABLE_RELOAD; - public static final String BEAN_ID = ResourceAwareTemplateEngine.BEAN_ID; + public static final String CONFIG_PROPERTY_DISABLE_CACHING_RESOURCES = Settings.GSP_DISABLE_CACHING_RESOURCES + public static final String CONFIG_PROPERTY_GSP_ENABLE_RELOAD = Settings.GSP_ENABLE_RELOAD + public static final String BEAN_ID = ResourceAwareTemplateEngine.BEAN_ID - private static final String GENERATED_GSP_NAME_PREFIX = "gsp_script_"; - private static final Log LOG = LogFactory.getLog(GroovyPagesTemplateEngine.class); - private static File dumpLineNumbersTo; + private static final String GENERATED_GSP_NAME_PREFIX = 'gsp_script_' + private static final Log LOG = LogFactory.getLog(GroovyPagesTemplateEngine) + private static File dumpLineNumbersTo - private ConcurrentMap> pageCache = new ConcurrentHashMap<>(); - private ClassLoader classLoader; - private AtomicInteger scriptNameCount = new AtomicInteger(0); + private ConcurrentMap> pageCache = new ConcurrentHashMap<>() + private ClassLoader classLoader + private AtomicInteger scriptNameCount = new AtomicInteger(0) - private ObservationRegistry observationRegistry = ObservationRegistry.NOOP; + private ObservationRegistry observationRegistry = ObservationRegistry.NOOP - private GroovyPageLocator groovyPageLocator = new DefaultGroovyPageLocator(); + private GroovyPageLocator groovyPageLocator = new DefaultGroovyPageLocator() - private boolean reloadEnabled; - private TagLibraryLookup tagLibraryLookup; - private TagLibraryResolver jspTagLibraryResolver; - private boolean cacheResources = true; - private String gspEncoding = System.getProperty("file.encoding", GroovyPageParser.DEFAULT_ENCODING); + private boolean reloadEnabled + private TagLibraryLookup tagLibraryLookup + private TagLibraryResolver jspTagLibraryResolver + private boolean cacheResources = true + private String gspEncoding = System.getProperty('file.encoding', GroovyPageParser.DEFAULT_ENCODING) - private GrailsApplication grailsApplication; - private Map> cachedDomainsWithoutPackage; + private GrailsApplication grailsApplication + private Map> cachedDomainsWithoutPackage - private List groovyPageSourceDecorators = new ArrayList(); + private List groovyPageSourceDecorators = new ArrayList() static { - String dirPath = System.getProperty("grails.dump.gsp.line.numbers.to.dir"); + String dirPath = System.getProperty('grails.dump.gsp.line.numbers.to.dir') if (dirPath != null) { - File dir = new File(dirPath); + File dir = new File(dirPath) if (dir.exists() || dir.mkdirs()) { - dumpLineNumbersTo = dir; + dumpLineNumbersTo = dir } } } private class GroovyPagesTemplateEngineCacheEntry extends CacheEntry { - private final String pageName; + private final String pageName - public GroovyPagesTemplateEngineCacheEntry(String pageName) { - this.pageName = pageName; + GroovyPagesTemplateEngineCacheEntry(String pageName) { + this.pageName = pageName } @Override protected boolean hasExpired(long timeout, Object cacheRequestObject) { - GroovyPageMetaInfo meta = getValue(); - Resource resource = (Resource) cacheRequestObject; - return meta == null || isGroovyPageReloadable(resource, meta); + GroovyPageMetaInfo meta = getValue() + Resource resource = (Resource) cacheRequestObject + return meta == null || isGroovyPageReloadable(resource, meta) } @Override protected GroovyPageMetaInfo updateValue(GroovyPageMetaInfo oldValue, Callable updater, Object cacheRequestObject) throws Exception { if (oldValue != null) { - oldValue.removePageMetaClass(); + oldValue.removePageMetaClass() } - Resource resource = (Resource) cacheRequestObject; - return buildPageMetaInfo(resource, pageName); + Resource resource = (Resource) cacheRequestObject + return buildPageMetaInfo(resource, pageName) } } private static class GroovyPagesTemplateEngineCallable implements Callable> { - private final CacheEntry cacheEntry; + private final CacheEntry cacheEntry - public GroovyPagesTemplateEngineCallable(CacheEntry cacheEntry) { - this.cacheEntry = cacheEntry; + GroovyPagesTemplateEngineCallable(CacheEntry cacheEntry) { + this.cacheEntry = cacheEntry } @Override - public CacheEntry call() throws Exception { - return cacheEntry; + CacheEntry call() throws Exception { + return cacheEntry } } - public GroovyPagesTemplateEngine() { - // default + void setGroovyPageSourceDecorators(List groovyPageSourceDecorators) { + this.groovyPageSourceDecorators = groovyPageSourceDecorators } - public void setGroovyPageSourceDecorators(List groovyPageSourceDecorators) { - this.groovyPageSourceDecorators = groovyPageSourceDecorators; + List getGroovyPageSourceDecorators() { + return groovyPageSourceDecorators } - public List getGroovyPageSourceDecorators() { - return groovyPageSourceDecorators; + void setGroovyPageLocator(GroovyPageLocator groovyPageLocator) { + this.groovyPageLocator = groovyPageLocator } - public void setGroovyPageLocator(GroovyPageLocator groovyPageLocator) { - this.groovyPageLocator = groovyPageLocator; + GroovyPageLocator getGroovyPageLocator() { + return groovyPageLocator } - public GroovyPageLocator getGroovyPageLocator() { - return groovyPageLocator; + void setResourceLoader(ResourceLoader resourceLoader) { + groovyPageLocator.addResourceLoader(resourceLoader) } - public void setResourceLoader(ResourceLoader resourceLoader) { - groovyPageLocator.addResourceLoader(resourceLoader); - } - - public void afterPropertiesSet() { + void afterPropertiesSet() { if (classLoader == null) { - classLoader = initGroovyClassLoader(Thread.currentThread().getContextClassLoader()); - } else if (!classLoader.getClass().equals(GroovyPageClassLoader.class)) { - classLoader = initGroovyClassLoader(classLoader); + classLoader = initGroovyClassLoader(Thread.currentThread().getContextClassLoader()) + } else if (!classLoader.getClass().equals(GroovyPageClassLoader)) { + classLoader = initGroovyClassLoader(classLoader) } if (!Environment.isDevelopmentMode()) { - cachedDomainsWithoutPackage = createDomainClassMap(); + cachedDomainsWithoutPackage = createDomainClassMap() } } private GroovyClassLoader initGroovyClassLoader(ClassLoader parent) { - CompilerConfiguration compConfig = new CompilerConfiguration(); - compConfig.setSourceEncoding(GroovyPageParser.GROOVY_SOURCE_CHAR_ENCODING); - return new GroovyPageClassLoader(parent, compConfig); + CompilerConfiguration compConfig = new CompilerConfiguration() + compConfig.setSourceEncoding(GroovyPageParser.GROOVY_SOURCE_CHAR_ENCODING) + return new GroovyPageClassLoader(parent, compConfig) } - public void setTagLibraryLookup(TagLibraryLookup tagLibraryLookup) { - this.tagLibraryLookup = tagLibraryLookup; + void setTagLibraryLookup(TagLibraryLookup tagLibraryLookup) { + this.tagLibraryLookup = tagLibraryLookup } - public void setJspTagLibraryResolver(TagLibraryResolver jspTagLibraryResolver) { - this.jspTagLibraryResolver = jspTagLibraryResolver; + void setJspTagLibraryResolver(TagLibraryResolver jspTagLibraryResolver) { + this.jspTagLibraryResolver = jspTagLibraryResolver } /** * Sets the ClassLoader that the TemplateEngine should use to * @param classLoader The ClassLoader to use when compilation of Groovy Pages occurs */ - public void setClassLoader(ClassLoader classLoader) { - this.classLoader = classLoader; + void setClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader } /** @@ -239,27 +225,27 @@ public void setClassLoader(ClassLoader classLoader) { * @param url The URL of the page * @return An array where the index is the line number witin the compiled GSP and the value is the line number within the source */ - public int[] calculateLineNumbersForPage(String url) { + int[] calculateLineNumbersForPage(String url) { try { - Template t = createTemplate(url); + Template t = createTemplate(url) if (t instanceof GroovyPageTemplate) { - return ((GroovyPageTemplate) t).getMetaInfo().getLineNumbers(); + return ((GroovyPageTemplate) t).getMetaInfo().getLineNumbers() } } catch (Exception e) { // ignore, non critical method used for retrieving debug info - LOG.warn("Exception retrieving line numbers from GSP: " + url + ", message: " + e.getMessage()); - LOG.debug("Full stack trace of error", e); + LOG.warn('Exception retrieving line numbers from GSP: ' + url + ', message: ' + e.getMessage()) + LOG.debug('Full stack trace of error', e) } - return new int[0]; + return new int[0] } - public int mapStackLineNumber(String url, int lineNumber) { - int[] lineNumbers = calculateLineNumbersForPage(url); + int mapStackLineNumber(String url, int lineNumber) { + int[] lineNumbers = calculateLineNumbersForPage(url) if (lineNumber < lineNumbers.length) { - lineNumber = lineNumbers[lineNumber - 1]; + lineNumber = lineNumbers[lineNumber - 1] } - return lineNumber; + return lineNumber } /** @@ -269,8 +255,8 @@ public int mapStackLineNumber(String url, int lineNumber) { * @return The Template instance */ @Override - public Template createTemplate(Resource resource) { - return createTemplate(resource, cacheResources); + Template createTemplate(Resource resource) { + return createTemplate(resource, cacheResources) } /** @@ -281,43 +267,43 @@ public Template createTemplate(Resource resource) { * @return The Template instance */ @Override - public Template createTemplate(Resource resource, final boolean cacheable) { + Template createTemplate(Resource resource, final boolean cacheable) { if (resource == null) { - throw new GroovyPagesException("Resource is null. No Groovy page found."); + throw new GroovyPagesException('Resource is null. No Groovy page found.') } //Yags: Because, "pageName" was sent as null originally, it is never go in pageCache, but will force to compile the String again and till the time this request // is getting executed, it will occupy space in PermGen space. So if there are 1000 request for the same resource at a particular instance, there will be 1000 instance // class in PermGen instead of ideally being 1 as they as essentially same resource. //we will cache metaInfo only is Developer wants-to. Developer will make sure that he creates unique key for every unique pages s/he wants to put in cache - final String pageName = establishPageName(resource, cacheable); + final String pageName = establishPageName(resource, cacheable) try { - return createTemplate(resource, pageName, cacheable); + return createTemplate(resource, pageName, cacheable) } catch (IOException e) { - throw new GroovyPagesException("Error loading template", e); + throw new GroovyPagesException('Error loading template', e) } } protected Template createTemplate(Resource resource, final String pageName, final boolean cacheable) throws IOException { - GroovyPageMetaInfo meta; + GroovyPageMetaInfo meta if (cacheable) { meta = CacheEntry.getValue(pageCache, pageName, -1, null, new GroovyPagesTemplateEngineCallable(new GroovyPagesTemplateEngineCacheEntry(pageName)), - true, resource); + true, resource) } else { - meta = buildPageMetaInfo(resource, pageName); + meta = buildPageMetaInfo(resource, pageName) } - return new GroovyPageTemplate(meta); + return new GroovyPageTemplate(meta) } protected String establishPageName(Resource resource, final boolean cacheable) { - String name; + String name if (cacheable) { - name = establishPageName(resource, getPathForResource(resource)); + name = establishPageName(resource, getPathForResource(resource)) } else { - name = establishPageName(resource, null); + name = establishPageName(resource, null) } - return name; + return name } /** @@ -328,78 +314,78 @@ protected String establishPageName(Resource resource, final boolean cacheable) { * @throws CompilationFailedException */ @Override - public Template createTemplate(String uri) { - return createTemplateForUri(uri); + Template createTemplate(String uri) { + return createTemplateForUri(uri) } private Template createTemplateFromPrecompiled(GroovyPageCompiledScriptSource compiledScriptSource) { - GroovyPageMetaInfo meta = initializeCompiledMetaInfo(compiledScriptSource.getGroovyPageMetaInfo()); + GroovyPageMetaInfo meta = initializeCompiledMetaInfo(compiledScriptSource.getGroovyPageMetaInfo()) if (isReloadEnabled()) { - GroovyPageResourceScriptSource changedResourceScriptSource = compiledScriptSource.getReloadableScriptSource(); + GroovyPageResourceScriptSource changedResourceScriptSource = compiledScriptSource.getReloadableScriptSource() if (changedResourceScriptSource != null) { - groovyPageLocator.removePrecompiledPage(compiledScriptSource); - return createTemplate(changedResourceScriptSource); + groovyPageLocator.removePrecompiledPage(compiledScriptSource) + return createTemplate(changedResourceScriptSource) } } - return new GroovyPageTemplate(meta); + return new GroovyPageTemplate(meta) } private GroovyPageMetaInfo initializeCompiledMetaInfo(GroovyPageMetaInfo meta) { meta.initializeOnDemand(new GroovyPageMetaInfo.GroovyPageMetaInfoInitializer() { - public void initialize(GroovyPageMetaInfo metaInfo) { - metaInfo.setGrailsApplication(grailsApplication); - metaInfo.setJspTagLibraryResolver(jspTagLibraryResolver); - metaInfo.setTagLibraryLookup(tagLibraryLookup); - metaInfo.initialize(); - GroovyPagesMetaUtils.registerMethodMissingForGSP(metaInfo.getPageClass(), tagLibraryLookup); + void initialize(GroovyPageMetaInfo metaInfo) { + metaInfo.setGrailsApplication(grailsApplication) + metaInfo.setJspTagLibraryResolver(jspTagLibraryResolver) + metaInfo.setTagLibraryLookup(tagLibraryLookup) + metaInfo.initialize() + GroovyPagesMetaUtils.registerMethodMissingForGSP(metaInfo.getPageClass(), tagLibraryLookup) } - }); - return meta; + }) + return meta } - public Template createTemplateForUri(String uri) { - return createTemplateForUri(new String[]{uri}); + Template createTemplateForUri(String uri) { + return createTemplateForUri([uri] as String[]) } - public Template createTemplateForUri(String[] uris) { - GroovyPageScriptSource scriptSource = findScriptSource(uris); + Template createTemplateForUri(String[] uris) { + GroovyPageScriptSource scriptSource = findScriptSource(uris) if (scriptSource != null) { - return createTemplate(scriptSource); + return createTemplate(scriptSource) } - return null; + return null } - public GroovyPageScriptSource findScriptSource(String uri) { - return findScriptSource(new String[]{uri}); + GroovyPageScriptSource findScriptSource(String uri) { + return findScriptSource([uri] as String[]) } - public GroovyPageScriptSource findScriptSource(String[] uris) { - GroovyPageScriptSource scriptSource = null; + GroovyPageScriptSource findScriptSource(String[] uris) { + GroovyPageScriptSource scriptSource = null - for (String uri : uris) { - scriptSource = groovyPageLocator.findPage(uri); - if (scriptSource != null) break; + for (String uri in uris) { + scriptSource = groovyPageLocator.findPage(uri) + if (scriptSource != null) break } - return scriptSource; + return scriptSource } - public Template createTemplate(ScriptSource scriptSource) { + Template createTemplate(ScriptSource scriptSource) { if (scriptSource instanceof GroovyPageCompiledScriptSource) { // handle pre-compiled - return createTemplateFromPrecompiled((GroovyPageCompiledScriptSource) scriptSource); + return createTemplateFromPrecompiled((GroovyPageCompiledScriptSource) scriptSource) } if (scriptSource instanceof ResourceScriptSource) { - ResourceScriptSource resourceSource = (ResourceScriptSource) scriptSource; - Resource resource = resourceSource.getResource(); - return createTemplate(resource, true); + ResourceScriptSource resourceSource = (ResourceScriptSource) scriptSource + Resource resource = resourceSource.getResource() + return createTemplate(resource, true) } try { - return createTemplate(scriptSource.getScriptAsString(), scriptSource.suggestedClassName()); + return createTemplate(scriptSource.getScriptAsString(), scriptSource.suggestedClassName()) } catch (IOException e) { - throw new RuntimeException("IOException in createTemplate", e); + throw new RuntimeException('IOException in createTemplate', e) } } @@ -414,11 +400,11 @@ public Template createTemplate(ScriptSource scriptSource) { * @throws CompilationFailedException * @throws IOException Thrown if an IO exception occurs creating the Template */ - public Template createTemplate(String txt, String pageName) throws IOException { - Assert.hasLength(txt, "Argument [txt] cannot be null or blank"); - Assert.hasLength(pageName, "Argument [pageName] cannot be null or blank"); + Template createTemplate(String txt, String pageName) throws IOException { + Assert.hasLength(txt, 'Argument [txt] cannot be null or blank') + Assert.hasLength(pageName, 'Argument [pageName] cannot be null or blank') - return createTemplate(new ByteArrayResource(txt.getBytes(StandardCharsets.UTF_8), pageName), pageName, pageName != null); + return createTemplate(new ByteArrayResource(txt.getBytes(StandardCharsets.UTF_8), pageName), pageName, pageName != null) } /** @@ -433,11 +419,11 @@ public Template createTemplate(String txt, String pageName) throws IOException { * @throws CompilationFailedException * @throws IOException Thrown if an IO exception occurs creating the Template */ - public Template createTemplate(String txt, String pageName, boolean cache) throws IOException { - Assert.hasLength(txt, "Argument [txt] cannot be null or blank"); - Assert.hasLength(pageName, "Argument [pageName] cannot be null or blank"); + Template createTemplate(String txt, String pageName, boolean cache) throws IOException { + Assert.hasLength(txt, 'Argument [txt] cannot be null or blank') + Assert.hasLength(pageName, 'Argument [pageName] cannot be null or blank') - return createTemplate(new ByteArrayResource(txt.getBytes(StandardCharsets.UTF_8), pageName), pageName, cache); + return createTemplate(new ByteArrayResource(txt.getBytes(StandardCharsets.UTF_8), pageName), pageName, cache) } /** @@ -453,8 +439,8 @@ public Template createTemplate(String txt, String pageName, boolean cache) throw * @throws IOException When a I/O Exception occurs reading the Template */ @Override - public Template createTemplate(File file) throws CompilationFailedException, ClassNotFoundException, IOException { - return createTemplate(new FileSystemResource(file)); + Template createTemplate(File file) throws CompilationFailedException, ClassNotFoundException, IOException { + return createTemplate(new FileSystemResource(file)) } /** @@ -468,8 +454,8 @@ public Template createTemplate(File file) throws CompilationFailedException, Cla * @throws IOException When a I/O Exception occurs reading the Template */ @Override - public Template createTemplate(URL url) throws CompilationFailedException, ClassNotFoundException, IOException { - return createTemplate(new UrlResource(url)); + Template createTemplate(URL url) throws CompilationFailedException, ClassNotFoundException, IOException { + return createTemplate(new UrlResource(url)) } /** @@ -478,39 +464,39 @@ public Template createTemplate(URL url) throws CompilationFailedException, Class * @return The Template instance */ @Override - public Template createTemplate(InputStream inputStream) { - GroovyPageMetaInfo metaInfo = buildPageMetaInfo(inputStream, null, null); - return new GroovyPageTemplate(metaInfo); + Template createTemplate(InputStream inputStream) { + GroovyPageMetaInfo metaInfo = buildPageMetaInfo(inputStream, null, null) + return new GroovyPageTemplate(metaInfo) } protected GroovyPageMetaInfo buildPageMetaInfo(Resource resource, String pageName) throws IOException { if (this.observationRegistry.isNoop()) { - return doBuildPageMetaInfo(resource, pageName); + return doBuildPageMetaInfo(resource, pageName) } // Compilation only happens on a template cache miss, so the count of this observation is // effectively the GSP compile (cache-miss) rate; its timer is the compile latency. - var resourceName = (pageName != null && !pageName.isEmpty()) ? pageName : "unknown"; - var observation = Observation.createNotStarted("gsp.compile", this.observationRegistry) - .contextualName("gsp.compile " + resourceName) - .highCardinalityKeyValue("gsp.name", resourceName); - return observation.observeChecked(() -> doBuildPageMetaInfo(resource, pageName)); + var resourceName = (pageName != null && !pageName.isEmpty()) ? pageName : 'unknown' + var observation = Observation.createNotStarted('gsp.compile', this.observationRegistry) + .contextualName('gsp.compile ' + resourceName) + .highCardinalityKeyValue('gsp.name', resourceName) + return observation.observeChecked({ -> doBuildPageMetaInfo(resource, pageName) } as Observation.CheckedCallable) } private GroovyPageMetaInfo doBuildPageMetaInfo(Resource resource, String pageName) throws IOException { - InputStream inputStream = resource.getInputStream(); + InputStream inputStream = resource.getInputStream() try { - return buildPageMetaInfo(inputStream, resource, pageName); + return buildPageMetaInfo(inputStream, resource, pageName) } finally { - inputStream.close(); + inputStream.close() } } private StringBuilder decorateGroovyPageSource(StringBuilder source) throws IOException { - for (GroovyPageSourceDecorator groovyPageSourceDecorator : groovyPageSourceDecorators) { - source = groovyPageSourceDecorator.decorate(source); + for (GroovyPageSourceDecorator groovyPageSourceDecorator in groovyPageSourceDecorators) { + source = groovyPageSourceDecorator.decorate(source) } - return source; + return source } /** @@ -521,11 +507,11 @@ private StringBuilder decorateGroovyPageSource(StringBuilder source) throws IOEx * @return true if it is reloadable */ private boolean isGroovyPageReloadable(final Resource resource, GroovyPageMetaInfo meta) { - return isReloadEnabled() && meta.shouldReload(new PrivilegedAction<>() { - public Resource run() { - return resource; + return isReloadEnabled() && meta.shouldReload(new PrivilegedAction() { + Resource run() { + return resource } - }); + }) } /** @@ -533,8 +519,8 @@ public Resource run() { * * @return true if it is */ - public boolean isReloadEnabled() { - return reloadEnabled; + boolean isReloadEnabled() { + return reloadEnabled } /** @@ -542,8 +528,8 @@ public boolean isReloadEnabled() { * * @param b True if it is enabled */ - public void setReloadEnabled(boolean b) { - reloadEnabled = b; + void setReloadEnabled(boolean b) { + reloadEnabled = b } /** @@ -552,21 +538,21 @@ public void setReloadEnabled(boolean b) { * @param uri The URI to check * @return A Resource instance */ - public Resource getResourceForUri(String uri) { - GroovyPageScriptSource scriptSource = getResourceWithinContext(uri); + Resource getResourceForUri(String uri) { + GroovyPageScriptSource scriptSource = getResourceWithinContext(uri) if (scriptSource != null && (scriptSource instanceof GroovyPageResourceScriptSource)) { - return ((GroovyPageResourceScriptSource) scriptSource).getResource(); + return ((GroovyPageResourceScriptSource) scriptSource).getResource() } - return null; + return null } private GroovyPageScriptSource getResourceWithinContext(String uri) { - Assert.state(groovyPageLocator != null, "TemplateEngine not initialised correctly, no [groovyPageLocator] specified!"); - GroovyPageScriptSource scriptSource = groovyPageLocator.findPage(uri); + Assert.state(groovyPageLocator != null, 'TemplateEngine not initialised correctly, no [groovyPageLocator] specified!') + GroovyPageScriptSource scriptSource = groovyPageLocator.findPage(uri) if (scriptSource != null) { - return scriptSource; + return scriptSource } - return null; + return null } /** @@ -578,62 +564,62 @@ private GroovyPageScriptSource getResourceWithinContext(String uri) { * @return The GroovyPageMetaInfo instance */ protected GroovyPageMetaInfo buildPageMetaInfo(InputStream inputStream, Resource res, String pageName) { - String name = establishPageName(res, pageName); + String name = establishPageName(res, pageName) - GroovyPageParser parser; - String path = getPathForResource(res); + GroovyPageParser parser + String path = getPathForResource(res) // Buffer the raw bytes rather than decoding straight off the stream, so the page can be checksummed // exactly as it is stored. The checksum has to be taken over the stored bytes, not over gspSource or // the decorated source below, because the runtime re-reads the resource raw when checking staleness. - byte[] gspBytes; + byte[] gspBytes try { - gspBytes = inputStream.readAllBytes(); - String gspSource = new String(gspBytes, getGspEncoding()); + gspBytes = inputStream.readAllBytes() + String gspSource = new String(gspBytes, getGspEncoding()) parser = new GroovyPageParser(name, path, path, decorateGroovyPageSource(new StringBuilder(gspSource)).toString(), - grailsApplication != null ? grailsApplication.getConfig() : null); + grailsApplication != null ? grailsApplication.getConfig() : null) } catch (IOException e) { - throw new GroovyPagesException("I/O parsing Groovy page [" + (res != null ? res.getDescription() : name) + "]: " + e.getMessage(), e); + throw new GroovyPagesException('I/O parsing Groovy page [' + (res != null ? res.getDescription() : name) + ']: ' + e.getMessage(), e) } - InputStream in = parser.parse(); + InputStream in = parser.parse() // Make a new metaInfo - GroovyPageMetaInfo metaInfo = createPageMetaInfo(parser, in); + GroovyPageMetaInfo metaInfo = createPageMetaInfo(parser, in) // A page compiled at runtime is checked for staleness the same way a precompiled one is. It costs // nothing extra -- the bytes are already in hand. - metaInfo.setSourceChecksum(GroovyPageParser.checksumOf(gspBytes)); + metaInfo.setSourceChecksum(GroovyPageParser.checksumOf(gspBytes)) try { - metaInfo.setPageClass(compileGroovyPage(in, name, path, metaInfo)); - metaInfo.setHtmlParts(parser.getHtmlPartsArray()); + metaInfo.setPageClass(compileGroovyPage(in, name, path, metaInfo)) + metaInfo.setHtmlParts(parser.getHtmlPartsArray()) } catch (GroovyPagesException e) { - metaInfo.setCompilationException(e); + metaInfo.setCompilationException(e) } - return metaInfo; + return metaInfo } private String getPathForResource(Resource res) { - if (res == null) return ""; + if (res == null) return '' - String path = null; + String path = null try { - File file = res.getFile(); + File file = res.getFile() if (file != null) { - path = file.getAbsolutePath(); + path = file.getAbsolutePath() } } - catch (IOException e) { + catch (IOException ignored) { // ignore } if (path != null) { - return path; + return path } if (res.getDescription() != null) { - return res.getDescription(); + return res.getDescription() } - return ""; + return '' } /** @@ -645,41 +631,41 @@ private String getPathForResource(Resource res) { * @return The compiled java.lang.Class, which is an instance of groovy.lang.Script */ private Class compileGroovyPage(InputStream in, String name, String pageName, GroovyPageMetaInfo metaInfo) { - GroovyClassLoader groovyClassLoader = findOrInitGroovyClassLoader(); + GroovyClassLoader groovyClassLoader = findOrInitGroovyClassLoader() // Compile the script into an object - Class scriptClass; + Class scriptClass try { - String groovySource = IOGroovyMethods.getText(in, GroovyPageParser.GROOVY_SOURCE_CHAR_ENCODING); + String groovySource = IOGroovyMethods.getText(in, GroovyPageParser.GROOVY_SOURCE_CHAR_ENCODING) //System.out.println(groovySource); - scriptClass = groovyClassLoader.parseClass(groovySource, name); + scriptClass = groovyClassLoader.parseClass(groovySource, name) } catch (CompilationFailedException e) { - LOG.error("Compilation error compiling GSP [" + name + "]:" + e.getMessage(), e); + LOG.error('Compilation error compiling GSP [' + name + ']:' + e.getMessage(), e) - int lineNumber = ExceptionUtils.extractLineNumber(e); + int lineNumber = ExceptionUtils.extractLineNumber(e) - final int[] lineMappings = metaInfo.getLineNumbers(); + final int[] lineMappings = metaInfo.getLineNumbers() if (lineNumber > 0 && lineNumber < lineMappings.length) { - lineNumber = lineMappings[lineNumber - 1]; + lineNumber = lineMappings[lineNumber - 1] } - String relativePageName = DefaultErrorsPrinter.makeRelativeIfPossible(pageName); - throw new GroovyPagesException("Could not parse script [" + relativePageName + "]: " + e.getMessage(), e, lineNumber, pageName); + String relativePageName = DefaultErrorsPrinter.makeRelativeIfPossible(pageName) + throw new GroovyPagesException('Could not parse script [' + relativePageName + ']: ' + e.getMessage(), e, lineNumber, pageName) } catch (IOException e) { - String relativePageName = DefaultErrorsPrinter.makeRelativeIfPossible(pageName); - throw new GroovyPagesException("IO exception parsing script [" + relativePageName + "]: " + e.getMessage(), e); + String relativePageName = DefaultErrorsPrinter.makeRelativeIfPossible(pageName) + throw new GroovyPagesException('IO exception parsing script [' + relativePageName + ']: ' + e.getMessage(), e) } - GroovyPagesMetaUtils.registerMethodMissingForGSP(scriptClass, tagLibraryLookup); + GroovyPagesMetaUtils.registerMethodMissingForGSP(scriptClass, tagLibraryLookup) - return scriptClass; + return scriptClass } private synchronized GroovyClassLoader findOrInitGroovyClassLoader() { if (!(classLoader instanceof GroovyPageClassLoader)) { - classLoader = initGroovyClassLoader(classLoader); + classLoader = initGroovyClassLoader(classLoader) } - return (GroovyClassLoader) classLoader; + return (GroovyClassLoader) classLoader } /** @@ -691,41 +677,41 @@ private synchronized GroovyClassLoader findOrInitGroovyClassLoader() { * @return A GroovyPageMetaInfo instance */ private GroovyPageMetaInfo createPageMetaInfo(GroovyPageParser parse, InputStream in) { - GroovyPageMetaInfo pageMeta = new GroovyPageMetaInfo(); - pageMeta.setGrailsApplication(grailsApplication); - pageMeta.setJspTagLibraryResolver(jspTagLibraryResolver); - pageMeta.setTagLibraryLookup(tagLibraryLookup); - pageMeta.setContentType(parse.getContentType()); - pageMeta.setLineNumbers(parse.getLineNumberMatrix()); - pageMeta.setJspTags(parse.getJspTags()); - - pageMeta.setStaticCodecName(parse.getStaticCodecDirectiveValue()); - pageMeta.setExpressionCodecName(parse.getExpressionCodecDirectiveValue()); - pageMeta.setOutCodecName(parse.getOutCodecDirectiveValue()); - pageMeta.setTaglibCodecName(parse.getTaglibCodecDirectiveValue()); - pageMeta.setCompileStaticMode(parse.isCompileStaticMode()); - pageMeta.setModelFieldsMode(parse.isModelFieldsMode()); - - pageMeta.initialize(); + GroovyPageMetaInfo pageMeta = new GroovyPageMetaInfo() + pageMeta.setGrailsApplication(grailsApplication) + pageMeta.setJspTagLibraryResolver(jspTagLibraryResolver) + pageMeta.setTagLibraryLookup(tagLibraryLookup) + pageMeta.setContentType(parse.getContentType()) + pageMeta.setLineNumbers(parse.getLineNumberMatrix()) + pageMeta.setJspTags(parse.getJspTags()) + + pageMeta.setStaticCodecName(parse.getStaticCodecDirectiveValue()) + pageMeta.setExpressionCodecName(parse.getExpressionCodecDirectiveValue()) + pageMeta.setOutCodecName(parse.getOutCodecDirectiveValue()) + pageMeta.setTaglibCodecName(parse.getTaglibCodecDirectiveValue()) + pageMeta.setCompileStaticMode(parse.isCompileStaticMode()) + pageMeta.setModelFieldsMode(parse.isModelFieldsMode()) + + pageMeta.initialize() // just return groovy and don't compile if asked if (GrailsUtil.isDevelopmentEnv()) { - pageMeta.setGroovySource(in); + pageMeta.setGroovySource(in) } if (dumpLineNumbersTo != null) { - String fileName = parse.getClassName() + GroovyPageMetaInfo.LINENUMBERS_DATA_POSTFIX; - File file = new File(dumpLineNumbersTo, fileName); + String fileName = parse.getClassName() + GroovyPageMetaInfo.LINENUMBERS_DATA_POSTFIX + File file = new File(dumpLineNumbersTo, fileName) try { - parse.writeLineNumbers(file); + parse.writeLineNumbers(file) } catch (IOException ignored) { if (file.exists()) { - file.delete(); + file.delete() } } } - return pageMeta; + return pageMeta } /** @@ -738,21 +724,21 @@ private GroovyPageMetaInfo createPageMetaInfo(GroovyPageParser parse, InputStrea */ protected String establishPageName(Resource res, String pageName) { if (res == null) { - return generateTemplateName(); + return generateTemplateName() } try { - String name = pageName != null ? pageName : res.getURL().getPath(); + String name = pageName != null ? pageName : res.getURL().getPath() // As the name take the first / off and then replace all characters that aren't // a word character or a digit with an underscore - if (name.startsWith("/")) name = name.substring(1); - return name.replaceAll("[^\\w\\d]", "_"); + if (name.startsWith('/')) name = name.substring(1) + return name.replaceAll('[^\\w\\d]', '_') } catch (IllegalStateException e) { - return generateTemplateName(); + return generateTemplateName() } catch (IOException ioex) { - return generateTemplateName(); + return generateTemplateName() } } @@ -762,7 +748,7 @@ protected String establishPageName(Resource res, String pageName) { * @return The template name */ private String generateTemplateName() { - return GENERATED_GSP_NAME_PREFIX + scriptNameCount.incrementAndGet(); + return GENERATED_GSP_NAME_PREFIX + scriptNameCount.incrementAndGet() } /** @@ -771,14 +757,14 @@ private String generateTemplateName() { * @param applicationContext The ApplicationContext * @throws BeansException Thrown when an error occurs with the ApplicationContext */ - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (applicationContext.containsBean(GrailsApplication.APPLICATION_ID)) { - this.grailsApplication = applicationContext.getBean(GrailsApplication.APPLICATION_ID, GrailsApplication.class); - Config config = grailsApplication.getConfig(); - this.gspEncoding = config.getProperty(GroovyPageParser.CONFIG_PROPERTY_GSP_ENCODING, System.getProperty("file.encoding", GroovyPageParser.DEFAULT_ENCODING)); + this.grailsApplication = applicationContext.getBean(GrailsApplication.APPLICATION_ID, GrailsApplication) + Config config = grailsApplication.getConfig() + this.gspEncoding = config.getProperty(GroovyPageParser.CONFIG_PROPERTY_GSP_ENCODING, System.getProperty('file.encoding', GroovyPageParser.DEFAULT_ENCODING)) } - this.observationRegistry = applicationContext.getBeanProvider(ObservationRegistry.class) - .getIfAvailable(() -> ObservationRegistry.NOOP); + this.observationRegistry = applicationContext.getBeanProvider(ObservationRegistry) + .getIfAvailable(() -> ObservationRegistry.NOOP) } /** @@ -788,56 +774,56 @@ public void setApplicationContext(ApplicationContext applicationContext) throws * @return The path of the URI within the Grails view directory */ protected String getUriWithinGrailsViews(String relativeUri) { - StringBuilder buf = new StringBuilder(); - String[] tokens; - if (relativeUri.startsWith("/")) { - relativeUri = relativeUri.substring(1); + StringBuilder buf = new StringBuilder() + String[] tokens + if (relativeUri.startsWith('/')) { + relativeUri = relativeUri.substring(1) } if (relativeUri.indexOf('/') > -1) { - tokens = relativeUri.split("/"); + tokens = relativeUri.split('/') } else { - tokens = new String[]{relativeUri}; + tokens = [relativeUri] as String[] } - buf.append(DefaultGroovyPageLocator.PATH_TO_WEB_INF_VIEWS); - for (String token : tokens) { - buf.append('/').append(token); + buf.append(DefaultGroovyPageLocator.PATH_TO_WEB_INF_VIEWS) + for (String token in tokens) { + buf.append('/').append(token) } if (!relativeUri.endsWith(GroovyPage.EXTENSION)) { - buf.append(GroovyPage.EXTENSION); + buf.append(GroovyPage.EXTENSION) } - return buf.toString(); + return buf.toString() } /** * Clears the page cache. Views will be re-compiled. */ - public void clearPageCache() { - for (Iterator>> it = pageCache.entrySet().iterator(); it.hasNext(); ) { - Map.Entry> entry = it.next(); - GroovyPageMetaInfo metaInfo = entry.getValue().getValue(); + void clearPageCache() { + for (Iterator>> it = pageCache.entrySet().iterator(); it.hasNext();) { + Map.Entry> entry = it.next() + GroovyPageMetaInfo metaInfo = entry.getValue().getValue() if (metaInfo != null) { - metaInfo.removePageMetaClass(); + metaInfo.removePageMetaClass() } - it.remove(); + it.remove() } } - public boolean isCacheResources() { - return cacheResources; + boolean isCacheResources() { + return cacheResources } - public void setCacheResources(boolean cacheResources) { - this.cacheResources = cacheResources; + void setCacheResources(boolean cacheResources) { + this.cacheResources = cacheResources } - public Map> getDomainClassMap() { + Map> getDomainClassMap() { if (cachedDomainsWithoutPackage != null) { - return cachedDomainsWithoutPackage; + return cachedDomainsWithoutPackage } - return createDomainClassMap(); + return createDomainClassMap() } /** @@ -848,27 +834,28 @@ public Map> getDomainClassMap() { * to prevent using the static cache that was used previously. */ private Map> createDomainClassMap() { - Map> domainsWithoutPackage = new HashMap<>(); + Map> domainsWithoutPackage = new HashMap<>() if (grailsApplication != null) { - GrailsClass[] domainClasses = grailsApplication.getArtefacts(DomainClassArtefactHandler.TYPE); - for (GrailsClass domainClass : domainClasses) { - final Class theClass = domainClass.getClazz(); - domainsWithoutPackage.put(theClass.getName(), theClass); + GrailsClass[] domainClasses = grailsApplication.getArtefacts(DomainClassArtefactHandler.TYPE) + for (GrailsClass domainClass in domainClasses) { + final Class theClass = domainClass.getClazz() + domainsWithoutPackage.put(theClass.getName(), theClass) } } - return domainsWithoutPackage; + return domainsWithoutPackage } @Override - public void setBeanClassLoader(ClassLoader beanClassLoader) { + void setBeanClassLoader(ClassLoader beanClassLoader) { // support passing BeanClassLoader as parent classloader for templates // don't set the classLoader field if it already has an explicit value if (beanClassLoader != null && this.classLoader == null) { - this.classLoader = beanClassLoader; + this.classLoader = beanClassLoader } } - public String getGspEncoding() { - return this.gspEncoding; + String getGspEncoding() { + return this.gspEncoding } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/ResourceAwareTemplateEngine.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/ResourceAwareTemplateEngine.groovy similarity index 55% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/ResourceAwareTemplateEngine.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/ResourceAwareTemplateEngine.groovy index 1d06d308987..f342ec7908c 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/ResourceAwareTemplateEngine.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/ResourceAwareTemplateEngine.groovy @@ -16,27 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp; +package org.grails.gsp -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.net.URL; +import groovy.text.Template +import groovy.text.TemplateEngine +import groovy.transform.CompileStatic +import org.codehaus.groovy.control.CompilationFailedException +import org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport +import org.springframework.core.io.Resource -import groovy.text.Template; -import groovy.text.TemplateEngine; -import org.codehaus.groovy.control.CompilationFailedException; -import org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport; - -import org.springframework.core.io.Resource; - -import grails.io.IOUtils; -import org.grails.buffer.StreamByteBuffer; +import grails.io.IOUtils +import org.grails.buffer.StreamByteBuffer /** * An abstract TemplateEngine that extends the default Groovy TemplateEngine (@see groovy.text.TemplateEngine) and @@ -45,9 +35,11 @@ * @author Graeme Rocher * @since 0.4 */ -public abstract class ResourceAwareTemplateEngine extends TemplateEngine { - public static final String BEAN_ID = "groovyPagesTemplateEngine"; - private static final String GROOVY_SOURCE_CHAR_ENCODING = "UTF-8"; +@CompileStatic +abstract class ResourceAwareTemplateEngine extends TemplateEngine { + + public static final String BEAN_ID = 'groovyPagesTemplateEngine' + private static final String GROOVY_SOURCE_CHAR_ENCODING = 'UTF-8' /** * Creates the specified Template using the given Spring Resource @@ -57,8 +49,8 @@ public abstract class ResourceAwareTemplateEngine extends TemplateEngine { * @throws IOException Thrown when there was an error reading the Template * @throws ClassNotFoundException Thrown when there was a problem loading the Template into a class */ - public Template createTemplate(Resource resource) throws IOException, ClassNotFoundException { - return createTemplateAndCloseInput(resource.getInputStream()); + Template createTemplate(Resource resource) throws IOException, ClassNotFoundException { + return createTemplateAndCloseInput(resource.getInputStream()) } /** @@ -69,13 +61,13 @@ public Template createTemplate(Resource resource) throws IOException, ClassNotFo * @return A Template instance * */ - public abstract Template createTemplate(Resource resource, boolean cacheable); + abstract Template createTemplate(Resource resource, boolean cacheable) @Override - public final Template createTemplate(Reader reader) throws IOException { - StreamByteBuffer buf = new StreamByteBuffer(); - IOUtils.copy(reader, new OutputStreamWriter(buf.getOutputStream(), GROOVY_SOURCE_CHAR_ENCODING)); - return createTemplate(buf.getInputStream()); + final Template createTemplate(Reader reader) throws IOException { + StreamByteBuffer buf = new StreamByteBuffer() + IOUtils.copy(reader, new OutputStreamWriter(buf.getOutputStream(), GROOVY_SOURCE_CHAR_ENCODING)) + return createTemplate(buf.getInputStream()) } /** @@ -86,32 +78,33 @@ public final Template createTemplate(Reader reader) throws IOException { * @return A Template instance * @throws IOException Thrown when an IO error occurs reading the stream */ - public abstract Template createTemplate(InputStream inputStream) throws IOException; + abstract Template createTemplate(InputStream inputStream) throws IOException @Override - public Template createTemplate(String templateText) throws CompilationFailedException, ClassNotFoundException, IOException { - return createTemplate(new ByteArrayInputStream(templateText.getBytes(GROOVY_SOURCE_CHAR_ENCODING))); + Template createTemplate(String templateText) throws CompilationFailedException, ClassNotFoundException, IOException { + return createTemplate(new ByteArrayInputStream(templateText.getBytes(GROOVY_SOURCE_CHAR_ENCODING))) } @Override - public Template createTemplate(File file) throws CompilationFailedException, ClassNotFoundException, IOException { - return createTemplateAndCloseInput(new FileInputStream(file)); + Template createTemplate(File file) throws CompilationFailedException, ClassNotFoundException, IOException { + return createTemplateAndCloseInput(new FileInputStream(file)) } @Override - public Template createTemplate(URL url) throws CompilationFailedException, ClassNotFoundException, IOException { - return createTemplateAndCloseInput(url.openStream()); + Template createTemplate(URL url) throws CompilationFailedException, ClassNotFoundException, IOException { + return createTemplateAndCloseInput(url.openStream()) } private Template createTemplateAndCloseInput(InputStream input) throws FileNotFoundException, IOException { try { - return createTemplate(input); + return createTemplate(input) } finally { - DefaultGroovyMethodsSupport.closeWithWarning(input); + DefaultGroovyMethodsSupport.closeWithWarning(input) } } - abstract public Template createTemplateForUri(String[] uris); + abstract Template createTemplateForUri(String[] uris) + + abstract int mapStackLineNumber(String url, int lineNumber) - abstract public int mapStackLineNumber(String url, int lineNumber); } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GSPWriter.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GSPWriter.groovy similarity index 55% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GSPWriter.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GSPWriter.groovy index fbd34264952..10a4ca9985a 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GSPWriter.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GSPWriter.groovy @@ -16,14 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler; +package org.grails.gsp.compiler -import java.io.PrintWriter; -import java.io.Writer; -import java.lang.reflect.Array; +import java.lang.reflect.Array -import grails.util.GrailsStringUtils; -import org.grails.gsp.GroovyPage; +import groovy.transform.CompileStatic + +import grails.util.GrailsStringUtils +import org.grails.gsp.GroovyPage /** * A PrintWriter used in the generation of GSP pages that allows printing to the target output @@ -31,79 +31,76 @@ * * @author Graeme Rocher */ -public class GSPWriter extends PrintWriter { +@CompileStatic +class GSPWriter extends PrintWriter { - private int lineNumber = 1; - private int[] lineNumbers = new int[1000]; + private int lineNumber = 1 + private int[] lineNumbers = new int[1000] //private static final Pattern LINE_BREAK = Pattern.compile("\\r\\n|\\n|\\r"); - private GroovyPageParser parse; + private GroovyPageParser parse - public GSPWriter(Writer out, GroovyPageParser parse) { - super(out); - this.parse = parse; + GSPWriter(Writer out, GroovyPageParser parse) { + super(out) + this.parse = parse } - @Override - public void write(char buf[], int off, int len) { - super.write(buf, off, len); + void printlnToResponse(String s) { + printlnToResponse(GroovyPage.OUT_STATEMENT, s) } - public void printlnToResponse(String s) { - printlnToResponse(GroovyPage.OUT_STATEMENT, s); - } - - public void printlnToResponse(String outVarName, String s) { + void printlnToResponse(String outVarName, String s) { if (!GrailsStringUtils.hasLength(s)) { - return; + return } - parse.flushTagBuffering(); - super.print(outVarName); - super.print(".print("); - super.print(s); - super.print(")"); - println(); + parse.flushTagBuffering() + super.print(outVarName) + super.print('.print(') + super.print(s) + super.print(')') + println() } - public void printlnToBuffer(String s, int index) { - if (s == null) s = "''"; - super.print("buf" + index + " << "); - super.print(s); - println(); + void printlnToBuffer(String s, int index) { + if (s == null) s = "''" + super.print('buf' + index + ' << ') + super.print(s) + println() } @Override - public void println() { - addLineNumber(); - super.println(); + void println() { + addLineNumber() + super.println() } private void addLineNumber() { if (lineNumber >= lineNumbers.length) { - lineNumbers = (int[]) resizeArray(lineNumbers, lineNumbers.length * 2); + lineNumbers = (int[]) resizeArray(lineNumbers, lineNumbers.length * 2) } else { - lineNumbers[lineNumber - 1] = parse.getCurrentOutputLineNumber(); - lineNumber++; + lineNumbers[lineNumber - 1] = parse.getCurrentOutputLineNumber() + lineNumber++ } } private Object resizeArray(Object oldArray, int newSize) { - int oldSize = java.lang.reflect.Array.getLength(oldArray); - Class elementType = oldArray.getClass().getComponentType(); - Object newArray = Array.newInstance(elementType, newSize); - int preserveLength = Math.min(oldSize, newSize); + int oldSize = java.lang.reflect.Array.getLength(oldArray) + Class elementType = oldArray.getClass().getComponentType() + Object newArray = Array.newInstance(elementType, newSize) + int preserveLength = Math.min(oldSize, newSize) if (preserveLength > 0) { - System.arraycopy(oldArray, 0, newArray, 0, preserveLength); + System.arraycopy(oldArray, 0, newArray, 0, preserveLength) } - return newArray; + return newArray } - public int getCurrentLineNumber() { - return lineNumber; + int getCurrentLineNumber() { + return lineNumber } - public int[] getLineNumbers() { - return lineNumbers; + int[] getLineNumbers() { + return lineNumbers } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GrailsLayoutPreprocessor.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GrailsLayoutPreprocessor.groovy similarity index 60% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GrailsLayoutPreprocessor.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GrailsLayoutPreprocessor.groovy index 8171511ece0..8c6ac380826 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GrailsLayoutPreprocessor.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GrailsLayoutPreprocessor.groovy @@ -16,11 +16,14 @@ * specific language governing permissions and limitations * under the License. */ +@SuppressWarnings('UnnecessarySemicolon') package org.grails.gsp.compiler; import java.util.regex.Matcher; import java.util.regex.Pattern; +import groovy.transform.CompileStatic; + /** * Adds GSP Grails Layout integration directly to compiled GSP. *

@@ -30,17 +33,20 @@ * * @author Lari Hotari, Sagire Software Oy */ -public class GrailsLayoutPreprocessor { +// TODO(groovyism-cleanup): semicolons kept to preserve rename-similarity against the original .java (see matrei's review on #16576). Removed by the stacked groovyism-cleanup PR. +@SuppressWarnings(['UnnecessarySemicolon']) +@CompileStatic +class GrailsLayoutPreprocessor { - Pattern parameterPattern = Pattern.compile("]+?)(/*?)>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); - Pattern metaPattern = Pattern.compile("]+?)(/*?)>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); - Pattern titlePattern = Pattern.compile("]*)?>(.*?)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); - Pattern headPattern = Pattern.compile("]*)?>(.*?)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); - Pattern bodyPattern = Pattern.compile("]*)?>(.*?)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); - Pattern contentPattern = Pattern.compile("]+)>(.*?)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); - public static final String XML_CLOSING_FOR_EMPTY_TAG_ATTRIBUTE_NAME = "gsp_sm_xmlClosingForEmptyTag"; + Pattern parameterPattern = Pattern.compile(']+?)(/*?)>', Pattern.CASE_INSENSITIVE | Pattern.DOTALL); + Pattern metaPattern = Pattern.compile(']+?)(/*?)>', Pattern.CASE_INSENSITIVE | Pattern.DOTALL); + Pattern titlePattern = Pattern.compile(']*)?>(.*?)', Pattern.CASE_INSENSITIVE | Pattern.DOTALL); + Pattern headPattern = Pattern.compile(']*)?>(.*?)', Pattern.CASE_INSENSITIVE | Pattern.DOTALL); + Pattern bodyPattern = Pattern.compile(']*)?>(.*?)', Pattern.CASE_INSENSITIVE | Pattern.DOTALL); + Pattern contentPattern = Pattern.compile(']+)>(.*?)', Pattern.CASE_INSENSITIVE | Pattern.DOTALL); + public static final String XML_CLOSING_FOR_EMPTY_TAG_ATTRIBUTE_NAME = 'gsp_sm_xmlClosingForEmptyTag'; - public String addGspGrailsLayoutCapturing(String gspSource) { + String addGspGrailsLayoutCapturing(String gspSource) { StringBuilder sb = addHeadCapturing(gspSource); sb = addBodyCapturing(sb); sb = addContentCapturing(sb); @@ -51,14 +57,14 @@ StringBuilder addHeadCapturing(String gspSource) { StringBuilder sb = new StringBuilder((int) (gspSource.length() * 1.2)); Matcher m = headPattern.matcher(gspSource); if (m.find()) { - m.appendReplacement(sb, ""); - sb.append(""); + sb.append('>'); sb.append(addMetaCapturing(addTitleCapturing(m.group(2)))); - sb.append(""); + sb.append(''); m.appendTail(sb); } else if (!bodyPattern.matcher(gspSource).find()) { // no body either, so replace meta & title in the entire gsp source @@ -73,23 +79,24 @@ StringBuilder addHeadCapturing(String gspSource) { String addMetaCapturing(String headContent) { Matcher m = metaPattern.matcher(headContent); final String result = parameterPattern.matcher( - m.replaceAll("") - ).replaceAll(""); + m.replaceAll('') + ).replaceAll(''); return result; } String addTitleCapturing(String headContent) { Matcher m = titlePattern.matcher(headContent); - return m.replaceAll("$2"); + return m.replaceAll('\$2'); } StringBuilder addBodyCapturing(StringBuilder sb) { Matcher m = bodyPattern.matcher(sb); - return new StringBuilder(m.replaceAll("$2")); + return new StringBuilder(m.replaceAll('\$2')); } StringBuilder addContentCapturing(StringBuilder sb) { Matcher m = contentPattern.matcher(sb); - return new StringBuilder(m.replaceAll("$2")); + return new StringBuilder(m.replaceAll('\$2')); } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageExpressionParser.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageExpressionParser.groovy similarity index 69% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageExpressionParser.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageExpressionParser.groovy index c65de488e29..f366d770b68 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageExpressionParser.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageExpressionParser.groovy @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler; +package org.grails.gsp.compiler -import java.util.Stack; +import groovy.transform.CompileStatic /** * Parses an expression in a GSP. @@ -27,30 +27,32 @@ * * @author Lari Hotari */ +@CompileStatic class GroovyPageExpressionParser { + private static enum ParsingState { - NORMAL, EXPRESSION, QUOTEDVALUE_SINGLE, QUOTEDVALUE_DOUBLE, TRIPLEQUOTED_SINGLE, TRIPLEQUOTED_DOUBLE; + NORMAL, EXPRESSION, QUOTEDVALUE_SINGLE, QUOTEDVALUE_DOUBLE, TRIPLEQUOTED_SINGLE, TRIPLEQUOTED_DOUBLE } - String scriptTokens; - int startPos; - char terminationChar; - char nextTerminationChar; - Stack parsingStateStack = new Stack<>(); - boolean containsGstrings = false; - int terminationCharPos = -1; - int relativeCharIndex = 0; + String scriptTokens + int startPos + char terminationChar + char nextTerminationChar + Stack parsingStateStack = new Stack<>() + boolean containsGstrings = false + int terminationCharPos = -1 + int relativeCharIndex = 0 - public GroovyPageExpressionParser(String scriptTokens, int startPos, char terminationChar, + GroovyPageExpressionParser(String scriptTokens, int startPos, char terminationChar, char nextTerminationChar, boolean startInExpression) { - this.scriptTokens = scriptTokens; - this.startPos = startPos; - this.terminationChar = terminationChar; - this.nextTerminationChar = nextTerminationChar; + this.scriptTokens = scriptTokens + this.startPos = startPos + this.terminationChar = terminationChar + this.nextTerminationChar = nextTerminationChar if (startInExpression) { - parsingStateStack.push(ParsingState.EXPRESSION); + parsingStateStack.push(ParsingState.EXPRESSION) } else { - parsingStateStack.push(ParsingState.NORMAL); + parsingStateStack.push(ParsingState.NORMAL) } } @@ -60,81 +62,82 @@ public GroovyPageExpressionParser(String scriptTokens, int startPos, char termin * @return end position of expression */ int parse() { - int currentPos = startPos; - char previousChar = 0; - char previousPreviousChar = 0; + int currentPos = startPos + char previousChar = 0 + char previousPreviousChar = 0 while (currentPos < scriptTokens.length() && terminationCharPos == -1) { - ParsingState parsingState = parsingStateStack.peek(); - char ch = scriptTokens.charAt(currentPos++); - char nextChar = (currentPos < scriptTokens.length()) ? scriptTokens.charAt(currentPos) : 0; + ParsingState parsingState = parsingStateStack.peek() + char ch = scriptTokens.charAt(currentPos++) + char nextChar = (currentPos < scriptTokens.length()) ? scriptTokens.charAt(currentPos) : (char) 0 if (parsingStateStack.size() == 1 && ch == terminationChar && (nextTerminationChar == 0 || nextTerminationChar == nextChar)) { - terminationCharPos = currentPos - 1; + terminationCharPos = currentPos - 1 } else if (parsingState == ParsingState.EXPRESSION || parsingState == ParsingState.NORMAL) { switch (ch) { case '{': if (previousChar == '$' && parsingState == ParsingState.EXPRESSION) { // invalid expression, starting new ${} expression inside expression - return -1; + return -1 } if (previousChar == '$' || parsingState == ParsingState.EXPRESSION) { - changeState(ParsingState.EXPRESSION); + changeState(ParsingState.EXPRESSION) } - break; + break case '[': if (relativeCharIndex == 0 || parsingState == ParsingState.EXPRESSION) { - changeState(ParsingState.EXPRESSION); + changeState(ParsingState.EXPRESSION) } - break; + break case '}': case ']': if (parsingState == ParsingState.EXPRESSION) { - parsingStateStack.pop(); + parsingStateStack.pop() } - break; + break case '\'': case '"': if (parsingState == ParsingState.EXPRESSION) { if (nextChar != ch && previousChar != ch) { - changeState(ch == '"' ? ParsingState.QUOTEDVALUE_DOUBLE : ParsingState.QUOTEDVALUE_SINGLE); + changeState(ch == '"' ? ParsingState.QUOTEDVALUE_DOUBLE : ParsingState.QUOTEDVALUE_SINGLE) } else if (previousChar == ch && previousPreviousChar == ch) { - changeState(ch == '"' ? ParsingState.TRIPLEQUOTED_DOUBLE : ParsingState.TRIPLEQUOTED_SINGLE); + changeState(ch == '"' ? ParsingState.TRIPLEQUOTED_DOUBLE : ParsingState.TRIPLEQUOTED_SINGLE) } } - break; + break } } else if (ch == '"' || ch == '\'') { if (nextChar != ch && (previousChar != ch || previousPreviousChar == '\\') && (previousChar != '\\' || (previousChar == '\\' && previousPreviousChar == '\\')) && ((parsingState == ParsingState.QUOTEDVALUE_DOUBLE && ch == '"') || (parsingState == ParsingState.QUOTEDVALUE_SINGLE && ch == '\''))) { - parsingStateStack.pop(); + parsingStateStack.pop() } else if ((previousChar == ch && previousPreviousChar == ch) && ((parsingState == ParsingState.TRIPLEQUOTED_DOUBLE && ch == '"') || (parsingState == ParsingState.TRIPLEQUOTED_SINGLE && ch == '\''))) { - parsingStateStack.pop(); + parsingStateStack.pop() } } - previousPreviousChar = previousChar; - previousChar = ch; - relativeCharIndex++; + previousPreviousChar = previousChar + previousChar = ch + relativeCharIndex++ } - return terminationCharPos; + return terminationCharPos } private void changeState(ParsingState newState) { - ParsingState currentState = parsingStateStack.peek(); + ParsingState currentState = parsingStateStack.peek() // check if expression contains GStrings if (relativeCharIndex > 1 && newState == ParsingState.EXPRESSION && (currentState == ParsingState.QUOTEDVALUE_DOUBLE || currentState == ParsingState.TRIPLEQUOTED_DOUBLE || currentState == ParsingState.NORMAL)) { - containsGstrings = true; + containsGstrings = true } - parsingStateStack.push(newState); + parsingStateStack.push(newState) } - public boolean isContainsGstrings() { - return containsGstrings; + boolean isContainsGstrings() { + return containsGstrings } - public int getTerminationCharPos() { - return terminationCharPos; + int getTerminationCharPos() { + return terminationCharPos } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageParser.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageParser.groovy similarity index 50% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageParser.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageParser.groovy index 1428b42f1b7..1690da4745b 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageParser.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageParser.groovy @@ -16,58 +16,33 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler; - -import java.io.BufferedOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; -import java.io.Writer; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.HexFormat; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Stack; -import java.util.TreeMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.codehaus.groovy.runtime.DefaultGroovyMethods; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import grails.config.ConfigMap; -import grails.io.IOUtils; -import grails.util.Environment; -import grails.util.GrailsStringUtils; -import org.grails.buffer.FastStringWriter; -import org.grails.buffer.StreamByteBuffer; -import org.grails.buffer.StreamCharBuffer; -import org.grails.gsp.CompileStaticGroovyPage; -import org.grails.gsp.GroovyPage; -import org.grails.gsp.ModelRecordingGroovyPage; -import org.grails.gsp.compiler.tags.GrailsTagRegistry; -import org.grails.gsp.compiler.tags.GroovySyntaxTag; -import org.grails.io.support.SpringIOUtils; -import org.grails.taglib.GrailsTagException; -import org.grails.taglib.encoder.OutputEncodingSettings; +package org.grails.gsp.compiler + +import java.security.MessageDigest +import java.security.NoSuchAlgorithmException +import java.util.regex.Matcher +import java.util.regex.Pattern + +import groovy.transform.CompileStatic +import org.codehaus.groovy.runtime.DefaultGroovyMethods +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import grails.config.ConfigMap +import grails.io.IOUtils +import grails.util.Environment +import grails.util.GrailsStringUtils +import org.grails.buffer.FastStringWriter +import org.grails.buffer.StreamByteBuffer +import org.grails.buffer.StreamCharBuffer +import org.grails.gsp.CompileStaticGroovyPage +import org.grails.gsp.GroovyPage +import org.grails.gsp.ModelRecordingGroovyPage +import org.grails.gsp.compiler.tags.GrailsTagRegistry +import org.grails.gsp.compiler.tags.GroovySyntaxTag +import org.grails.io.support.SpringIOUtils +import org.grails.taglib.GrailsTagException +import org.grails.taglib.encoder.OutputEncodingSettings /** * NOTE: Based on work done by the GSP standalone project (https://gsp.dev.java.net/). @@ -81,49 +56,50 @@ * @author Graeme Rocher * @author Lari Hotari */ -public class GroovyPageParser implements Tokens { +@CompileStatic +class GroovyPageParser implements Tokens { - private static final Logger LOG = LoggerFactory.getLogger(GroovyPageParser.class); + private static final Logger LOG = LoggerFactory.getLogger(GroovyPageParser) private static final Pattern PARA_BREAK = Pattern.compile( - "/p>\\s*]*>", Pattern.CASE_INSENSITIVE); + '/p>\\s*]*>', Pattern.CASE_INSENSITIVE) private static final Pattern ROW_BREAK = Pattern.compile( - "((/td>\\s*\\s*<)?tr[^>]*>\\s*<)?td[^>]*>", - Pattern.CASE_INSENSITIVE); + '((/td>\\s*\\s*<)?tr[^>]*>\\s*<)?td[^>]*>', + Pattern.CASE_INSENSITIVE) private static final Pattern PAGE_DIRECTIVE_PATTERN = Pattern.compile( - "(\\w+)\\s*=\\s*(\"\"\"|\"(?!\"\")|'''|'(?!''))(.*?)\\2", Pattern.DOTALL); - - private static final String TAGLIB_DIRECTIVE = "taglib"; - - private static final Pattern PRESCAN_PAGE_DIRECTIVE_PATTERN = Pattern.compile("<%@\\s*(?!" + TAGLIB_DIRECTIVE + " )(.*?)\\s*%>", Pattern.DOTALL); - private static final Pattern PRESCAN_COMMENT_PATTERN = Pattern.compile("<%--.*?--%>|%\\{--.*?--}%", Pattern.DOTALL); - private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s"); - private static final Pattern NON_WHITESPACE_PATTERN = Pattern.compile("\\S"); - private static final Pattern IMPORT_SEMICOLON_PATTERN = Pattern.compile(";"); - - public static final String CONSTANT_NAME_JSP_TAGS = "JSP_TAGS"; - public static final String CONSTANT_NAME_CONTENT_TYPE = "CONTENT_TYPE"; - public static final String CONSTANT_NAME_SOURCE_CHECKSUM = "SOURCE_CHECKSUM"; - public static final String CONSTANT_NAME_EXPRESSION_CODEC = "EXPRESSION_CODEC"; - public static final String CONSTANT_NAME_STATIC_CODEC = "STATIC_CODEC"; - public static final String CONSTANT_NAME_OUT_CODEC = "OUT_CODEC"; - public static final String CONSTANT_NAME_TAGLIB_CODEC = "TAGLIB_CODEC"; - public static final String CONSTANT_NAME_COMPILE_STATIC_MODE = "COMPILE_STATIC_MODE"; - public static final String CONSTANT_NAME_MODEL_FIELDS_MODE = "MODEL_FIELDS_MODE"; - public static final String DEFAULT_ENCODING = "UTF-8"; - - private static final String CHECKSUM_ALGORITHM = "SHA-256"; - - private static final String MULTILINE_GROOVY_STRING_DOUBLEQUOTES = "\"\"\""; - private static final String MULTILINE_GROOVY_STRING_SINGLEQUOTES = "'''"; - private static final String SET_TAG_NAME = "set"; - private static final String TYPE_ATTRIBUTE = "type"; - private static final String VAR_ATTRIBUTE = "var"; - - public static final String MODEL_DIRECTIVE = "model"; - public static final String COMPILE_STATIC_DIRECTIVE = "compileStatic"; - public static final String TAGLIBS_DIRECTIVE = "taglibs"; + "(\\w+)\\s*=\\s*(\"\"\"|\"(?!\"\")|'''|'(?!''))(.*?)\\2", Pattern.DOTALL) + + private static final String TAGLIB_DIRECTIVE = 'taglib' + + private static final Pattern PRESCAN_PAGE_DIRECTIVE_PATTERN = Pattern.compile('<%@\\s*(?!' + TAGLIB_DIRECTIVE + ' )(.*?)\\s*%>', Pattern.DOTALL) + private static final Pattern PRESCAN_COMMENT_PATTERN = Pattern.compile('<%--.*?--%>|%\\{--.*?--}%', Pattern.DOTALL) + private static final Pattern WHITESPACE_PATTERN = Pattern.compile('\\s') + private static final Pattern NON_WHITESPACE_PATTERN = Pattern.compile('\\S') + private static final Pattern IMPORT_SEMICOLON_PATTERN = Pattern.compile(';') + + public static final String CONSTANT_NAME_JSP_TAGS = 'JSP_TAGS' + public static final String CONSTANT_NAME_CONTENT_TYPE = 'CONTENT_TYPE' + public static final String CONSTANT_NAME_SOURCE_CHECKSUM = 'SOURCE_CHECKSUM' + public static final String CONSTANT_NAME_EXPRESSION_CODEC = 'EXPRESSION_CODEC' + public static final String CONSTANT_NAME_STATIC_CODEC = 'STATIC_CODEC' + public static final String CONSTANT_NAME_OUT_CODEC = 'OUT_CODEC' + public static final String CONSTANT_NAME_TAGLIB_CODEC = 'TAGLIB_CODEC' + public static final String CONSTANT_NAME_COMPILE_STATIC_MODE = 'COMPILE_STATIC_MODE' + public static final String CONSTANT_NAME_MODEL_FIELDS_MODE = 'MODEL_FIELDS_MODE' + public static final String DEFAULT_ENCODING = 'UTF-8' + + private static final String CHECKSUM_ALGORITHM = 'SHA-256' + + private static final String MULTILINE_GROOVY_STRING_DOUBLEQUOTES = '"""' + private static final String MULTILINE_GROOVY_STRING_SINGLEQUOTES = "'''" + private static final String SET_TAG_NAME = 'set' + private static final String TYPE_ATTRIBUTE = 'type' + private static final String VAR_ATTRIBUTE = 'var' + + public static final String MODEL_DIRECTIVE = 'model' + public static final String COMPILE_STATIC_DIRECTIVE = 'compileStatic' + public static final String TAGLIBS_DIRECTIVE = 'taglibs' /** * The names the framework binds into every page, and the type each holds. * @@ -133,123 +109,123 @@ public class GroovyPageParser implements Tokens { * they can be named here and not there. A page declaring one of these in its model gets its own * declaration and none of this, which is what lets it choose a different type.

*/ - private static final Map FRAMEWORK_SUPPLIED_TYPES; + private static final Map FRAMEWORK_SUPPLIED_TYPES static { - Map types = new LinkedHashMap<>(); - types.put("params", "grails.util.TypeConvertingMap"); - types.put("flash", "grails.web.mvc.FlashScope"); - types.put("request", "jakarta.servlet.http.HttpServletRequest"); - types.put("response", "jakarta.servlet.http.HttpServletResponse"); - types.put("session", "jakarta.servlet.http.HttpSession"); - types.put("application", "jakarta.servlet.ServletContext"); - types.put("servletContext", "jakarta.servlet.ServletContext"); - types.put("webRequest", "org.grails.web.servlet.mvc.GrailsWebRequest"); - types.put("controllerName", "java.lang.String"); - types.put("actionName", "java.lang.String"); - types.put("namespace", "java.lang.String"); - FRAMEWORK_SUPPLIED_TYPES = Collections.unmodifiableMap(types); - } - - public static final List DEFAULT_TAGLIB_NAMESPACES = Collections.unmodifiableList(Arrays.asList(new String[]{"g", "tmpl", "f", "asset", "plugin"})); - - private GroovyPageScanner scan; - private GSPWriter out; - private String className; - private String packageName; - private String sourceName; // last segment of the file name (eg- index.gsp) - private boolean finalPass = false; - private int tagIndex; - private Map tagContext; - private Stack tagMetaStack = new Stack<>(); - private GrailsTagRegistry tagRegistry = GrailsTagRegistry.getInstance(); - private Environment environment; - private List htmlParts = new ArrayList<>(); - private static GrailsLayoutPreprocessor grailsLayoutPreprocessor = new GrailsLayoutPreprocessor(); - - Set bodyVarsDefined = new HashSet<>(); - Map attrsVarsMapDefinition = new HashMap<>(); - - int closureLevel = 0; + Map types = new LinkedHashMap<>() + types.put('params', 'grails.util.TypeConvertingMap') + types.put('flash', 'grails.web.mvc.FlashScope') + types.put('request', 'jakarta.servlet.http.HttpServletRequest') + types.put('response', 'jakarta.servlet.http.HttpServletResponse') + types.put('session', 'jakarta.servlet.http.HttpSession') + types.put('application', 'jakarta.servlet.ServletContext') + types.put('servletContext', 'jakarta.servlet.ServletContext') + types.put('webRequest', 'org.grails.web.servlet.mvc.GrailsWebRequest') + types.put('controllerName', 'java.lang.String') + types.put('actionName', 'java.lang.String') + types.put('namespace', 'java.lang.String') + FRAMEWORK_SUPPLIED_TYPES = Collections.unmodifiableMap(types) + } + + public static final List DEFAULT_TAGLIB_NAMESPACES = Collections.unmodifiableList(Arrays.asList(['g', 'tmpl', 'f', 'asset', 'plugin'] as String[])) + + private GroovyPageScanner scan + private GSPWriter out + private String className + private String packageName + private String sourceName // last segment of the file name (eg- index.gsp) + private boolean finalPass = false + private int tagIndex + private Map tagContext + private Stack tagMetaStack = new Stack<>() + private GrailsTagRegistry tagRegistry = GrailsTagRegistry.getInstance() + private Environment environment + private List htmlParts = new ArrayList<>() + private static GrailsLayoutPreprocessor grailsLayoutPreprocessor = new GrailsLayoutPreprocessor() + + Set bodyVarsDefined = new HashSet<>() + Map attrsVarsMapDefinition = new HashMap<>() + + int closureLevel = 0 /* * Set to true when whitespace is currently being saved for later output if * the next tag isn't set to swallow it */ - private boolean currentlyBufferingWhitespace; + private boolean currentlyBufferingWhitespace /* * Set to true if the last output was not whitespace, so that we can detect * when a tag has illegal content before it */ - private boolean previousContentWasNonWhitespace; - - private StringBuffer whitespaceBuffer = new StringBuffer(); - - private String contentType = DEFAULT_CONTENT_TYPE; - private boolean doNextScan = true; - private int state; - private static final String DEFAULT_CONTENT_TYPE = "text/html;charset=UTF-8"; - private int constantCount = 0; - private Map constantsToNumbers = new HashMap<>(); - - private final String pageName; - public static final String[] DEFAULT_IMPORTS = { - "grails.plugins.metadata.GrailsPlugin", - "org.grails.gsp.compiler.transform.LineNumber", - "org.grails.gsp.GroovyPage", - "org.grails.web.taglib.*", - "org.grails.taglib.GrailsTagException", - "org.springframework.web.util.*", - "grails.util.GrailsUtil" - }; - public static final String CONFIG_PROPERTY_DEFAULT_CODEC = "grails.views.default.codec"; - public static final String CONFIG_PROPERTY_GSP_ENCODING = "grails.views.gsp.encoding"; - public static final String CONFIG_PROPERTY_GSP_KEEPGENERATED_DIR = "grails.views.gsp.keepgenerateddir"; - public static final String CONFIG_PROPERTY_GSP_GRAILS_LAYOUT_PREPROCESS = "grails.views.gsp.layout.preprocess"; - public static final String CONFIG_PROPERTY_GSP_COMPILESTATIC = "grails.views.gsp.compileStatic"; - public static final String CONFIG_PROPERTY_GSP_ALLOWED_TAGLIB_NAMESPACES = "grails.views.gsp.compileStaticConfig.taglibs"; - public static final String CONFIG_PROPERTY_GSP_COMPILESTATIC_STRICT = "grails.views.gsp.compileStaticConfig.strict"; - public static final String CONFIG_PROPERTY_GSP_CODECS = "grails.views.gsp.codecs"; - - private static final String IMPORT_DIRECTIVE = "import"; - private static final String CONTENT_TYPE_DIRECTIVE = "contentType"; - public static final String CODEC_DIRECTIVE_POSTFIX = "Codec"; - private static final String EXPRESSION_CODEC_DIRECTIVE = OutputEncodingSettings.EXPRESSION_CODEC_NAME + CODEC_DIRECTIVE_POSTFIX; - private static final String EXPRESSION_CODEC_DIRECTIVE_ALIAS = "default" + CODEC_DIRECTIVE_POSTFIX; - private static final String STATIC_CODEC_DIRECTIVE = OutputEncodingSettings.STATIC_CODEC_NAME + CODEC_DIRECTIVE_POSTFIX; - private static final String OUT_CODEC_DIRECTIVE = OutputEncodingSettings.OUT_CODEC_NAME + CODEC_DIRECTIVE_POSTFIX; - private static final String TAGLIB_CODEC_DIRECTIVE = OutputEncodingSettings.TAGLIB_CODEC_NAME + CODEC_DIRECTIVE_POSTFIX; - private static final String GRAILS_LAYOUT_PREPROCESS_DIRECTIVE = "grailsLayoutPreprocess"; + private boolean previousContentWasNonWhitespace + + private StringBuffer whitespaceBuffer = new StringBuffer() + + private String contentType = DEFAULT_CONTENT_TYPE + private boolean doNextScan = true + private int state + private static final String DEFAULT_CONTENT_TYPE = 'text/html;charset=UTF-8' + private int constantCount = 0 + private Map constantsToNumbers = new HashMap<>() + + private final String pageName + public static final String[] DEFAULT_IMPORTS = [ + 'grails.plugins.metadata.GrailsPlugin', + 'org.grails.gsp.compiler.transform.LineNumber', + 'org.grails.gsp.GroovyPage', + 'org.grails.web.taglib.*', + 'org.grails.taglib.GrailsTagException', + 'org.springframework.web.util.*', + 'grails.util.GrailsUtil' + ] as String[] + public static final String CONFIG_PROPERTY_DEFAULT_CODEC = 'grails.views.default.codec' + public static final String CONFIG_PROPERTY_GSP_ENCODING = 'grails.views.gsp.encoding' + public static final String CONFIG_PROPERTY_GSP_KEEPGENERATED_DIR = 'grails.views.gsp.keepgenerateddir' + public static final String CONFIG_PROPERTY_GSP_GRAILS_LAYOUT_PREPROCESS = 'grails.views.gsp.layout.preprocess' + public static final String CONFIG_PROPERTY_GSP_COMPILESTATIC = 'grails.views.gsp.compileStatic' + public static final String CONFIG_PROPERTY_GSP_ALLOWED_TAGLIB_NAMESPACES = 'grails.views.gsp.compileStaticConfig.taglibs' + public static final String CONFIG_PROPERTY_GSP_COMPILESTATIC_STRICT = 'grails.views.gsp.compileStaticConfig.strict' + public static final String CONFIG_PROPERTY_GSP_CODECS = 'grails.views.gsp.codecs' + + private static final String IMPORT_DIRECTIVE = 'import' + private static final String CONTENT_TYPE_DIRECTIVE = 'contentType' + public static final String CODEC_DIRECTIVE_POSTFIX = 'Codec' + private static final String EXPRESSION_CODEC_DIRECTIVE = OutputEncodingSettings.EXPRESSION_CODEC_NAME + CODEC_DIRECTIVE_POSTFIX + private static final String EXPRESSION_CODEC_DIRECTIVE_ALIAS = 'default' + CODEC_DIRECTIVE_POSTFIX + private static final String STATIC_CODEC_DIRECTIVE = OutputEncodingSettings.STATIC_CODEC_NAME + CODEC_DIRECTIVE_POSTFIX + private static final String OUT_CODEC_DIRECTIVE = OutputEncodingSettings.OUT_CODEC_NAME + CODEC_DIRECTIVE_POSTFIX + private static final String TAGLIB_CODEC_DIRECTIVE = OutputEncodingSettings.TAGLIB_CODEC_NAME + CODEC_DIRECTIVE_POSTFIX + private static final String GRAILS_LAYOUT_PREPROCESS_DIRECTIVE = 'grailsLayoutPreprocess' /** * The page directive by which a page asks that the lines holding only directives, scriptlets and * comments write nothing, for a page rendering text in which every line break counts. */ - private static final String TRIM_LOGIC_LINES_DIRECTIVE = "trimLogicLines"; - - private String pluginAnnotation; - public static final String GROOVY_SOURCE_CHAR_ENCODING = "UTF-8"; - private Map jspTags = new HashMap<>(); - private String sourceChecksum; - private boolean precompileMode; - private Boolean compileStaticMode; - private boolean modelFieldsMode; - private boolean grailsLayoutPreprocessMode = false; - private String expressionCodecDirectiveValue = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.EXPRESSION_CODEC_NAME); - private String outCodecDirectiveValue = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.OUT_CODEC_NAME); - private String staticCodecDirectiveValue = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.STATIC_CODEC_NAME); - private String taglibCodecDirectiveValue = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.TAGLIB_CODEC_NAME); - private String modelDirectiveValue; - - private boolean enableGrailsLayoutProcessing = true; - private File keepGeneratedDirectory; - private Set allowedTaglibNamespaces = new LinkedHashSet<>(DEFAULT_TAGLIB_NAMESPACES); + private static final String TRIM_LOGIC_LINES_DIRECTIVE = 'trimLogicLines' + + private String pluginAnnotation + public static final String GROOVY_SOURCE_CHAR_ENCODING = 'UTF-8' + private Map jspTags = new HashMap<>() + private String sourceChecksum + private boolean precompileMode + private Boolean compileStaticMode + private boolean modelFieldsMode + private boolean grailsLayoutPreprocessMode = false + private String expressionCodecDirectiveValue = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.EXPRESSION_CODEC_NAME) + private String outCodecDirectiveValue = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.OUT_CODEC_NAME) + private String staticCodecDirectiveValue = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.STATIC_CODEC_NAME) + private String taglibCodecDirectiveValue = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.TAGLIB_CODEC_NAME) + private String modelDirectiveValue + + private boolean enableGrailsLayoutProcessing = true + private File keepGeneratedDirectory + private Set allowedTaglibNamespaces = new LinkedHashSet<>(DEFAULT_TAGLIB_NAMESPACES) /** * The {@code var} and {@code status} attributes of the tags this page calls, which are the names * the page introduces for itself. */ - private final Set pageScopeVariables = new LinkedHashSet<>(); + private final Set pageScopeVariables = new LinkedHashSet<>() /** * The names a typed {@code g:set} has declared, one frame per block the page emits. @@ -258,88 +234,88 @@ public class GroovyPageParser implements Tokens { * Frames rather than a flat set because two sibling blocks are two scopes: a name declared in one * is not in scope in the other, so assigning there would write to a variable that does not exist. */ - private final Deque> typedSetScopes = new ArrayDeque<>( - Collections.singletonList(new LinkedHashSet<>())); + private final Deque> typedSetScopes = new ArrayDeque>( + Collections.singletonList(new LinkedHashSet())) /** Whether what a page never declared fails the compilation rather than resolving at render time. */ - private boolean compileStaticStrict; + private boolean compileStaticStrict - public String getContentType() { - return contentType; + String getContentType() { + return contentType } - public int getCurrentOutputLineNumber() { - return scan.getLineNumberForToken(); + int getCurrentOutputLineNumber() { + return scan.getLineNumberForToken() } - public Map getJspTags() { - return jspTags; + Map getJspTags() { + return jspTags } - public void setKeepGeneratedDirectory(File keepGeneratedDirectory) { - this.keepGeneratedDirectory = keepGeneratedDirectory; + void setKeepGeneratedDirectory(File keepGeneratedDirectory) { + this.keepGeneratedDirectory = keepGeneratedDirectory } - public void setEnableGrailsLayoutProcessing(boolean enableGrailsLayoutProcessing) { - this.enableGrailsLayoutProcessing = enableGrailsLayoutProcessing; + void setEnableGrailsLayoutProcessing(boolean enableGrailsLayoutProcessing) { + this.enableGrailsLayoutProcessing = enableGrailsLayoutProcessing } class TagMeta { - String name; - String namespace; - Object instance; - boolean isDynamic; - boolean hasAttributes; - int lineNumber; - boolean emptyTag; - int tagIndex; - boolean bufferMode = false; - int bufferPartNumber = -1; + String name + String namespace + Object instance + boolean isDynamic + boolean hasAttributes + int lineNumber + boolean emptyTag + int tagIndex + boolean bufferMode = false + int bufferPartNumber = -1 @Override - public String toString() { - return "<" + namespace + ":" + name + ">"; + String toString() { + return '<' + namespace + ':' + name + '>' } } - public GroovyPageParser(String name, String uri, String filename, InputStream in, String encoding, String expressionCodecName, ConfigMap configMap) throws IOException { - this(name, uri, filename, readStream(in, encoding), expressionCodecName, configMap); + GroovyPageParser(String name, String uri, String filename, InputStream in, String encoding, String expressionCodecName, ConfigMap configMap) throws IOException { + this(name, uri, filename, readStream(in, encoding), expressionCodecName, configMap) } - public GroovyPageParser(String name, String uri, String filename, String gspSource, ConfigMap configMap) throws IOException { - this(name, uri, filename, gspSource, null, configMap); + GroovyPageParser(String name, String uri, String filename, String gspSource, ConfigMap configMap) throws IOException { + this(name, uri, filename, gspSource, null, configMap) } - public GroovyPageParser(String name, String uri, String filename, InputStream in, ConfigMap configMap) throws IOException { - this(name, uri, filename, in, null, null, configMap); + GroovyPageParser(String name, String uri, String filename, InputStream in, ConfigMap configMap) throws IOException { + this(name, uri, filename, in, null, null, configMap) } - public GroovyPageParser(String name, String uri, String filename, String gspSource, String expressionCodecName, ConfigMap configMap) throws IOException { - this.expressionCodecDirectiveValue = expressionCodecName; + GroovyPageParser(String name, String uri, String filename, String gspSource, String expressionCodecName, ConfigMap configMap) throws IOException { + this.expressionCodecDirectiveValue = expressionCodecName if (expressionCodecDirectiveValue == null) { - expressionCodecDirectiveValue = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.EXPRESSION_CODEC_NAME); + expressionCodecDirectiveValue = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.EXPRESSION_CODEC_NAME) } if (configMap != null) { - configure(configMap); + configure(configMap) } - applyCompileStaticSystemProperty(); + applyCompileStaticSystemProperty() - Map directives = parseDirectives(gspSource); + Map directives = parseDirectives(gspSource) if (GrailsStringUtils.toBoolean(directives.get(TRIM_LOGIC_LINES_DIRECTIVE))) { - gspSource = LogicLineTrimmer.trim(gspSource); + gspSource = LogicLineTrimmer.trim(gspSource) } if (isGrailsLayoutPreprocessingEnabled(directives.get(GRAILS_LAYOUT_PREPROCESS_DIRECTIVE))) { // GSP preprocessing for direct grails layout integration: replace head -> g:captureHead, title -> g:captureTitle, meta -> g:captureMeta, body -> g:captureBody - gspSource = grailsLayoutPreprocessor.addGspGrailsLayoutCapturing(gspSource); - grailsLayoutPreprocessMode = true; + gspSource = grailsLayoutPreprocessor.addGspGrailsLayoutCapturing(gspSource) + grailsLayoutPreprocessMode = true } - collectPageScopeVariables(gspSource); - scan = new GroovyPageScanner(gspSource, uri); - pageName = uri; - environment = Environment.getCurrent(); - makeName(name); - makeSourceName(filename); + collectPageScopeVariables(gspSource) + scan = new GroovyPageScanner(gspSource, uri) + pageName = uri + environment = Environment.getCurrent() + makeName(name) + makeSourceName(filename) } /** @@ -349,7 +325,7 @@ public GroovyPageParser(String name, String uri, String filename, String gspSour * @param gspSource the page source */ private void collectPageScopeVariables(String gspSource) { - PageScopeVariableScanner.collect(gspSource, pageScopeVariables); + PageScopeVariableScanner.collect(gspSource, pageScopeVariables) } /** @@ -368,13 +344,13 @@ private void collectPageScopeVariables(String gspSource) { * read afterwards and still decides for the page that carries it.

*/ private void applyCompileStaticSystemProperty() { - String value = System.getProperty(CONFIG_PROPERTY_GSP_COMPILESTATIC); + String value = System.getProperty(CONFIG_PROPERTY_GSP_COMPILESTATIC) if (!GrailsStringUtils.isBlank(value)) { - compileStaticMode = GrailsStringUtils.toBoolean(value.trim()); + compileStaticMode = GrailsStringUtils.toBoolean(value.trim()) } - String strict = System.getProperty(CONFIG_PROPERTY_GSP_COMPILESTATIC_STRICT); + String strict = System.getProperty(CONFIG_PROPERTY_GSP_COMPILESTATIC_STRICT) if (!GrailsStringUtils.isBlank(strict)) { - compileStaticStrict = GrailsStringUtils.toBoolean(strict.trim()); + compileStaticStrict = GrailsStringUtils.toBoolean(strict.trim()) } } @@ -384,305 +360,305 @@ private void applyCompileStaticSystemProperty() { * @param config The config map */ private void configure(ConfigMap config) { - compileStaticMode = config.getProperty(GroovyPageParser.CONFIG_PROPERTY_GSP_COMPILESTATIC, Boolean.class); - compileStaticStrict = config.getProperty(CONFIG_PROPERTY_GSP_COMPILESTATIC_STRICT, Boolean.class, Boolean.FALSE); + compileStaticMode = config.getProperty(GroovyPageParser.CONFIG_PROPERTY_GSP_COMPILESTATIC, Boolean) + compileStaticStrict = config.getProperty(CONFIG_PROPERTY_GSP_COMPILESTATIC_STRICT, Boolean, Boolean.FALSE) - Object allowedTagLibsConfigValue = config.getProperty(CONFIG_PROPERTY_GSP_ALLOWED_TAGLIB_NAMESPACES, Object.class); + Object allowedTagLibsConfigValue = config.getProperty(CONFIG_PROPERTY_GSP_ALLOWED_TAGLIB_NAMESPACES, Object) if (allowedTagLibsConfigValue instanceof Iterable) { - for (Object val : ((Iterable) allowedTagLibsConfigValue)) { - allowedTaglibNamespaces.add(String.valueOf(val).trim()); + for (Object val in ((Iterable) allowedTagLibsConfigValue)) { + allowedTaglibNamespaces.add(String.valueOf(val).trim()) } } else if (allowedTagLibsConfigValue instanceof CharSequence) { - allowedTaglibNamespaces.addAll(Arrays.asList(allowedTagLibsConfigValue.toString().split("\\s*,\\s*"))); + allowedTaglibNamespaces.addAll(Arrays.asList(allowedTagLibsConfigValue.toString().split('\\s*,\\s*'))) } setEnableGrailsLayoutProcessing( - config.getProperty(GroovyPageParser.CONFIG_PROPERTY_GSP_GRAILS_LAYOUT_PREPROCESS, Boolean.class, true) - ); + config.getProperty(GroovyPageParser.CONFIG_PROPERTY_GSP_GRAILS_LAYOUT_PREPROCESS, Boolean, true) + ) setExpressionCodecDirectiveValue( - config.getProperty(OutputEncodingSettings.CONFIG_PROPERTY_GSP_CODECS + '.' + OutputEncodingSettings.EXPRESSION_CODEC_NAME, String.class, - config.getProperty(OutputEncodingSettings.CONFIG_PROPERTY_DEFAULT_CODEC, String.class, OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.EXPRESSION_CODEC_NAME))) - ); + config.getProperty(OutputEncodingSettings.CONFIG_PROPERTY_GSP_CODECS + '.' + OutputEncodingSettings.EXPRESSION_CODEC_NAME, String, + config.getProperty(OutputEncodingSettings.CONFIG_PROPERTY_DEFAULT_CODEC, String, OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.EXPRESSION_CODEC_NAME))) + ) setStaticCodecDirectiveValue( - config.getProperty(OutputEncodingSettings.CONFIG_PROPERTY_GSP_CODECS + '.' + OutputEncodingSettings.STATIC_CODEC_NAME, String.class, OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.STATIC_CODEC_NAME)) - ); + config.getProperty(OutputEncodingSettings.CONFIG_PROPERTY_GSP_CODECS + '.' + OutputEncodingSettings.STATIC_CODEC_NAME, String, OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.STATIC_CODEC_NAME)) + ) setTaglibCodecDirectiveValue( - config.getProperty(OutputEncodingSettings.CONFIG_PROPERTY_GSP_CODECS + '.' + OutputEncodingSettings.TAGLIB_CODEC_NAME, String.class, OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.TAGLIB_CODEC_NAME)) - ); + config.getProperty(OutputEncodingSettings.CONFIG_PROPERTY_GSP_CODECS + '.' + OutputEncodingSettings.TAGLIB_CODEC_NAME, String, OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.TAGLIB_CODEC_NAME)) + ) setOutCodecDirectiveValue( - config.getProperty(OutputEncodingSettings.CONFIG_PROPERTY_GSP_CODECS + '.' + OutputEncodingSettings.OUT_CODEC_NAME, String.class, OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.OUT_CODEC_NAME)) - ); + config.getProperty(OutputEncodingSettings.CONFIG_PROPERTY_GSP_CODECS + '.' + OutputEncodingSettings.OUT_CODEC_NAME, String, OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.OUT_CODEC_NAME)) + ) - Object keepDirObj = config.getProperty(GroovyPageParser.CONFIG_PROPERTY_GSP_KEEPGENERATED_DIR, Object.class); + Object keepDirObj = config.getProperty(GroovyPageParser.CONFIG_PROPERTY_GSP_KEEPGENERATED_DIR, Object) if (keepDirObj instanceof File) { - setKeepGeneratedDirectory((File) keepDirObj); + setKeepGeneratedDirectory((File) keepDirObj) } else if (keepDirObj != null) { - setKeepGeneratedDirectory(new File(String.valueOf(keepDirObj))); + setKeepGeneratedDirectory(new File(String.valueOf(keepDirObj))) } } private Map parseDirectives(String gspSource) { - Map result = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + Map result = new TreeMap<>(String.CASE_INSENSITIVE_ORDER) // strip gsp comments - String input = PRESCAN_COMMENT_PATTERN.matcher(gspSource).replaceAll(""); + String input = PRESCAN_COMMENT_PATTERN.matcher(gspSource).replaceAll('') // find page directives - Matcher m = PRESCAN_PAGE_DIRECTIVE_PATTERN.matcher(input); + Matcher m = PRESCAN_PAGE_DIRECTIVE_PATTERN.matcher(input) while (m.find()) { - Matcher mat = PAGE_DIRECTIVE_PATTERN.matcher(m.group(1)); + Matcher mat = PAGE_DIRECTIVE_PATTERN.matcher(m.group(1)) while (mat.find()) { - String name = mat.group(1); - String value = mat.group(3).trim(); + String name = mat.group(1) + String value = mat.group(3).trim() // Match directPage: later settings replace earlier ones. - result.put(name, value); + result.put(name, value) } } - return result; + return result } private boolean isGrailsLayoutPreprocessingEnabled(String gspFilePreprocessDirective) { if (gspFilePreprocessDirective != null) { - return GrailsStringUtils.toBoolean(gspFilePreprocessDirective.trim()); + return GrailsStringUtils.toBoolean(gspFilePreprocessDirective.trim()) } - return enableGrailsLayoutProcessing; + return enableGrailsLayoutProcessing } - public int[] getLineNumberMatrix() { - return out.getLineNumbers(); + int[] getLineNumberMatrix() { + return out.getLineNumbers() } - public String getClassName() { - return className; + String getClassName() { + return className } - public void setClassName(String className) { - this.className = className; + void setClassName(String className) { + this.className = className } - public String getPackageName() { - return packageName; + String getPackageName() { + return packageName } - public void setPackageName(String packageName) { - this.packageName = packageName; + void setPackageName(String packageName) { + this.packageName = packageName } - public InputStream parse() { - resolveKeepGeneratedDirectory(); + InputStream parse() { + resolveKeepGeneratedDirectory() - StreamCharBuffer streamBuffer = new StreamCharBuffer(1024); + StreamCharBuffer streamBuffer = new StreamCharBuffer(1024) StreamByteBuffer byteOutputBuffer = new StreamByteBuffer(1024, - StreamByteBuffer.ReadMode.RETAIN_AFTER_READING); + StreamByteBuffer.ReadMode.RETAIN_AFTER_READING) try { streamBuffer.connectTo(new OutputStreamWriter(byteOutputBuffer.getOutputStream(), - GROOVY_SOURCE_CHAR_ENCODING), true); + GROOVY_SOURCE_CHAR_ENCODING), true) } catch (UnsupportedEncodingException e) { - throw new RuntimeException("Grails cannot run unless your environment supports UTF-8!"); + throw new RuntimeException('Grails cannot run unless your environment supports UTF-8!') } - File keepGeneratedFile = null; - Writer keepGeneratedWriter = null; + File keepGeneratedFile = null + Writer keepGeneratedWriter = null if (keepGeneratedDirectory != null) { - keepGeneratedFile = new File(keepGeneratedDirectory, className); + keepGeneratedFile = new File(keepGeneratedDirectory, className) try { keepGeneratedWriter = new OutputStreamWriter( new FileOutputStream(keepGeneratedFile), - GROOVY_SOURCE_CHAR_ENCODING); + GROOVY_SOURCE_CHAR_ENCODING) } catch (IOException e) { - LOG.warn("Cannot open keepgenerated file for writing. File's absolute path is '{}'", keepGeneratedFile.getAbsolutePath()); - keepGeneratedFile = null; + LOG.warn("Cannot open keepgenerated file for writing. File's absolute path is '{}'", keepGeneratedFile.getAbsolutePath()) + keepGeneratedFile = null } - streamBuffer.connectTo(keepGeneratedWriter, true); + streamBuffer.connectTo(keepGeneratedWriter, true) } - Writer target = streamBuffer.getWriter(); + Writer target = streamBuffer.getWriter() try { - generateGsp(target, false); - return byteOutputBuffer.getInputStream(); + generateGsp(target, false) + return byteOutputBuffer.getInputStream() } finally { - SpringIOUtils.closeQuietly(keepGeneratedWriter); + SpringIOUtils.closeQuietly(keepGeneratedWriter) } } private void resolveKeepGeneratedDirectory() { if (keepGeneratedDirectory != null && !keepGeneratedDirectory.isDirectory()) { - LOG.warn("The directory specified with {} config parameter doesn't exist or isn't a readable directory. Absolute path: '{}' Keepgenerated will be disabled.", CONFIG_PROPERTY_GSP_KEEPGENERATED_DIR, keepGeneratedDirectory.getAbsolutePath()); - keepGeneratedDirectory = null; + LOG.warn("The directory specified with {} config parameter doesn't exist or isn't a readable directory. Absolute path: '{}' Keepgenerated will be disabled.", CONFIG_PROPERTY_GSP_KEEPGENERATED_DIR, keepGeneratedDirectory.getAbsolutePath()) + keepGeneratedDirectory = null } } - public void generateGsp(Writer target) { - generateGsp(target, true); + void generateGsp(Writer target) { + generateGsp(target, true) } - public void generateGsp(Writer target, boolean precompileMode) { - this.precompileMode = precompileMode; + void generateGsp(Writer target, boolean precompileMode) { + this.precompileMode = precompileMode - out = new GSPWriter(target, this); + out = new GSPWriter(target, this) if (packageName != null && packageName.length() > 0) { - out.println("package " + packageName); - out.println(); + out.println('package ' + packageName) + out.println() } - page(); - finalPass = true; - scan.reset(); - previousContentWasNonWhitespace = false; - currentlyBufferingWhitespace = false; - page(); + page() + finalPass = true + scan.reset() + previousContentWasNonWhitespace = false + currentlyBufferingWhitespace = false + page() - out.close(); - scan = null; + out.close() + scan = null } - public void writeHtmlParts(File filename) throws IOException { - DataOutputStream dataOut = null; + void writeHtmlParts(File filename) throws IOException { + DataOutputStream dataOut = null try { dataOut = new DataOutputStream(new BufferedOutputStream( - new FileOutputStream(filename))); - dataOut.writeInt(htmlParts.size()); - for (String part : htmlParts) { - dataOut.writeUTF(part); + new FileOutputStream(filename))) + dataOut.writeInt(htmlParts.size()) + for (String part in htmlParts) { + dataOut.writeUTF(part) } } finally { - SpringIOUtils.closeQuietly(dataOut); + SpringIOUtils.closeQuietly(dataOut) } } - public void writeLineNumbers(File filename) throws IOException { - DataOutputStream dataOut = null; + void writeLineNumbers(File filename) throws IOException { + DataOutputStream dataOut = null try { dataOut = new DataOutputStream(new BufferedOutputStream( - new FileOutputStream(filename))); - int lineNumbersCount = out.getCurrentLineNumber() - 1; - int[] lineNumbers = out.getLineNumbers(); - dataOut.writeInt(lineNumbersCount); + new FileOutputStream(filename))) + int lineNumbersCount = out.getCurrentLineNumber() - 1 + int[] lineNumbers = out.getLineNumbers() + dataOut.writeInt(lineNumbersCount) for (int i = 0; i < lineNumbersCount; i++) { - dataOut.writeInt(lineNumbers[i]); + dataOut.writeInt(lineNumbers[i]) } } finally { - SpringIOUtils.closeQuietly(dataOut); + SpringIOUtils.closeQuietly(dataOut) } } private void declare(boolean gsp) { - String syntax = gsp ? "!{ ... }!" : "<%! ... %>"; + String syntax = gsp ? '!{ ... }!' : '<%! ... %>' throw new GrailsTagException( - "JSP-style declaration blocks (" + syntax + ") are not supported in Groovy Server Pages. " + - "Use <% ... %> for scriptlet code or move logic to a controller or service.", - pageName, getCurrentOutputLineNumber()); + 'JSP-style declaration blocks (' + syntax + ') are not supported in Groovy Server Pages. ' + + 'Use <% ... %> for scriptlet code or move logic to a controller or service.', + pageName, getCurrentOutputLineNumber()) } private void direct() { if (finalPass) { - return; + return } - String text = scan.getToken(); - text = text.trim(); - if (text.startsWith(TAGLIB_DIRECTIVE + " ")) { - directJspTagLib(text); + String text = scan.getToken() + text = text.trim() + if (text.startsWith(TAGLIB_DIRECTIVE + ' ')) { + directJspTagLib(text) } else { - directPage(text); + directPage(text) } } private void directPage(String text) { - text = text.trim(); - Matcher mat = PAGE_DIRECTIVE_PATTERN.matcher(text); - Boolean compileStaticModeSetting = compileStaticMode; + text = text.trim() + Matcher mat = PAGE_DIRECTIVE_PATTERN.matcher(text) + Boolean compileStaticModeSetting = compileStaticMode while (mat.find()) { - String name = mat.group(1); - String value = mat.group(3); + String name = mat.group(1) + String value = mat.group(3) if (name.equals(IMPORT_DIRECTIVE)) { - pageImport(value); + pageImport(value) } if (name.equalsIgnoreCase(CONTENT_TYPE_DIRECTIVE)) { - contentType(value); + contentType(value) } if (name.equalsIgnoreCase(EXPRESSION_CODEC_DIRECTIVE)) { - expressionCodecDirectiveValue = value.trim(); + expressionCodecDirectiveValue = value.trim() } if (name.equalsIgnoreCase(EXPRESSION_CODEC_DIRECTIVE_ALIAS)) { - expressionCodecDirectiveValue = value.trim(); + expressionCodecDirectiveValue = value.trim() } if (name.equalsIgnoreCase(STATIC_CODEC_DIRECTIVE)) { - staticCodecDirectiveValue = value.trim(); + staticCodecDirectiveValue = value.trim() } if (name.equalsIgnoreCase(OUT_CODEC_DIRECTIVE)) { - outCodecDirectiveValue = value.trim(); + outCodecDirectiveValue = value.trim() } if (name.equalsIgnoreCase(TAGLIB_CODEC_DIRECTIVE)) { - taglibCodecDirectiveValue = value.trim(); + taglibCodecDirectiveValue = value.trim() } if (name.equalsIgnoreCase(MODEL_DIRECTIVE)) { if (modelDirectiveValue != null) { - modelDirectiveValue += "\n" + value.trim(); + modelDirectiveValue += '\n' + value.trim() } else { - modelDirectiveValue = value.trim(); + modelDirectiveValue = value.trim() } - modelFieldsMode = true; + modelFieldsMode = true if (compileStaticModeSetting == null) { - compileStaticModeSetting = true; + compileStaticModeSetting = true } } if (name.equalsIgnoreCase(COMPILE_STATIC_DIRECTIVE)) { - compileStaticModeSetting = GrailsStringUtils.toBoolean(value.trim()); + compileStaticModeSetting = GrailsStringUtils.toBoolean(value.trim()) } if (name.equalsIgnoreCase(TAGLIBS_DIRECTIVE)) { - allowedTaglibNamespaces.addAll(Arrays.asList(value.trim().split("\\s*,\\s*"))); + allowedTaglibNamespaces.addAll(Arrays.asList(value.trim().split('\\s*,\\s*'))) } } - this.compileStaticMode = compileStaticModeSetting != null ? compileStaticModeSetting : false; + this.compileStaticMode = compileStaticModeSetting != null ? compileStaticModeSetting : false } private void directJspTagLib(String text) { - text = text.substring(TAGLIB_DIRECTIVE.length() + 1, text.length()); - Map attrs = new LinkedHashMap<>(); - populateMapWithAttributes(attrs, text); + text = text.substring(TAGLIB_DIRECTIVE.length() + 1, text.length()) + Map attrs = new LinkedHashMap<>() + populateMapWithAttributes(attrs, text) - String prefix = attrs.get("\"prefix\""); - String uri = attrs.get("\"uri\""); + String prefix = attrs.get('"prefix"') + String uri = attrs.get('"uri"') if (uri != null && prefix != null) { - final String namespace = prefix.substring(1, prefix.length() - 1); + final String namespace = prefix.substring(1, prefix.length() - 1) if (!GroovyPage.DEFAULT_NAMESPACE.equals(namespace)) { - jspTags.put(namespace, uri.substring(1, uri.length() - 1)); + jspTags.put(namespace, uri.substring(1, uri.length() - 1)) } else { - LOG.error("You cannot override the default 'g' namespace with the directive <%@ taglib prefix=\"g\" %>. Please select another namespace."); + LOG.error("You cannot override the default 'g' namespace with the directive <%@ taglib prefix=\"g\" %>. Please select another namespace.") } } } private void contentType(String value) { - contentType = value; + contentType = value } private void scriptletExpr() { if (!finalPass) { - return; + return } - String text = scan.getToken().trim(); - out.printlnToResponse(text); + String text = scan.getToken().trim() + out.printlnToResponse(text) } private void expr() { - if (!finalPass) return; + if (!finalPass) return - String text = scan.getToken().trim(); - text = getExpressionText(text); - if (text != null && text.length() > 2 && text.startsWith("(") && text.endsWith(")")) { - out.printlnToResponse(GroovyPage.EXPRESSION_OUT_STATEMENT, text.substring(1, text.length() - 1)); + String text = scan.getToken().trim() + text = getExpressionText(text) + if (text != null && text.length() > 2 && text.startsWith('(') && text.endsWith(')')) { + out.printlnToResponse(GroovyPage.EXPRESSION_OUT_STATEMENT, text.substring(1, text.length() - 1)) } else { - out.printlnToResponse(GroovyPage.EXPRESSION_OUT_STATEMENT, text); + out.printlnToResponse(GroovyPage.EXPRESSION_OUT_STATEMENT, text) } } @@ -692,109 +668,109 @@ private void expr() { * @param text The text * @return An expression text */ - public String getExpressionText(String text) { - return getExpressionText(text, true); + String getExpressionText(String text) { + return getExpressionText(text, true) } - public String getExpressionText(String text, boolean _safeDereference) { - boolean safeDereference = false; - if (text.endsWith("?")) { - text = text.substring(0, text.length() - 1); - safeDereference = _safeDereference; + String getExpressionText(String text, boolean _safeDereference) { + boolean safeDereference = false + if (text.endsWith('?')) { + text = text.substring(0, text.length() - 1) + safeDereference = _safeDereference } if (!precompileMode && !isCompileStaticMode() && (environment == Environment.DEVELOPMENT || environment == Environment.TEST)) { - String escaped = escapeGroovy(text); + String escaped = escapeGroovy(text) text = "evaluate('" + escaped + "', " + - getCurrentOutputLineNumber() + ", it) { return " + text + - " }" + (safeDereference ? "?" : ""); + getCurrentOutputLineNumber() + ', it) { return ' + text + + ' }' + (safeDereference ? '?' : '') } else { // add extra parenthesis, see http://jira.codehaus.org/browse/GRAILS-4351 // or GroovyPagesTemplateEngineTests.testForEachInProductionMode - text = "(" + text + ")" + (safeDereference ? "?" : ""); + text = '(' + text + ')' + (safeDereference ? '?' : '') } - return text; + return text } private String escapeGroovy(String text) { - return text.replace("\\", "\\\\").replace("'", "\\'").replace("\n", "\\n").replace("\r", "\\r"); + return text.replace('\\', '\\\\').replace("'", "\\'").replace('\n', '\\n').replace('\r', '\\r') } /** * Write to the outputstream ONLY if the string is not blank, else we hold * it back in case it is to be swallowed between tags */ - @SuppressWarnings("unused") + @SuppressWarnings('unused') private void bufferedPrintlnToResponse(String s) { if (currentlyBufferingWhitespace) { - whitespaceBuffer.append(s); + whitespaceBuffer.append(s) } else { - flushTagBuffering(); - out.printlnToResponse(s); + flushTagBuffering() + out.printlnToResponse(s) } } private void htmlPartPrintlnToResponse(int partNumber) { if (!tagMetaStack.isEmpty()) { - TagMeta tm = tagMetaStack.peek(); + TagMeta tm = tagMetaStack.peek() if (tm.bufferMode && tm.bufferPartNumber == -1) { - tm.bufferPartNumber = partNumber; - return; + tm.bufferPartNumber = partNumber + return } } - flushTagBuffering(); + flushTagBuffering() - htmlPartPrintlnRaw(partNumber); + htmlPartPrintlnRaw(partNumber) } private void htmlPartPrintlnRaw(int partNumber) { - out.print("h("); - out.print(String.valueOf(partNumber)); - out.print(")"); - out.println(); + out.print('h(') + out.print(String.valueOf(partNumber)) + out.print(')') + out.println() } - public void flushTagBuffering() { + void flushTagBuffering() { if (!tagMetaStack.isEmpty()) { - TagMeta tm = tagMetaStack.peek(); + TagMeta tm = tagMetaStack.peek() if (tm.bufferMode) { - writeTagBodyStart(tm); + writeTagBodyStart(tm) if (tm.bufferPartNumber != -1) { - htmlPartPrintlnRaw(tm.bufferPartNumber); + htmlPartPrintlnRaw(tm.bufferPartNumber) } - tm.bufferMode = false; + tm.bufferMode = false } } } private void html() { - if (!finalPass) return; + if (!finalPass) return - String text = scan.getToken(); + String text = scan.getToken() if (text.length() == 0) { - return; + return } // A \${ the scanner left in the text is an escaped expression: render a literal ${ - text = text.replace("\\${", "${"); + text = text.replace('\\\${', '\${') // If we detect it is all whitespace, we need to keep it for later // If it is not whitespace, we need to flush any whitespace we do have - boolean contentIsWhitespace = !NON_WHITESPACE_PATTERN.matcher(text).find(); + boolean contentIsWhitespace = !NON_WHITESPACE_PATTERN.matcher(text).find() if (!contentIsWhitespace && currentlyBufferingWhitespace) { - flushBufferedWhiteSpace(); + flushBufferedWhiteSpace() } else { - currentlyBufferingWhitespace = contentIsWhitespace; + currentlyBufferingWhitespace = contentIsWhitespace } // We need to know if the last content output was not whitespace, for tag safety checks - previousContentWasNonWhitespace = !contentIsWhitespace; + previousContentWasNonWhitespace = !contentIsWhitespace if (currentlyBufferingWhitespace) { - whitespaceBuffer.append(text); + whitespaceBuffer.append(text) } else { - appendHtmlPart(text); + appendHtmlPart(text) } } @@ -802,50 +778,50 @@ private void appendHtmlPart(String text) { // flush previous white space if any if (whitespaceBuffer.length() > 0) { if (text != null) { - whitespaceBuffer.append(text); + whitespaceBuffer.append(text) } - text = whitespaceBuffer.toString(); - clearBufferedWhiteSpace(); + text = whitespaceBuffer.toString() + clearBufferedWhiteSpace() } // de-dupe constants - Integer constantNumber = constantsToNumbers.get(text); + Integer constantNumber = constantsToNumbers.get(text) if (constantNumber == null) { - constantNumber = constantCount++; - constantsToNumbers.put(text, constantNumber); - htmlParts.add(text); + constantNumber = constantCount++ + constantsToNumbers.put(text, constantNumber) + htmlParts.add(text) } - htmlPartPrintlnToResponse(constantNumber); + htmlPartPrintlnToResponse(constantNumber) } private void makeName(String uri) { - String name; - int slash = uri.lastIndexOf('/'); + String name + int slash = uri.lastIndexOf('/') if (slash > -1) { - name = uri.substring(slash + 1); - uri = uri.substring(0, (uri.length() - 1) - name.length()); - while (uri.endsWith("/")) { - uri = uri.substring(0, uri.length() - 1); + name = uri.substring(slash + 1) + uri = uri.substring(0, (uri.length() - 1) - name.length()) + while (uri.endsWith('/')) { + uri = uri.substring(0, uri.length() - 1) } - slash = uri.lastIndexOf('/'); + slash = uri.lastIndexOf('/') if (slash > -1) { - name = uri.substring(slash + 1) + '_' + name; + name = uri.substring(slash + 1) + '_' + name } } else { - name = uri; + name = uri } - StringBuilder buf = new StringBuilder(name.length()); + StringBuilder buf = new StringBuilder(name.length()) for (int ix = 0, ixz = name.length(); ix < ixz; ix++) { - char c = name.charAt(ix); - if (c < '0' || (c > '9' && c < '@') || (c > 'Z' && c < '_') || - (c > '_' && c < 'a') || c > 'z') { - c = '_'; - } else if (ix == 0 && c >= '0' && c <= '9') { - c = '_'; + char c = name.charAt(ix) + if (c < (char) '0' || (c > (char) '9' && c < (char) '@') || (c > (char) 'Z' && c < (char) '_') || + (c > (char) '_' && c < (char) 'a') || c > (char) 'z') { + c = '_' + } else if (ix == 0 && c >= (char) '0' && c <= (char) '9') { + c = '_' } - buf.append(c); + buf.append(c) } - className = buf.toString(); + className = buf.toString() } /** @@ -855,211 +831,211 @@ private void makeName(String uri) { */ private void makeSourceName(String filename) { if (filename != null) { - int lastSegmentStart = filename.lastIndexOf('/'); + int lastSegmentStart = filename.lastIndexOf('/') if (lastSegmentStart == -1) { - lastSegmentStart = filename.lastIndexOf('\\'); + lastSegmentStart = filename.lastIndexOf('\\') } - sourceName = filename.substring(lastSegmentStart + 1); + sourceName = filename.substring(lastSegmentStart + 1) } else { - sourceName = className; + sourceName = className } } private static boolean match(CharSequence pat, CharSequence text, int start) { - int ix = start, ixz = text.length(), ixy = start + pat.length(); + int ix = start, ixz = text.length(), ixy = start + pat.length() if (ixz > ixy) { - ixz = ixy; + ixz = ixy } if (pat.length() > ixz - start) { - return false; + return false } for (; ix < ixz; ix++) { if (Character.toLowerCase(text.charAt(ix)) != Character.toLowerCase(pat.charAt(ix - start))) { - return false; + return false } } - return true; + return true } private static int match(Pattern pat, CharSequence text, int start) { - Matcher mat = pat.matcher(text); + Matcher mat = pat.matcher(text) if (mat.find(start) && mat.start() == start) { - return mat.end(); + return mat.end() } - return 0; + return 0 } private void page() { if (finalPass) { - out.println(); + out.println() if (pluginAnnotation != null) { - out.println(pluginAnnotation); + out.println(pluginAnnotation) } if (isCompileStaticMode()) { - out.println("@groovy.transform.CompileStatic(extensions = ['" + GroovyPageTypeCheckingExtension.class.getName() + "'])"); + out.println("@groovy.transform.CompileStatic(extensions = ['" + GroovyPageTypeCheckingExtension.getName() + "'])") if (allowedTaglibNamespaces != null && !allowedTaglibNamespaces.isEmpty()) { - StringBuilder config = new StringBuilder("@") - .append(GroovyPageTypeCheckingConfig.class.getName()) + StringBuilder config = new StringBuilder('@') + .append(GroovyPageTypeCheckingConfig.getName()) .append("(taglibs = ['") .append(DefaultGroovyMethods.join((Iterable) allowedTaglibNamespaces, "','")) - .append("']"); + .append("']") if (!pageScopeVariables.isEmpty()) { config.append(", pageScopeVariables = ['") .append(DefaultGroovyMethods.join((Iterable) pageScopeVariables, "','")) - .append("']"); + .append("']") } // A page that declares its model has said what it is rendered with, so a name it // did not declare is a mistake rather than something to defer. A page that // declares nothing has said nothing, and is read the way a dynamic page reads it. if (compileStaticStrict || modelFieldsMode) { - config.append(", strict = true"); + config.append(', strict = true') } - out.println(config.append(')').toString()); + out.println(config.append(')').toString()) } } - out.print("class "); - out.print(className); - out.print(" extends "); - out.print(resolveGspSuperClassName()); - out.println(" {"); + out.print('class ') + out.print(className) + out.print(' extends ') + out.print(resolveGspSuperClassName()) + out.println(' {') if (modelDirectiveValue != null) { - out.println("// start model fields"); - out.println(modelDirectiveValue); - out.println("// end model fields"); + out.println('// start model fields') + out.println(modelDirectiveValue) + out.println('// end model fields') } - writeFrameworkSuppliedAccessors(); - out.println("public String getGroovyPageFileName() { \"" + - pageName.replaceAll("\\\\", "/") + "\" }"); - out.println("public Object run() {"); + writeFrameworkSuppliedAccessors() + out.println('public String getGroovyPageFileName() { "' + + pageName.replaceAll('\\\\', '/') + '" }') + out.println('public Object run() {') /* out.println("def params = binding.params"); out.println("def request = binding.request"); out.println("def flash = binding.flash"); out.println("def response = binding.response"); */ - out.println("Writer " + GroovyPage.OUT + " = getOut()"); - out.println("Writer " + GroovyPage.EXPRESSION_OUT + " = getExpressionOut()"); + out.println('Writer ' + GroovyPage.OUT + ' = getOut()') + out.println('Writer ' + GroovyPage.EXPRESSION_OUT + ' = getExpressionOut()') //out.println("JspTagLib jspTag"); } loop: - for (; ; ) { + for (;;) { if (doNextScan) { - state = scan.nextToken(); + state = scan.nextToken() } else { - doNextScan = true; + doNextScan = true } // Flush any buffered whitespace if there's not a possibility of more whitespace // or a new tag which will handle flushing as necessary if ((state != GSTART_TAG) && (state != HTML)) { - flushBufferedWhiteSpace(); - previousContentWasNonWhitespace = false; // well, we don't know + flushBufferedWhiteSpace() + previousContentWasNonWhitespace = false // well, we don't know } switch (state) { case EOF: - break loop; + break loop case HTML: - html(); - break; + html() + break case JEXPR: - scriptletExpr(); - break; + scriptletExpr() + break case JSCRIPT: - script(false); - break; + script(false) + break case JDIRECT: - direct(); - break; + direct() + break case JDECLAR: - declare(false); - break; + declare(false) + break case GEXPR: - expr(); - break; + expr() + break case GSCRIPT: - script(true); - break; + script(true) + break case GDIRECT: - direct(); - break; + direct() + break case GDECLAR: - declare(true); - break; + declare(true) + break case GSTART_TAG: - startTag(); - break; + startTag() + break case GEND_EMPTY_TAG: case GEND_TAG: - endTag(); - break; + endTag() + break } } if (finalPass) { if (!tagMetaStack.isEmpty()) { - throw new GrailsTagException("Grails tags were not closed! [" + - tagMetaStack + "] in GSP " + pageName + "", pageName, - getCurrentOutputLineNumber()); + throw new GrailsTagException('Grails tags were not closed! [' + + tagMetaStack + '] in GSP ' + pageName + '', pageName, + getCurrentOutputLineNumber()) } - out.println("}"); + out.println('}') - out.println("public static final Map " + CONSTANT_NAME_JSP_TAGS + " = new HashMap()"); + out.println('public static final Map ' + CONSTANT_NAME_JSP_TAGS + ' = new HashMap()') if (jspTags != null && jspTags.size() > 0) { - out.println("static {"); + out.println('static {') for (Map.Entry entry : jspTags.entrySet()) { - out.print("\t" + CONSTANT_NAME_JSP_TAGS + ".put('"); - out.print(escapeGroovy(entry.getKey())); - out.print("','"); - out.print(escapeGroovy(entry.getValue())); - out.println("')"); + out.print('\t' + CONSTANT_NAME_JSP_TAGS + ".put('") + out.print(escapeGroovy(entry.getKey())) + out.print("','") + out.print(escapeGroovy(entry.getValue())) + out.println("')") } - out.println("}"); + out.println('}') } - out.println("protected void init() {"); - out.println("\tthis.jspTags = " + CONSTANT_NAME_JSP_TAGS); - out.println("}"); + out.println('protected void init() {') + out.println('\tthis.jspTags = ' + CONSTANT_NAME_JSP_TAGS) + out.println('}') - out.println("public static final String " + + out.println('public static final String ' + CONSTANT_NAME_CONTENT_TYPE + " = '" + - escapeGroovy(contentType) + "'"); + escapeGroovy(contentType) + "'") - out.println("public static final String " + - CONSTANT_NAME_SOURCE_CHECKSUM + " = " + - (this.sourceChecksum == null ? "null" : "'" + escapeGroovy(this.sourceChecksum) + "'")); + out.println('public static final String ' + + CONSTANT_NAME_SOURCE_CHECKSUM + ' = ' + + (this.sourceChecksum == null ? 'null' : "'" + escapeGroovy(this.sourceChecksum) + "'")) - out.println("public static final String " + - CONSTANT_NAME_EXPRESSION_CODEC + " = '" + escapeGroovy(expressionCodecDirectiveValue) + "'"); - out.println("public static final String " + - CONSTANT_NAME_STATIC_CODEC + " = '" + escapeGroovy(staticCodecDirectiveValue) + "'"); - out.println("public static final String " + - CONSTANT_NAME_OUT_CODEC + " = '" + escapeGroovy(outCodecDirectiveValue) + "'"); - out.println("public static final String " + - CONSTANT_NAME_TAGLIB_CODEC + " = '" + escapeGroovy(taglibCodecDirectiveValue) + "'"); + out.println('public static final String ' + + CONSTANT_NAME_EXPRESSION_CODEC + " = '" + escapeGroovy(expressionCodecDirectiveValue) + "'") + out.println('public static final String ' + + CONSTANT_NAME_STATIC_CODEC + " = '" + escapeGroovy(staticCodecDirectiveValue) + "'") + out.println('public static final String ' + + CONSTANT_NAME_OUT_CODEC + " = '" + escapeGroovy(outCodecDirectiveValue) + "'") + out.println('public static final String ' + + CONSTANT_NAME_TAGLIB_CODEC + " = '" + escapeGroovy(taglibCodecDirectiveValue) + "'") if (isCompileStaticMode()) { - out.println("public static final boolean " + - CONSTANT_NAME_COMPILE_STATIC_MODE + " = " + isCompileStaticMode()); + out.println('public static final boolean ' + + CONSTANT_NAME_COMPILE_STATIC_MODE + ' = ' + isCompileStaticMode()) } if (modelFieldsMode) { - out.println("public static final boolean " + - CONSTANT_NAME_MODEL_FIELDS_MODE + " = " + modelFieldsMode); + out.println('public static final boolean ' + + CONSTANT_NAME_MODEL_FIELDS_MODE + ' = ' + modelFieldsMode) } - out.println("}"); + out.println('}') if (shouldAddLineNumbers()) { - addLineNumbers(); + addLineNumbers() } } else { for (int i = 0; i < DEFAULT_IMPORTS.length; i++) { - out.print("import "); - out.println(DEFAULT_IMPORTS[i]); + out.print('import ') + out.println(DEFAULT_IMPORTS[i]) } } } @@ -1070,17 +1046,17 @@ private void page() { */ private void writeFrameworkSuppliedAccessors() { if (!isCompileStaticMode()) { - return; + return } - Set declared = declaredModelNames(); + Set declared = declaredModelNames() for (Map.Entry supplied : FRAMEWORK_SUPPLIED_TYPES.entrySet()) { - String name = supplied.getKey(); + String name = supplied.getKey() if (declared.contains(name)) { - continue; + continue } - String type = supplied.getValue(); - String accessor = "get" + Character.toUpperCase(name.charAt(0)) + name.substring(1); - out.println(type + " " + accessor + "() { (" + type + ") resolveProperty('" + name + "') }"); + String type = supplied.getValue() + String accessor = 'get' + Character.toUpperCase(name.charAt(0)) + name.substring(1) + out.println(type + ' ' + accessor + '() { (' + type + ") resolveProperty('" + name + "') }") } } @@ -1088,31 +1064,31 @@ private void writeFrameworkSuppliedAccessors() { * The names this page's model directive declares, which are the ones it has spoken for. */ private Set declaredModelNames() { - Set names = new LinkedHashSet<>(); + Set names = new LinkedHashSet<>() if (modelDirectiveValue == null) { - return names; + return names } - for (String declaration : modelDirectiveValue.split("[;\n]")) { - String withoutValue = declaration.split("=", 2)[0].trim(); + for (String declaration in modelDirectiveValue.split('[;\n]')) { + String withoutValue = declaration.split('=', 2)[0].trim() if (withoutValue.isEmpty()) { - continue; + continue } - String[] tokens = WHITESPACE_PATTERN.split(withoutValue); - String candidate = tokens[tokens.length - 1].trim(); + String[] tokens = WHITESPACE_PATTERN.split(withoutValue) + String candidate = tokens[tokens.length - 1].trim() if (!candidate.isEmpty()) { - names.add(candidate); + names.add(candidate) } } - return names; + return names } private String resolveGspSuperClassName() { - Class gspSuperClass = isCompileStaticMode() ? CompileStaticGroovyPage.class : (isModelRecordingModeEnabled() ? ModelRecordingGroovyPage.class : GroovyPage.class); - return gspSuperClass.getName(); + Class gspSuperClass = isCompileStaticMode() ? CompileStaticGroovyPage : (isModelRecordingModeEnabled() ? ModelRecordingGroovyPage : GroovyPage) + return gspSuperClass.getName() } private boolean isModelRecordingModeEnabled() { - return ModelRecordingGroovyPage.ENABLED; + return ModelRecordingGroovyPage.ENABLED } /** @@ -1123,10 +1099,10 @@ private boolean isModelRecordingModeEnabled() { private boolean shouldAddLineNumbers() { try { // for now, we support this through a system property. - return Boolean.valueOf(System.getenv("GROOVY_PAGE_ADD_LINE_NUMBERS")); + return Boolean.valueOf(System.getenv('GROOVY_PAGE_ADD_LINE_NUMBERS')) } catch (Exception e) { // something wild happened - return false; + return false } } @@ -1135,23 +1111,23 @@ private boolean shouldAddLineNumbers() { * in a way suitable for the LineNumberTransform AST transform to operate on it */ private void addLineNumbers() { - out.println(); - out.println("@LineNumber("); - out.print("\tlines = ["); + out.println() + out.println('@LineNumber(') + out.print('\tlines = [') // get the line numbers here. this will mean that the last 2 lines will not be captured in the // line number information, but that's OK since a user cannot set a breakpoint there anyway. - int[] lineNumbers = filterTrailing0s(out.getLineNumbers()); + int[] lineNumbers = filterTrailing0s(out.getLineNumbers()) for (int i = 0; i < lineNumbers.length; i++) { - out.print(lineNumbers[i]); + out.print(lineNumbers[i]) if (i < lineNumbers.length - 1) { - out.print(", "); + out.print(', ') } } - out.println("],"); - out.println("\tsourceName = \"" + sourceName + "\""); - out.println(")"); - out.println("class ___LineNumberPlaceholder { }"); + out.println('],') + out.println('\tsourceName = "' + sourceName + '"') + out.println(')') + out.println('class ___LineNumberPlaceholder { }') } /** @@ -1161,17 +1137,17 @@ private void addLineNumbers() { * @return a new array that removes all 0s from the end of it */ private int[] filterTrailing0s(int[] lineNumbers) { - int startLocation = lineNumbers.length - 1; + int startLocation = lineNumbers.length - 1 for (int i = lineNumbers.length - 1; i >= 0; i--) { if (lineNumbers[i] > 0) { - startLocation = i + 1; - break; + startLocation = i + 1 + break } } - int[] newLineNumbers = new int[startLocation]; - System.arraycopy(lineNumbers, 0, newLineNumbers, 0, startLocation); - return newLineNumbers; + int[] newLineNumbers = new int[startLocation] + System.arraycopy(lineNumbers, 0, newLineNumbers, 0, startLocation) + return newLineNumbers } /** @@ -1179,250 +1155,250 @@ private int[] filterTrailing0s(int[] lineNumbers) { * declared it and this occurrence assigns to that declaration */ private boolean declareTypedSetVariable(String var) { - for (Set scope : typedSetScopes) { + for (Set scope in typedSetScopes) { if (scope.contains(var)) { - return false; + return false } } - typedSetScopes.peek().add(var); - return true; + typedSetScopes.peek().add(var) + return true } private void endTag() { - if (!finalPass) return; + if (!finalPass) return - String tagName = scan.getToken().trim(); - String ns = scan.getNamespace(); + String tagName = scan.getToken().trim() + String ns = scan.getNamespace() if (tagMetaStack.isEmpty()) throw new GrailsTagException( - "Found closing Grails tag with no opening [" + tagName + "]", pageName, - getCurrentOutputLineNumber()); + 'Found closing Grails tag with no opening [' + tagName + ']', pageName, + getCurrentOutputLineNumber()) - TagMeta tm = tagMetaStack.pop(); + TagMeta tm = tagMetaStack.pop() if (!tm.emptyTag && typedSetScopes.size() > 1) { - typedSetScopes.pop(); + typedSetScopes.pop() } - String lastInStack = tm.name; - String lastNamespaceInStack = tm.namespace; + String lastInStack = tm.name + String lastNamespaceInStack = tm.namespace // if the tag name is blank then it has been closed by the start tag ie if (GrailsStringUtils.isBlank(tagName)) { - tagName = lastInStack; + tagName = lastInStack } if (!lastInStack.equals(tagName) || !lastNamespaceInStack.equals(ns)) { - throw new GrailsTagException("Grails tag [" + lastNamespaceInStack + - ":" + lastInStack + "] was not closed", pageName, getCurrentOutputLineNumber()); + throw new GrailsTagException('Grails tag [' + lastNamespaceInStack + + ':' + lastInStack + '] was not closed', pageName, getCurrentOutputLineNumber()) } if (GroovyPage.DEFAULT_NAMESPACE.equals(ns) && tagRegistry.isSyntaxTag(tagName)) { if (tm.instance instanceof GroovySyntaxTag) { - GroovySyntaxTag tag = (GroovySyntaxTag) tm.instance; - tag.doEndTag(); + GroovySyntaxTag tag = (GroovySyntaxTag) tm.instance + tag.doEndTag() } else { - throw new GrailsTagException("Grails tag [" + tagName + - "] was not closed", pageName, - getCurrentOutputLineNumber()); + throw new GrailsTagException('Grails tag [' + tagName + + '] was not closed', pageName, + getCurrentOutputLineNumber()) } } else { - int bodyTagIndex = -1; + int bodyTagIndex = -1 if (!tm.emptyTag && !tm.bufferMode) { - bodyTagIndex = tagIndex; - out.println("})"); - closureLevel--; + bodyTagIndex = tagIndex + out.println('})') + closureLevel-- } if (tm.bufferMode && tm.bufferPartNumber != -1) { if (!bodyVarsDefined.contains(tm.tagIndex)) { //out.print("def "); - bodyVarsDefined.add(tm.tagIndex); + bodyVarsDefined.add(tm.tagIndex) } - out.println("createClosureForHtmlPart(" + tm.bufferPartNumber + ", " + tm.tagIndex + ")"); - bodyTagIndex = tm.tagIndex; - tm.bufferMode = false; + out.println('createClosureForHtmlPart(' + tm.bufferPartNumber + ', ' + tm.tagIndex + ')') + bodyTagIndex = tm.tagIndex + tm.bufferMode = false } if (jspTags.containsKey(ns)) { - String uri = jspTags.get(ns); - out.println("jspTag = getJspTag('" + uri + "', '" + tagName + "')"); + String uri = jspTags.get(ns) + out.println("jspTag = getJspTag('" + uri + "', '" + tagName + "')") out.println("if (!jspTag) throw new GrailsTagException('Unknown JSP tag " + - ns + ":" + tagName + "')"); - out.print("jspTag.doTag(out," + attrsVarsMapDefinition.get(tagIndex) + ","); + ns + ':' + tagName + "')") + out.print('jspTag.doTag(out,' + attrsVarsMapDefinition.get(tagIndex) + ',') if (bodyTagIndex > -1) { - out.print("getBodyClosure(" + bodyTagIndex + ")"); + out.print('getBodyClosure(' + bodyTagIndex + ')') } else { - out.print("null"); + out.print('null') } - out.println(")"); + out.println(')') } else { if (tm.hasAttributes) { out.println("invokeTag('" + tagName + "','" + ns + "'," + - getCurrentOutputLineNumber() + "," + attrsVarsMapDefinition.get(tagIndex) + - "," + bodyTagIndex + ")"); + getCurrentOutputLineNumber() + ',' + attrsVarsMapDefinition.get(tagIndex) + + ',' + bodyTagIndex + ')') } else { out.println("invokeTag('" + tagName + "','" + ns + "'," + - getCurrentOutputLineNumber() + ",[:]," + bodyTagIndex + ")"); + getCurrentOutputLineNumber() + ',[:],' + bodyTagIndex + ')') } } } - tm.bufferMode = false; + tm.bufferMode = false - tagIndex--; + tagIndex-- } - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings(['unchecked', 'rawtypes']) private void startTag() { - if (!finalPass) return; + if (!finalPass) return - tagIndex++; + tagIndex++ - String text; - StringBuilder buf = new StringBuilder(scan.getToken()); - String ns = scan.getNamespace(); + String text + StringBuilder buf = new StringBuilder(scan.getToken()) + String ns = scan.getNamespace() - boolean emptyTag = false; + boolean emptyTag = false - state = scan.nextToken(); + state = scan.nextToken() while (state != HTML && state != GEND_TAG && state != GEND_EMPTY_TAG && state != EOF) { if (state == GTAG_EXPR) { - buf.append("${"); - buf.append(scan.getToken().trim()); - buf.append("}"); + buf.append('\${') + buf.append(scan.getToken().trim()) + buf.append('}') } else { - buf.append(scan.getToken()); + buf.append(scan.getToken()) } - state = scan.nextToken(); + state = scan.nextToken() } if (state == GEND_EMPTY_TAG) { - emptyTag = true; + emptyTag = true } - doNextScan = false; + doNextScan = false - text = buf.toString(); + text = buf.toString() - String tagName; - Map attrs = new LinkedHashMap(); + String tagName + Map attrs = new LinkedHashMap() - Matcher m = WHITESPACE_PATTERN.matcher(text); + Matcher m = WHITESPACE_PATTERN.matcher(text) if (m.find()) { // ignores carriage returns and new lines - tagName = text.substring(0, m.start()); + tagName = text.substring(0, m.start()) if (state != EOF) { - String attrTokens = text.substring(m.start(), text.length()); - populateMapWithAttributes(attrs, attrTokens); + String attrTokens = text.substring(m.start(), text.length()) + populateMapWithAttributes(attrs, attrTokens) } } else { - tagName = text; + tagName = text } if (state == EOF) { throw new GrailsTagException( - "Unexpected end of file encountered parsing Tag [" + tagName + "] for " + className + + 'Unexpected end of file encountered parsing Tag [' + tagName + '] for ' + className + ". Are you missing a closing brace '}'?", pageName, - getCurrentOutputLineNumber()); + getCurrentOutputLineNumber()) } - flushTagBuffering(); + flushTagBuffering() - TagMeta tm = new TagMeta(); - tm.name = tagName; - tm.namespace = ns; - tm.hasAttributes = !attrs.isEmpty(); - tm.lineNumber = getCurrentOutputLineNumber(); - tm.emptyTag = emptyTag; - tm.tagIndex = tagIndex; - tagMetaStack.push(tm); + TagMeta tm = new TagMeta() + tm.name = tagName + tm.namespace = ns + tm.hasAttributes = !attrs.isEmpty() + tm.lineNumber = getCurrentOutputLineNumber() + tm.emptyTag = emptyTag + tm.tagIndex = tagIndex + tagMetaStack.push(tm) if (!emptyTag) { // The body is emitted inside a block, so a name declared in it belongs to that block. - typedSetScopes.push(new LinkedHashSet<>()); + typedSetScopes.push(new LinkedHashSet<>()) } if (GroovyPage.DEFAULT_NAMESPACE.equals(ns) && tagRegistry.isSyntaxTag(tagName)) { if (tagContext == null) { - tagContext = new HashMap<>(); - tagContext.put(GroovyPage.OUT, out); - tagContext.put(GroovyPageParser.class, this); + tagContext = new HashMap<>() + tagContext.put(GroovyPage.OUT, out) + tagContext.put(GroovyPageParser, this) } - GroovySyntaxTag tag = (GroovySyntaxTag) tagRegistry.newTag(tagName); - tag.init(tagContext); - tag.setAttributes(attrs); + GroovySyntaxTag tag = (GroovySyntaxTag) tagRegistry.newTag(tagName) + tag.init(tagContext) + tag.setAttributes(attrs) if (tag.isKeepPrecedingWhiteSpace() && currentlyBufferingWhitespace) { - flushBufferedWhiteSpace(); + flushBufferedWhiteSpace() } else if (!tag.isAllowPrecedingContent() && previousContentWasNonWhitespace) { - throw new GrailsTagException("Tag [" + tag.getName() + - "] cannot have non-whitespace characters directly preceding it.", pageName, - getCurrentOutputLineNumber()); + throw new GrailsTagException('Tag [' + tag.getName() + + '] cannot have non-whitespace characters directly preceding it.', pageName, + getCurrentOutputLineNumber()) } else { // If tag does not specify buffering of WS, we swallow it here - clearBufferedWhiteSpace(); + clearBufferedWhiteSpace() } - tag.doStartTag(); + tag.doStartTag() - tm.instance = tag; + tm.instance = tag } else { // Custom taglibs have to always flush the whitespace, there's no // "allowPrecedingWhitespace" property on tags yet - flushBufferedWhiteSpace(); + flushBufferedWhiteSpace() - writeTypedSetDeclaration(ns, tagName, attrs); + writeTypedSetDeclaration(ns, tagName, attrs) if (attrs.size() > 0) { - FastStringWriter buffer = new FastStringWriter(); - buffer.print("["); - for (Iterator i = attrs.keySet().iterator(); i.hasNext(); ) { - String name = (String) i.next(); - String cleanedName = name; - if (name.startsWith("\"") && name.endsWith("\"")) { - cleanedName = "'" + name.substring(1, name.length() - 1) + "'"; + FastStringWriter buffer = new FastStringWriter() + buffer.print('[') + for (Iterator i = attrs.keySet().iterator(); i.hasNext();) { + String name = (String) i.next() + String cleanedName = name + if (name.startsWith('"') && name.endsWith('"')) { + cleanedName = "'" + name.substring(1, name.length() - 1) + "'" } - buffer.print(cleanedName); - buffer.print(':'); + buffer.print(cleanedName) + buffer.print(':') - buffer.print(getExpressionText(attrs.get(name).toString())); + buffer.print(getExpressionText(attrs.get(name).toString())) if (i.hasNext()) { - buffer.print(','); + buffer.print(',') } else { - buffer.print("]"); + buffer.print(']') } } - attrsVarsMapDefinition.put(tagIndex, buffer.toString()); - buffer.close(); + attrsVarsMapDefinition.put(tagIndex, buffer.toString()) + buffer.close() } if (!emptyTag) { - tm.bufferMode = true; + tm.bufferMode = true } } } private void writeTagBodyStart(TagMeta tm) { if (tm.bufferMode) { - tm.bufferMode = false; + tm.bufferMode = false if (!bodyVarsDefined.contains(tm.tagIndex)) { //out.print("def "); - bodyVarsDefined.add(tm.tagIndex); + bodyVarsDefined.add(tm.tagIndex) } - out.println("createTagBody(" + tm.tagIndex + ", {->"); - closureLevel++; + out.println('createTagBody(' + tm.tagIndex + ', {->') + closureLevel++ } } private void clearBufferedWhiteSpace() { - whitespaceBuffer.delete(0, whitespaceBuffer.length()); - currentlyBufferingWhitespace = false; + whitespaceBuffer.delete(0, whitespaceBuffer.length()) + currentlyBufferingWhitespace = false } // Write out any whitespace we saved between tags private void flushBufferedWhiteSpace() { if (currentlyBufferingWhitespace) { - appendHtmlPart(null); + appendHtmlPart(null) } - currentlyBufferingWhitespace = false; + currentlyBufferingWhitespace = false } /** @@ -1440,185 +1416,185 @@ private void flushBufferedWhiteSpace() { */ private void writeTypedSetDeclaration(String ns, String tagName, Map attrs) { if (!GroovyPage.DEFAULT_NAMESPACE.equals(ns) || !SET_TAG_NAME.equals(tagName)) { - return; + return } - String type = attributeText(attrs, TYPE_ATTRIBUTE); + String type = attributeText(attrs, TYPE_ATTRIBUTE) if (type == null) { - return; + return } - String var = attributeText(attrs, VAR_ATTRIBUTE); + String var = attributeText(attrs, VAR_ATTRIBUTE) if (GrailsStringUtils.isBlank(var)) { - throw new GrailsTagException("Tag [set] with a [type] needs a [var] naming what to declare", - pageName, getCurrentOutputLineNumber()); + throw new GrailsTagException('Tag [set] with a [type] needs a [var] naming what to declare', + pageName, getCurrentOutputLineNumber()) } - Object value = attrs.get("\"value\""); + Object value = attrs.get('"value"') if (value == null) { - throw new GrailsTagException("Tag [set] can only be given a [type] together with a [value]; " + - "the body and the [bean] attribute are produced when the tag runs, so there is nothing " + - "to declare the variable from", pageName, getCurrentOutputLineNumber()); + throw new GrailsTagException('Tag [set] can only be given a [type] together with a [value]; ' + + 'the body and the [bean] attribute are produced when the tag runs, so there is nothing ' + + 'to declare the variable from', pageName, getCurrentOutputLineNumber()) } - attrs.remove("\"" + TYPE_ATTRIBUTE + "\""); + attrs.remove('"' + TYPE_ATTRIBUTE + '"') // A name typed once is declared; typing it again assigns to what was declared. Declaring it // twice would not compile, where the untyped tag simply writes the scope again. - String declaration = declareTypedSetVariable(var) ? type + " " + var : var; + String declaration = declareTypedSetVariable(var) ? type + ' ' + var : var // A Groovy cast rather than Class.cast, which only accepts what is already of the type: a // long declared from an integer literal, a String from a GString and a List from an array are // all ordinary things to write, and all of them are conversions rather than instances. - out.println(declaration + " = (" + type + ") (" + getExpressionText(value.toString()) + ")"); + out.println(declaration + ' = (' + type + ') (' + getExpressionText(value.toString()) + ')') // and the tag is called with what was just declared, so it writes the same value into the scope - attrs.put("\"value\"", var); + attrs.put('"value"', var) } /** The plain text of a quoted attribute, or {@code null} where the page did not give one. */ private static String attributeText(Map attrs, String name) { - Object raw = attrs.get("\"" + name + "\""); + Object raw = attrs.get('"' + name + '"') if (raw == null) { - return null; + return null } - String text = raw.toString().trim(); - if (text.length() > 1 && (text.startsWith("\"") || text.startsWith("'")) && + String text = raw.toString().trim() + if (text.length() > 1 && (text.startsWith('"') || text.startsWith("'")) && text.charAt(0) == text.charAt(text.length() - 1)) { - return text.substring(1, text.length() - 1).trim(); + return text.substring(1, text.length() - 1).trim() } - return text; + return text } private void populateMapWithAttributes(Map attrs, String attrTokens) { - attrTokens = attrTokens.trim(); - int startPos = 0; + attrTokens = attrTokens.trim() + int startPos = 0 while (startPos < attrTokens.length()) { // parse name (before '=' character) - int equalsignPos = attrTokens.indexOf('=', startPos); + int equalsignPos = attrTokens.indexOf('=', startPos) if (equalsignPos == -1) { - throw new GrailsTagException("Expecting '=' after attribute name (" + attrTokens + ").", pageName, getCurrentOutputLineNumber()); + throw new GrailsTagException("Expecting '=' after attribute name (" + attrTokens + ').', pageName, getCurrentOutputLineNumber()) } - String name = attrTokens.substring(startPos, equalsignPos).trim(); + String name = attrTokens.substring(startPos, equalsignPos).trim() // parse value - startPos = equalsignPos + 1; - char ch = attrTokens.charAt(startPos++); + startPos = equalsignPos + 1 + char ch = attrTokens.charAt(startPos++) while (Character.isWhitespace(ch) && startPos < attrTokens.length()) { - ch = attrTokens.charAt(startPos++); + ch = attrTokens.charAt(startPos++) } if (!(ch == '\'' || ch == '"')) { - throw new GrailsTagException("Attribute value must be quoted (" + attrTokens + ").", pageName, getCurrentOutputLineNumber()); + throw new GrailsTagException('Attribute value must be quoted (' + attrTokens + ').', pageName, getCurrentOutputLineNumber()) } - char quoteChar = ch; + char quoteChar = ch - GroovyPageExpressionParser expressionParser = new GroovyPageExpressionParser(attrTokens, startPos, quoteChar, (char) 0, false); - int endQuotepos = expressionParser.parse(); + GroovyPageExpressionParser expressionParser = new GroovyPageExpressionParser(attrTokens, startPos, quoteChar, (char) 0, false) + int endQuotepos = expressionParser.parse() if (endQuotepos == -1) { - throw new GrailsTagException("Attribute value quote wasn't closed (" + attrTokens + ").", pageName, getCurrentOutputLineNumber()); + throw new GrailsTagException("Attribute value quote wasn't closed (" + attrTokens + ').', pageName, getCurrentOutputLineNumber()) } - String val = attrTokens.substring(startPos, endQuotepos); + String val = attrTokens.substring(startPos, endQuotepos) - if (val.startsWith("${") && val.endsWith("}") && !expressionParser.isContainsGstrings()) { - val = val.substring(2, val.length() - 1); - } else if (!(val.startsWith("[") && val.endsWith("]"))) { + if (val.startsWith('\${') && val.endsWith('}') && !expressionParser.isContainsGstrings()) { + val = val.substring(2, val.length() - 1) + } else if (!(val.startsWith('[') && val.endsWith(']'))) { if (val.indexOf('"') == -1) { - quoteChar = '"'; + quoteChar = '"' } - String quoteStr; + String quoteStr // use multiline groovy string if the value contains newlines if (val.indexOf('\n') != -1 || val.indexOf('\r') != -1) { if (quoteChar == '"') { - quoteStr = MULTILINE_GROOVY_STRING_DOUBLEQUOTES; + quoteStr = MULTILINE_GROOVY_STRING_DOUBLEQUOTES } else { - quoteStr = MULTILINE_GROOVY_STRING_SINGLEQUOTES; + quoteStr = MULTILINE_GROOVY_STRING_SINGLEQUOTES } } else { - quoteStr = String.valueOf(quoteChar); + quoteStr = String.valueOf(quoteChar) } - val = quoteStr + val + quoteStr; + val = quoteStr + val + quoteStr } - attrs.put("\"" + name + "\"", val); - startPos = endQuotepos + 1; + attrs.put('"' + name + '"', val) + startPos = endQuotepos + 1 } } private void pageImport(String value) { - String[] imports = IMPORT_SEMICOLON_PATTERN.split(value.subSequence(0, value.length())); + String[] imports = IMPORT_SEMICOLON_PATTERN.split(value.subSequence(0, value.length())) for (int ix = 0; ix < imports.length; ix++) { - out.print("import "); - out.print(imports[ix]); - out.println(); + out.print('import ') + out.print(imports[ix]) + out.println() } } private static String readStream(InputStream in, String gspEncoding) throws IOException { if (gspEncoding == null) { - gspEncoding = DEFAULT_ENCODING; + gspEncoding = DEFAULT_ENCODING } - return IOUtils.toString(in, gspEncoding); + return IOUtils.toString(in, gspEncoding) } - public static String getGspEncoding() { - return DEFAULT_ENCODING; + static String getGspEncoding() { + return DEFAULT_ENCODING } private void script(boolean gsp) { - flushTagBuffering(); - if (!finalPass) return; + flushTagBuffering() + if (!finalPass) return - out.println(); - write(scan.getToken().trim(), gsp); - out.println(); - out.println(); + out.println() + write(scan.getToken().trim(), gsp) + out.println() + out.println() } private void write(CharSequence text, boolean gsp) { if (!gsp) { - out.print(text); - return; + out.print(text) + return } for (int ix = 0, ixz = text.length(); ix < ixz; ix++) { - char c = text.charAt(ix); - String rep = null; + char c = text.charAt(ix) + String rep = null if (Character.isWhitespace(c)) { for (ix++; ix < ixz; ix++) { if (Character.isWhitespace(text.charAt(ix))) { - continue; + continue } - ix--; - rep = " "; - break; + ix-- + rep = ' ' + break } } else if (c == '&') { - if (match(";", text, ix)) { - rep = ";"; - ix += 5; - } else if (match("&", text, ix)) { - rep = "&"; - ix += 4; - } else if (match("<", text, ix)) { - rep = "<"; - ix += 3; - } else if (match(">", text, ix)) { - rep = ">"; - ix += 3; + if (match(';', text, ix)) { + rep = ';' + ix += 5 + } else if (match('&', text, ix)) { + rep = '&' + ix += 4 + } else if (match('<', text, ix)) { + rep = '<' + ix += 3 + } else if (match('>', text, ix)) { + rep = '>' + ix += 3 } } else if (c == '<') { - if (match("
", text, ix) || match("
", text, ix)) { - rep = "\n"; + if (match('
', text, ix) || match('
', text, ix)) { + rep = '\n' //incrementLineNumber(); - ix += 3; + ix += 3 } else { - int end = match(PARA_BREAK, text, ix); + int end = match(PARA_BREAK, text, ix) if (end <= 0) - end = match(ROW_BREAK, text, ix); + end = match(ROW_BREAK, text, ix) if (end > 0) { - rep = "\n"; + rep = '\n' //incrementLineNumber(); - ix = end; + ix = end } } } if (rep != null) { - out.print(rep); + out.print(rep) } else { - out.print(c); + out.print(c) } } } @@ -1638,13 +1614,13 @@ private void write(CharSequence text, boolean gsp) { * @return the checksum as a lower-case hex string * @since 8.0.0 */ - public static String checksumOf(byte[] source) { + static String checksumOf(byte[] source) { try { - return HexFormat.of().formatHex(MessageDigest.getInstance(CHECKSUM_ALGORITHM).digest(source)); + return HexFormat.of().formatHex(MessageDigest.getInstance(CHECKSUM_ALGORITHM).digest(source)) } catch (NoSuchAlgorithmException e) { // every JVM is required to provide SHA-256 - throw new IllegalStateException("Checksum algorithm " + CHECKSUM_ALGORITHM + " is not available", e); + throw new IllegalStateException('Checksum algorithm ' + CHECKSUM_ALGORITHM + ' is not available', e) } } @@ -1652,8 +1628,8 @@ public static String checksumOf(byte[] source) { * @return a checksum of the GSP source this page was generated from, or {@code null} if none was recorded * @since 8.0.0 */ - public String getSourceChecksum() { - return this.sourceChecksum; + String getSourceChecksum() { + return this.sourceChecksum } /** @@ -1663,63 +1639,64 @@ public String getSourceChecksum() { * @param sourceChecksum the checksum, or {@code null} to record none * @since 8.0.0 */ - public void setSourceChecksum(String sourceChecksum) { - this.sourceChecksum = sourceChecksum; + void setSourceChecksum(String sourceChecksum) { + this.sourceChecksum = sourceChecksum } - public List getHtmlParts() { - return htmlParts; + List getHtmlParts() { + return htmlParts } - public String[] getHtmlPartsArray() { - return htmlParts.toArray(new String[htmlParts.size()]); + String[] getHtmlPartsArray() { + return htmlParts.toArray(new String[htmlParts.size()]) } - public boolean isInClosure() { - return closureLevel > 0; + boolean isInClosure() { + return closureLevel > 0 } - public String getExpressionCodecDirectiveValue() { - return expressionCodecDirectiveValue; + String getExpressionCodecDirectiveValue() { + return expressionCodecDirectiveValue } - public String getPageName() { - return pageName; + String getPageName() { + return pageName } - public String getOutCodecDirectiveValue() { - return outCodecDirectiveValue; + String getOutCodecDirectiveValue() { + return outCodecDirectiveValue } - public String getStaticCodecDirectiveValue() { - return staticCodecDirectiveValue; + String getStaticCodecDirectiveValue() { + return staticCodecDirectiveValue } - public String getTaglibCodecDirectiveValue() { - return taglibCodecDirectiveValue; + String getTaglibCodecDirectiveValue() { + return taglibCodecDirectiveValue } - public void setTaglibCodecDirectiveValue(String taglibCodecDirectiveValue) { - this.taglibCodecDirectiveValue = taglibCodecDirectiveValue; + void setTaglibCodecDirectiveValue(String taglibCodecDirectiveValue) { + this.taglibCodecDirectiveValue = taglibCodecDirectiveValue } - public void setExpressionCodecDirectiveValue(String expressionCodecDirectiveValue) { - this.expressionCodecDirectiveValue = expressionCodecDirectiveValue; + void setExpressionCodecDirectiveValue(String expressionCodecDirectiveValue) { + this.expressionCodecDirectiveValue = expressionCodecDirectiveValue } - public void setOutCodecDirectiveValue(String outCodecDirectiveValue) { - this.outCodecDirectiveValue = outCodecDirectiveValue; + void setOutCodecDirectiveValue(String outCodecDirectiveValue) { + this.outCodecDirectiveValue = outCodecDirectiveValue } - public void setStaticCodecDirectiveValue(String staticCodecDirectiveValue) { - this.staticCodecDirectiveValue = staticCodecDirectiveValue; + void setStaticCodecDirectiveValue(String staticCodecDirectiveValue) { + this.staticCodecDirectiveValue = staticCodecDirectiveValue } - public boolean isCompileStaticMode() { - return compileStaticMode != null ? compileStaticMode : false; + boolean isCompileStaticMode() { + return compileStaticMode != null ? compileStaticMode : false } - public boolean isModelFieldsMode() { - return modelFieldsMode; + boolean isModelFieldsMode() { + return modelFieldsMode } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageScanner.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageScanner.groovy similarity index 57% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageScanner.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageScanner.groovy index 2c4201b553f..352fd832456 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageScanner.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageScanner.groovy @@ -16,13 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler; +package org.grails.gsp.compiler -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; +import java.util.regex.Pattern -import org.grails.taglib.GrailsTagException; +import groovy.transform.CompileStatic + +import org.grails.taglib.GrailsTagException /** * NOTE: Based on work done by on the GSP standalone project (https://gsp.dev.java.net/) @@ -34,246 +34,248 @@ * * Date: Jan 10, 2004 */ +@CompileStatic class GroovyPageScanner implements Tokens { - private static final int DEFAULT_MAX_HTML_LENGTH = 64000; - private String text; - private int end1; - private int begin1; - private int end2; - private int begin2; - private int state = HTML; - private int len; - private String lastNamespace; - private List lineNumberPositions; - private int lastLineNumberIndex = -1; - private String pageName = "Unknown"; - private int maxHtmlLength = DEFAULT_MAX_HTML_LENGTH; - private Pattern isTagNameSpacePattern = Pattern.compile("^\\p{Alpha}\\w*$"); + + private static final int DEFAULT_MAX_HTML_LENGTH = 64000 + private String text + private int end1 + private int begin1 + private int end2 + private int begin2 + private int state = HTML + private int len + private String lastNamespace + private List lineNumberPositions + private int lastLineNumberIndex = -1 + private String pageName = 'Unknown' + private int maxHtmlLength = DEFAULT_MAX_HTML_LENGTH + private Pattern isTagNameSpacePattern = Pattern.compile('^\\p{Alpha}\\w*\$') GroovyPageScanner(String text) { - Strip strip = new Strip(text); - strip.strip(0); - this.text = strip.toString(); - len = this.text.length(); - resolveLineNumberPositions(); + Strip strip = new Strip(text) + strip.strip(0) + this.text = strip.toString() + len = this.text.length() + resolveLineNumberPositions() } - public GroovyPageScanner(String gspSource, String uri) { - this(gspSource); - this.pageName = uri; + GroovyPageScanner(String gspSource, String uri) { + this(gspSource) + this.pageName = uri } // add line starting positions to array private void resolveLineNumberPositions() { - lineNumberPositions = new ArrayList<>(); + lineNumberPositions = new ArrayList<>() // first line starts at 0 - lineNumberPositions.add(0); + lineNumberPositions.add(0) for (int i = 0; i < len; i++) { if (text.charAt(i) == '\n') { // next line starts after LF - lineNumberPositions.add(i + 1); + lineNumberPositions.add(i + 1) } } } private int found(int newState, int skip) { - begin2 = begin1; - end2 = --end1; - begin1 = end1 += skip; - int lastState = state; - state = newState; - return lastState; + begin2 = begin1 + end2 = --end1 + begin1 = end1 += skip + int lastState = state + state = newState + return lastState } private int foundStartOrEndTag(int newState, int skip, String namespace) { - begin2 = begin1; - end2 = --end1; - begin1 = end1 += skip; - int lastState = state; - state = newState; - lastNamespace = namespace; - return lastState; + begin2 = begin1 + end2 = --end1 + begin1 = end1 += skip + int lastState = state + state = newState + lastNamespace = namespace + return lastState } String getToken() { - return text.substring(begin2, end2); + return text.substring(begin2, end2) } int getLineNumberForToken() { for (int i = lastLineNumberIndex + 1; i < lineNumberPositions.size(); i++) { if (lineNumberPositions.get(i) > begin2) { - lastLineNumberIndex = i - 1; - return i; + lastLineNumberIndex = i - 1 + return i } } // unknown - return 1; + return 1 } String getNamespace() { - return lastNamespace; + return lastNamespace } int nextToken() { for (;;) { - int left = len - end1; + int left = len - end1 if (left == 0) { - end1++; // in order to include the last letter - return found(EOF, 0); + end1++ // in order to include the last letter + return found(EOF, 0) } - char c = text.charAt(end1++); - char c1 = left > 1 ? text.charAt(end1) : 0; - char c2 = left > 2 ? text.charAt(end1 + 1) : 0; - int tokenLength = end1 - begin1; + char c = text.charAt(end1++) + char c1 = left > 1 ? text.charAt(end1) : (char) 0 + char c2 = left > 2 ? text.charAt(end1 + 1) : (char) 0 + int tokenLength = end1 - begin1 switch (state) { case HTML: if (isPotentialScriptletOrTag(c, left)) { if (c1 == '%') { if (c2 == '=') { - return found(JEXPR, 3); + return found(JEXPR, 3) } if (c2 == '@') { - return found(JDIRECT, 3); + return found(JDIRECT, 3) } if (c2 == '!') { - return found(JDECLAR, 3); + return found(JDECLAR, 3) } if (isStartComment(c1, c2, left)) { if (skipJComment()) - continue; + continue } - return found(JSCRIPT, 2); + return found(JSCRIPT, 2) } - boolean bStartTag = !isClosingTag(c1); + boolean bStartTag = !isClosingTag(c1) - String tagNameSpace = getTagNamespace(bStartTag ? end1 : end1 + 1); + String tagNameSpace = getTagNamespace(bStartTag ? end1 : end1 + 1) if (isTagDefinition(tagNameSpace)) { if (bStartTag) { - return foundStartOrEndTag(GSTART_TAG, tagNameSpace.length() + 2, tagNameSpace); + return foundStartOrEndTag(GSTART_TAG, tagNameSpace.length() + 2, tagNameSpace) } - return foundStartOrEndTag(GEND_TAG, tagNameSpace.length() + 3, tagNameSpace); + return foundStartOrEndTag(GEND_TAG, tagNameSpace.length() + 3, tagNameSpace) } } else if (isStartOfGExpression(c, c1) && !isEscapedGExpression()) { - return found(GEXPR, 2); + return found(GEXPR, 2) } if (c == '%' && c1 == '{') { if (c2 == '-' && left > 3 && text.charAt(end1 + 2) == '-') { if (skipGComment()) - continue; + continue } - return found(GSCRIPT, 2); + return found(GSCRIPT, 2) } if (c == '!' && c1 == '{') { - return found(GDECLAR, 2); + return found(GDECLAR, 2) } if (c == '@' && c1 == '{') { - return found(GDIRECT, 2); + return found(GDIRECT, 2) } if (tokenLength > maxHtmlLength) { - return found(HTML, 0); + return found(HTML, 0) } - break; + break case JEXPR: case JSCRIPT: case JDIRECT: case JDECLAR: if (c == '%' && c1 == '>') { - return found(HTML, 2); + return found(HTML, 2) } - break; + break case GSTART_TAG: if (isStartOfGExpression(c, c1)) { - return found(GTAG_EXPR, 2); + return found(GTAG_EXPR, 2) } if (c == '>') { - return found(HTML, 1); + return found(HTML, 1) } else if (isClosingTag(c) && c1 == '>') { - return found(GEND_EMPTY_TAG, 1); + return found(GEND_EMPTY_TAG, 1) } - break; + break case GEND_TAG: case GEND_EMPTY_TAG: if (c == '>') { - return found(HTML, 1); + return found(HTML, 1) } - break; + break case GTAG_EXPR: case GEXPR: - return parseExpression(); + return parseExpression() case GDIRECT: if (c == '}') { - return found(HTML, 1); + return found(HTML, 1) } - break; + break case GSCRIPT: if (c == '}' && c1 == '%') { - return found(HTML, 2); + return found(HTML, 2) } - break; + break case GDECLAR: if (c == '}' && (c1 == '!' || c1 == '%')) { - return found(HTML, 2); + return found(HTML, 2) } - break; + break } } } protected int parseExpression() { - char terminationChar = '}'; - char nextTerminationChar = 0; - boolean startInExpression = true; - GroovyPageExpressionParser expressionParser = new GroovyPageExpressionParser(text, end1 - 1, terminationChar, nextTerminationChar, startInExpression); - int endpos = expressionParser.parse(); + char terminationChar = '}' + char nextTerminationChar = 0 + boolean startInExpression = true + GroovyPageExpressionParser expressionParser = new GroovyPageExpressionParser(text, end1 - 1, terminationChar, nextTerminationChar, startInExpression) + int endpos = expressionParser.parse() if (endpos != -1) { - end1 = endpos + 1; - int expressionEndState = HTML; + end1 = endpos + 1 + int expressionEndState = HTML if (state == GTAG_EXPR) { - expressionEndState = GSTART_TAG; + expressionEndState = GSTART_TAG } - return found(expressionEndState, nextTerminationChar == 0 ? 1 : 2); + return found(expressionEndState, nextTerminationChar == 0 ? 1 : 2) } - throw new GrailsTagException("Unclosed GSP expression", pageName, getLineNumberForToken()); + throw new GrailsTagException('Unclosed GSP expression', pageName, getLineNumberForToken()) } private boolean isClosingTag(char c1) { - return c1 == '/'; + return c1 == '/' } private boolean isTagDefinition(String tagNameSpace) { - return tagNameSpace != null && isTagNameSpacePattern.matcher(tagNameSpace).matches(); + return tagNameSpace != null && isTagNameSpacePattern.matcher(tagNameSpace).matches() } private String getTagNamespace(int fromIndex) { - int foundColonIdx = text.indexOf(":", fromIndex); - String tagNameSpace = null; + int foundColonIdx = text.indexOf(':', fromIndex) + String tagNameSpace = null if (foundColonIdx > -1) { - tagNameSpace = text.substring(fromIndex, foundColonIdx); + tagNameSpace = text.substring(fromIndex, foundColonIdx) } - return tagNameSpace; + return tagNameSpace } private boolean isPotentialScriptletOrTag(char c, int left) { - return c == '<' && left > 3; + return c == '<' && left > 3 } private boolean isStartComment(char c1, char c2, int left) { - return c1 == '%' && c2 == '-' && left > 3 && text.charAt(end1 + 2) == '-'; + return c1 == '%' && c2 == '-' && left > 3 && text.charAt(end1 + 2) == '-' } private boolean isStartOfGExpression(char c, char c1) { - return c == '$' && c1 == '{'; + return c == '$' && c1 == '{' } /** @@ -284,43 +286,44 @@ private boolean isStartOfGExpression(char c, char c1) { * escaped this way. */ private boolean isEscapedGExpression() { - return end1 > 1 && text.charAt(end1 - 2) == '\\'; + return end1 > 1 && text.charAt(end1 - 2) == '\\' } private boolean skipComment(char c3, char c4) { - int ix = end1 + 3; + int ix = end1 + 3 for (int ixz = len - 4; ; ix++) { - if (ix > ixz) return false; + if (ix > ixz) return false if (text.charAt(ix) == '-' && text.charAt(ix + 1) == '-' && text.charAt(ix + 2) == c3 && text.charAt(ix + 3) == c4) { - break; + break } } - text = text.substring(0, --end1) + text.substring(ix + 4); - len = text.length(); - return true; + text = text.substring(0, --end1) + text.substring(ix + 4) + len = text.length() + return true } private boolean skipGComment() { - return skipComment('}', '%'); + return skipComment((char) '}', (char) '%') } private boolean skipJComment() { - return skipComment('%', '>'); + return skipComment((char) '%', (char) '>') } void reset() { - end1 = begin1 = end2 = begin2 = 0; - state = HTML; - lastNamespace = null; - lastLineNumberIndex = -1; + end1 = begin1 = end2 = begin2 = 0 + state = HTML + lastNamespace = null + lastLineNumberIndex = -1 } - public int getMaxHtmlLength() { - return maxHtmlLength; + int getMaxHtmlLength() { + return maxHtmlLength } - public void setMaxHtmlLength(int maxHtmlLength) { - this.maxHtmlLength = maxHtmlLength; + void setMaxHtmlLength(int maxHtmlLength) { + this.maxHtmlLength = maxHtmlLength } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageTypeCheckingConfig.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageTypeCheckingConfig.groovy similarity index 84% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageTypeCheckingConfig.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageTypeCheckingConfig.groovy index d1f3fc4c65d..654bded001e 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageTypeCheckingConfig.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageTypeCheckingConfig.groovy @@ -17,17 +17,18 @@ * under the License. */ -package org.grails.gsp.compiler; +package org.grails.gsp.compiler -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.ElementType +import java.lang.annotation.Retention +import java.lang.annotation.RetentionPolicy +import java.lang.annotation.Target @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) -public @interface GroovyPageTypeCheckingConfig { - String[] taglibs() default {}; +@interface GroovyPageTypeCheckingConfig { + + String[] taglibs() default [] /** * Names the page introduces for itself, through the {@code var} and {@code status} attributes of @@ -38,7 +39,7 @@ * rather than reported, so that using a tag to introduce a name does not require declaring it a * second time in the model directive.

*/ - String[] pageScopeVariables() default {}; + String[] pageScopeVariables() default [] /** * Whether a name the page never declares, and a member read from something whose type is not @@ -49,5 +50,6 @@ * has not declared the model of every page: what can be checked is checked, and what cannot is * left to run as it always has. Turning it on asks for the guarantee instead.

*/ - boolean strict() default false; + boolean strict() default false + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/PageScopeVariableScanner.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/PageScopeVariableScanner.groovy similarity index 77% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/PageScopeVariableScanner.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/PageScopeVariableScanner.groovy index 4f1c0136f9b..8ac83be3c0b 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/PageScopeVariableScanner.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/PageScopeVariableScanner.groovy @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler; +package org.grails.gsp.compiler -import java.util.Set; +import groovy.transform.CompileStatic /** * Finds the names a page introduces through the {@code var} and {@code status} attributes of the @@ -39,6 +39,7 @@ * recursing once per character until the compiling thread runs out of stack. Here the work is linear * in the page and the depth of the call stack is constant, whatever the page contains.

*/ +@CompileStatic final class PageScopeVariableScanner { private PageScopeVariableScanner() { @@ -49,21 +50,21 @@ private PageScopeVariableScanner() { * namespaced tag in {@code source}. */ static void collect(String source, Set names) { - int length = source.length(); - int i = 0; + int length = source.length() + int i = 0 while (i < length) { - int afterNamespace = source.charAt(i) == '<' ? namespaceEnd(source, i + 1) : -1; - i = afterNamespace < 0 ? i + 1 : scanTag(source, afterNamespace, names); + int afterNamespace = source.charAt(i) == '<' ? namespaceEnd(source, i + 1) : -1 + i = afterNamespace < 0 ? i + 1 : scanTag(source, afterNamespace, names) } } /** The index just past {@code \w+:} starting at {@code from}, or -1 when there is none there. */ private static int namespaceEnd(String source, int from) { - int i = from; + int i = from while (i < source.length() && isWordChar(source.charAt(i))) { - i++; + i++ } - return i > from && i < source.length() && source.charAt(i) == ':' ? i + 1 : -1; + return i > from && i < source.length() && source.charAt(i) == ':' ? i + 1 : -1 } /** @@ -71,24 +72,24 @@ private static int namespaceEnd(String source, int from) { * the index just past its closing {@code >}, or the end of the source when it has none. */ private static int scanTag(String source, int from, Set names) { - int length = source.length(); - int i = from; + int length = source.length() + int i = from while (i < length) { - char c = source.charAt(i); + char c = source.charAt(i) if (c == '>') { - return i + 1; + return i + 1 } if (isExpressionStart(source, i)) { - i = skipExpression(source, i + 2); + i = skipExpression(source, i + 2) } else if (c == '"' || c == '\'') { - i = skipAttributeValue(source, i + 1, c); + i = skipAttributeValue(source, i + 1, c) } else if (isWordChar(c) && !isWordChar(source.charAt(i - 1))) { - i = readAttributeName(source, i, names); + i = readAttributeName(source, i, names) } else { - i++; + i++ } } - return length; + return length } /** @@ -97,36 +98,36 @@ private static int scanTag(String source, int from, Set names) { * leaving the value to be stepped over as any other quoted value is. */ private static int readAttributeName(String source, int from, Set names) { - int length = source.length(); - int end = from; + int length = source.length() + int end = from while (end < length && isWordChar(source.charAt(end))) { - end++; + end++ } - String name = source.substring(from, end); - if (!name.equals("var") && !name.equals("status")) { - return end; + String name = source.substring(from, end) + if (!name.equals('var') && !name.equals('status')) { + return end } - int i = skipWhitespace(source, end); + int i = skipWhitespace(source, end) if (i >= length || source.charAt(i) != '=') { - return end; + return end } - i = skipWhitespace(source, i + 1); + i = skipWhitespace(source, i + 1) if (i >= length || (source.charAt(i) != '"' && source.charAt(i) != '\'')) { - return end; + return end } - int identifierStart = i + 1; - int identifierEnd = identifierStart; + int identifierStart = i + 1 + int identifierEnd = identifierStart if (identifierEnd < length && isIdentifierStart(source.charAt(identifierEnd))) { - identifierEnd++; + identifierEnd++ while (identifierEnd < length && isIdentifierPart(source.charAt(identifierEnd))) { - identifierEnd++; + identifierEnd++ } - char closing = identifierEnd < length ? source.charAt(identifierEnd) : 0; + char closing = identifierEnd < length ? source.charAt(identifierEnd) : (char) 0 if (closing == '"' || closing == '\'') { - names.add(source.substring(identifierStart, identifierEnd)); + names.add(source.substring(identifierStart, identifierEnd)) } } - return end; + return end } /** @@ -136,8 +137,8 @@ private static int readAttributeName(String source, int from, Set names) * the source. */ private static int skipAttributeValue(String source, int from, char quote) { - int end = new GroovyPageExpressionParser(source, from, quote, (char) 0, false).parse(); - return end < 0 ? source.length() : end + 1; + int end = new GroovyPageExpressionParser(source, from, quote, (char) 0, false).parse() + return end < 0 ? source.length() : end + 1 } /** @@ -146,32 +147,34 @@ private static int skipAttributeValue(String source, int from, char quote) { * past the closing brace, or the end of the source. */ private static int skipExpression(String source, int from) { - int end = new GroovyPageExpressionParser(source, from, '}', (char) 0, true).parse(); - return end < 0 ? source.length() : end + 1; + int end = new GroovyPageExpressionParser(source, from, (char) '}', (char) 0, true).parse() + return end < 0 ? source.length() : end + 1 } private static boolean isExpressionStart(String source, int i) { - return source.charAt(i) == '$' && i + 1 < source.length() && source.charAt(i + 1) == '{'; + return source.charAt(i) == '$' && i + 1 < source.length() && source.charAt(i + 1) == '{' } private static int skipWhitespace(String source, int from) { - int i = from; + int i = from while (i < source.length() && Character.isWhitespace(source.charAt(i))) { - i++; + i++ } - return i; + return i } /** {@code \w} as a regular expression reads it: ASCII letters, digits and underscore. */ private static boolean isWordChar(char c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'; + int code = (int) c + return (code >= 97 && code <= 122) || (code >= 65 && code <= 90) || (code >= 48 && code <= 57) || c == '_' } private static boolean isIdentifierStart(char c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '$'; + int code = (int) c + return (code >= 97 && code <= 122) || (code >= 65 && code <= 90) || c == '_' || c == '$' } private static boolean isIdentifierPart(char c) { - return isWordChar(c) || c == '$'; + return isWordChar(c) || c == '$' } } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Reverse.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Reverse.groovy similarity index 64% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Reverse.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Reverse.groovy index c4ab5a0cffc..110afd57b48 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Reverse.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Reverse.groovy @@ -16,7 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler; +package org.grails.gsp.compiler + +import groovy.transform.CompileStatic /** * NOTE: Based on work done by on the GSP standalone project (https://gsp.dev.java.net/) @@ -25,40 +27,43 @@ * * @author Troy Heninger */ +@CompileStatic class Reverse implements CharSequence { - private CharSequence text; - private int start, end, anchor; + + private CharSequence text + private int start, end, anchor Reverse(CharSequence text) { - this(text, 0, text.length()); + this(text, 0, text.length()) } Reverse(CharSequence text, int start, int end) { - this.text = text; - this.start = start; - this.end = end; - anchor = end - 1; + this.text = text + this.start = start + this.end = end + anchor = end - 1 } - public char charAt(int index) { - return text.charAt(anchor - index); + char charAt(int index) { + return text.charAt(anchor - index) } - public int length() { - return end - start; + int length() { + return end - start } - public CharSequence subSequence(int start, int end) { - return new Reverse(text, anchor - end, anchor - start); + CharSequence subSequence(int start, int end) { + return new Reverse(text, anchor - end, anchor - start) } @Override - public String toString() { - int len = length(); - StringBuilder buf = new StringBuilder(len); + String toString() { + int len = length() + StringBuilder buf = new StringBuilder(len) for (int ix = anchor; ix >= start; ix--) { - buf.append(text.charAt(ix)); + buf.append(text.charAt(ix)) } - return buf.toString(); + return buf.toString() } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Strip.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Strip.groovy similarity index 56% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Strip.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Strip.groovy index 5f31f043d6b..ed1d5768749 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Strip.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Strip.groovy @@ -16,10 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler; +package org.grails.gsp.compiler -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.regex.Matcher +import java.util.regex.Pattern + +import groovy.transform.CompileStatic /** * NOTE: Based on work done by on the GSP standalone project (https://gsp.dev.java.net/) @@ -29,51 +31,54 @@ * @author Troy Heninger * Date: Jan 10, 2004 */ +@CompileStatic class Strip { - private static Pattern stripTag = Pattern.compile("\\^([a-zA-Z]+)%\\{([^}]|\\}[^%])*\\}%"); - private static Pattern anyTag = Pattern.compile("((\\^[a-zA-Z])?%\\{([^}]|\\}[^%])*\\}%|[$@]\\{[^}]*\\})"); + + private static Pattern stripTag = Pattern.compile('\\^([a-zA-Z]+)%\\{([^}]|\\}[^%])*\\}%') + private static Pattern anyTag = Pattern.compile('((\\^[a-zA-Z])?%\\{([^}]|\\}[^%])*\\}%|[\$@]\\{[^}]*\\})') // not thread-safe but only used in the GroovyPageScanner constructor - private StringBuilder text; + private StringBuilder text Strip(CharSequence text) { - this.text = new StringBuilder(text.toString()); + this.text = new StringBuilder(text.toString()) } void strip(int index) { - Matcher match = stripTag.matcher(text); + Matcher match = stripTag.matcher(text) if (match.find(index)) { - strip(match.end()); - String tag = match.group(1); - int start = match.start() + 1 + tag.length(); // begin after '^tag'; at the '%{' - int end = match.end(); - Pattern patAfter = Pattern.compile("|[^>a-zA-Z][^>]*>)\\s*", Pattern.CASE_INSENSITIVE); - Matcher matchAfter = patAfter.matcher(text); + strip(match.end()) + String tag = match.group(1) + int start = match.start() + 1 + tag.length() // begin after '^tag'; at the '%{' + int end = match.end() + Pattern patAfter = Pattern.compile('|[^>a-zA-Z][^>]*>)\\s*', Pattern.CASE_INSENSITIVE) + Matcher matchAfter = patAfter.matcher(text) if (matchAfter.find(end)) { - int end2 = matchAfter.end(); - Matcher matchAny = anyTag.matcher(text.subSequence(0, end2)); - if (matchAny.find(end)) end2 = matchAny.start(); - Pattern nextTagPat = Pattern.compile("<" + tag + "(\\s|>)", Pattern.CASE_INSENSITIVE); - Matcher matchNext = nextTagPat.matcher(text.subSequence(0, end2)); - if (matchNext.find(end)) end2 = matchNext.start(); + int end2 = matchAfter.end() + Matcher matchAny = anyTag.matcher(text.subSequence(0, end2)) + if (matchAny.find(end)) end2 = matchAny.start() + Pattern nextTagPat = Pattern.compile('<' + tag + '(\\s|>)', Pattern.CASE_INSENSITIVE) + Matcher matchNext = nextTagPat.matcher(text.subSequence(0, end2)) + if (matchNext.find(end)) end2 = matchNext.start() // System.out.println("Stripping " + text.subSequence(end, end2)); - text.delete(end, end2); + text.delete(end, end2) } - Pattern patBefore = Pattern.compile(new Reverse("*s\\<" + tag).toString(), - Pattern.CASE_INSENSITIVE); - Matcher matchBefore = patBefore.matcher(new Reverse(text, 0, start)); + Pattern patBefore = Pattern.compile(new Reverse('*s\\<' + tag).toString(), + Pattern.CASE_INSENSITIVE) + Matcher matchBefore = patBefore.matcher(new Reverse(text, 0, start)) if (matchBefore.find()) { - int start2 = start - matchBefore.end(); - Matcher matchAny = anyTag.matcher(text.subSequence(0, start)); - if (matchAny.find(start2)) start2 = matchAny.end(); + int start2 = start - matchBefore.end() + Matcher matchAny = anyTag.matcher(text.subSequence(0, start)) + if (matchAny.find(start2)) start2 = matchAny.end() // System.out.println("Stripping " + text.subSequence(start2, start)); - text.delete(start2, start); + text.delete(start2, start) } } } @Override - public String toString() { - return text.toString(); + String toString() { + return text.toString() } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Tokens.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Tokens.groovy similarity index 69% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Tokens.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Tokens.groovy index 02499f8ae5d..633fbd6e171 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Tokens.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/Tokens.groovy @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler; +package org.grails.gsp.compiler /** * NOTE: Based on work done by on the GSP standalone project (https://gsp.dev.java.net/) @@ -29,18 +29,20 @@ * Date: Jan 10, 2004 */ interface Tokens { - int EOF = -1; - int HTML = 0; - int JEXPR = 1; // <%= ... %> - int JSCRIPT = 2; // <% .... %> - int JDIRECT = 3; // <%@ ... %> - int JDECLAR = 4; // <%! ... %> - int GEXPR = 11; // ${ ... } - int GSCRIPT = 12; // %{ ... }% - int GDIRECT = 13; // @{ ... } - int GDECLAR = 14; // !{ ... }! - int GSTART_TAG = 15; // - int GEND_TAG = 16; // - int GTAG_EXPR = 17; // ${..} - int GEND_EMPTY_TAG = 18; + + int EOF = -1 + int HTML = 0 + int JEXPR = 1 // <%= ... %> + int JSCRIPT = 2 // <% .... %> + int JDIRECT = 3 // <%@ ... %> + int JDECLAR = 4 // <%! ... %> + int GEXPR = 11 // ${ ... } + int GSCRIPT = 12 // %{ ... }% + int GDIRECT = 13 // @{ ... } + int GDECLAR = 14 // !{ ... }! + int GSTART_TAG = 15 // + int GEND_TAG = 16 // + int GTAG_EXPR = 17 // ${..} + int GEND_EMPTY_TAG = 18 + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GrailsTag.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GrailsTag.groovy similarity index 77% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GrailsTag.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GrailsTag.groovy index 8772f0014e8..4a6ffda0b95 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GrailsTag.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GrailsTag.groovy @@ -16,10 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler.tags; - -import java.io.Writer; -import java.util.Map; +package org.grails.gsp.compiler.tags /** * Allows to tag implementation to be abstracted from the JSP custom tag spec.. hence allowing @@ -27,43 +24,44 @@ * * @author Graeme Rocher */ -public interface GrailsTag { +interface GrailsTag { - @SuppressWarnings("rawtypes") - void init(Map tagContext); + @SuppressWarnings('rawtypes') + void init(Map tagContext) /** * Sets the writer that processes the tag * @param w */ - void setWriter(Writer w); + void setWriter(Writer w) /** * Sets the attributes of the tag * @param attributes */ - @SuppressWarnings("rawtypes") - void setAttributes(Map attributes); + @SuppressWarnings('rawtypes') + void setAttributes(Map attributes) /** * Sets an attribute of the tag * @param name * @param value */ - void setAttribute(String name, Object value); + void setAttribute(String name, Object value) /** * Process the start tag */ - void doStartTag(); + void doStartTag() /** * process the end tag */ - void doEndTag(); + void doEndTag() /** * @return The name of the tag */ - String getName(); + String getName() + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GrailsTagRegistry.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GrailsTagRegistry.groovy similarity index 61% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GrailsTagRegistry.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GrailsTagRegistry.groovy index 09d1d1c315d..78325b3ca34 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GrailsTagRegistry.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GrailsTagRegistry.groovy @@ -16,76 +16,79 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler.tags; +package org.grails.gsp.compiler.tags -import java.lang.reflect.InvocationTargetException; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.lang.reflect.InvocationTargetException +import java.util.concurrent.ConcurrentHashMap -import org.grails.taglib.GrailsTagException; +import groovy.transform.CompileStatic + +import org.grails.taglib.GrailsTagException /** * A registry for holding all Grails tag implementations. * * @author Graeme Rocher */ -public class GrailsTagRegistry { +@CompileStatic +class GrailsTagRegistry { - private static GrailsTagRegistry instance = new GrailsTagRegistry(); + private static GrailsTagRegistry instance = new GrailsTagRegistry() - private static Map> tagRegistry = new ConcurrentHashMap<>(); + private static Map> tagRegistry = new ConcurrentHashMap<>() static { - instance.registerTag(GroovyEachTag.TAG_NAME, GroovyEachTag.class); - instance.registerTag(GroovyIfTag.TAG_NAME, GroovyIfTag.class); - instance.registerTag(GroovyUnlessTag.TAG_NAME, GroovyUnlessTag.class); - instance.registerTag(GroovyElseTag.TAG_NAME, GroovyElseTag.class); - instance.registerTag(GroovyElseIfTag.TAG_NAME, GroovyElseIfTag.class); - instance.registerTag(GroovyFindAllTag.TAG_NAME, GroovyFindAllTag.class); - instance.registerTag(GroovyCollectTag.TAG_NAME, GroovyCollectTag.class); - instance.registerTag(GroovyGrepTag.TAG_NAME, GroovyGrepTag.class); - instance.registerTag(GroovyWhileTag.TAG_NAME, GroovyWhileTag.class); - instance.registerTag(GroovyDefTag.TAG_NAME, GroovyDefTag.class); + instance.registerTag(GroovyEachTag.TAG_NAME, GroovyEachTag) + instance.registerTag(GroovyIfTag.TAG_NAME, GroovyIfTag) + instance.registerTag(GroovyUnlessTag.TAG_NAME, GroovyUnlessTag) + instance.registerTag(GroovyElseTag.TAG_NAME, GroovyElseTag) + instance.registerTag(GroovyElseIfTag.TAG_NAME, GroovyElseIfTag) + instance.registerTag(GroovyFindAllTag.TAG_NAME, GroovyFindAllTag) + instance.registerTag(GroovyCollectTag.TAG_NAME, GroovyCollectTag) + instance.registerTag(GroovyGrepTag.TAG_NAME, GroovyGrepTag) + instance.registerTag(GroovyWhileTag.TAG_NAME, GroovyWhileTag) + instance.registerTag(GroovyDefTag.TAG_NAME, GroovyDefTag) } private GrailsTagRegistry() { // singleton } - public static GrailsTagRegistry getInstance() { - return instance; + static GrailsTagRegistry getInstance() { + return instance } - public void registerTag(String tagName, Class tag) { - tagRegistry.put(tagName, tag); + void registerTag(String tagName, Class tag) { + tagRegistry.put(tagName, tag) } - public boolean tagSupported(String tagName) { - return tagRegistry.containsKey(tagName); + boolean tagSupported(String tagName) { + return tagRegistry.containsKey(tagName) } - public boolean isSyntaxTag(String tagName) { + boolean isSyntaxTag(String tagName) { if (tagRegistry.containsKey(tagName)) { - return GroovySyntaxTag.class.isAssignableFrom(tagRegistry.get(tagName)); + return GroovySyntaxTag.isAssignableFrom(tagRegistry.get(tagName)) } - return false; + return false } - public GrailsTag newTag(String tagName) { + GrailsTag newTag(String tagName) { if (!tagRegistry.containsKey(tagName)) { - throw new GrailsTagException("Tag [" + tagName + "] is not a a valid grails tag"); + throw new GrailsTagException('Tag [' + tagName + '] is not a a valid grails tag') } - Class tagClass = tagRegistry.get(tagName); + Class tagClass = tagRegistry.get(tagName) try { - return (GrailsTag) tagClass.getDeclaredConstructor().newInstance(); + return (GrailsTag) tagClass.getDeclaredConstructor().newInstance() } catch (InstantiationException | InvocationTargetException | NoSuchMethodException e) { - throw new GrailsTagException("Instantiation error loading tag [" + tagName + "]: " + e.getMessage(), e); + throw new GrailsTagException('Instantiation error loading tag [' + tagName + ']: ' + e.getMessage(), e) } catch (IllegalAccessException e) { - throw new GrailsTagException("Illegal access error loading tag [" + tagName + "]: " + e.getMessage(), e); + throw new GrailsTagException('Illegal access error loading tag [' + tagName + ']: ' + e.getMessage(), e) } } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyCollectTag.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyCollectTag.groovy similarity index 64% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyCollectTag.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyCollectTag.groovy index 2e1945696ce..d79cbf72ef5 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyCollectTag.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyCollectTag.groovy @@ -16,8 +16,11 @@ * specific language governing permissions and limitations * under the License. */ +@SuppressWarnings('UnnecessarySemicolon') package org.grails.gsp.compiler.tags; +import groovy.transform.CompileStatic; + import grails.util.GrailsStringUtils; import org.grails.taglib.GrailsTagException; @@ -34,47 +37,51 @@ * @author Graeme Rocher * @since 19-Jan-2006 */ -public class GroovyCollectTag extends GroovySyntaxTag { +// TODO(groovyism-cleanup): semicolons kept to preserve rename-similarity against the original .java (see matrei's review on #16576). Removed by the stacked groovyism-cleanup PR. +@SuppressWarnings(['UnnecessarySemicolon']) +@CompileStatic +class GroovyCollectTag extends GroovySyntaxTag { - public static final String TAG_NAME = "collect"; - private static final String ATTRIBUTE_EXPR = "expr"; + public static final String TAG_NAME = 'collect'; + private static final String ATTRIBUTE_EXPR = 'expr'; @Override - public boolean isKeepPrecedingWhiteSpace() { + boolean isKeepPrecedingWhiteSpace() { return true; } @Override - public boolean isAllowPrecedingContent() { + boolean isAllowPrecedingContent() { return true; } - public void doStartTag() { + void doStartTag() { String in = attributes.get(ATTRIBUTE_IN); if (GrailsStringUtils.isBlank(in)) { - throw new GrailsTagException("Tag [" + TAG_NAME + "] missing required attribute [" + ATTRIBUTE_IN + "]", parser.getPageName(), parser.getCurrentOutputLineNumber()); + throw new GrailsTagException('Tag [' + TAG_NAME + '] missing required attribute [' + ATTRIBUTE_IN + ']', parser.getPageName(), parser.getCurrentOutputLineNumber()); } String expr = attributes.get(ATTRIBUTE_EXPR); if (GrailsStringUtils.isBlank(expr)) { - throw new GrailsTagException("Tag [" + TAG_NAME + "] missing required attribute [" + ATTRIBUTE_EXPR + "]", parser.getPageName(), parser.getCurrentOutputLineNumber()); + throw new GrailsTagException('Tag [' + TAG_NAME + '] missing required attribute [' + ATTRIBUTE_EXPR + ']', parser.getPageName(), parser.getCurrentOutputLineNumber()); } StringBuilder builder = new StringBuilder(); builder.append(in); - builder.append(".collect {"); + builder.append('.collect {'); expr = calculateExpression(expr); builder.append(expr); - builder.append("}"); + builder.append('}'); doEachMethod(builder.toString()); } - public void doEndTag() { - out.println("}"); + void doEndTag() { + out.println('}'); } - public String getName() { + String getName() { return TAG_NAME; } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyConditionalTag.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyConditionalTag.groovy similarity index 53% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyConditionalTag.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyConditionalTag.groovy index 72069715061..8f8af80a1b7 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyConditionalTag.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyConditionalTag.groovy @@ -16,66 +16,70 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler.tags; +package org.grails.gsp.compiler.tags -import grails.util.GrailsStringUtils; -import org.grails.taglib.GrailsTagException; +import groovy.transform.CompileStatic +import grails.util.GrailsStringUtils +import org.grails.taglib.GrailsTagException + +@CompileStatic abstract class GroovyConditionalTag extends GroovySyntaxTag { - static final String ATTRIBUTE_TEST = "test"; - static final String ATTRIBUTE_ENV = "env"; + static final String ATTRIBUTE_TEST = 'test' + static final String ATTRIBUTE_ENV = 'env' - public void doStartTag() { - String env = attributeValueOrNull(ATTRIBUTE_ENV); - String test = attributeValueOrNull(ATTRIBUTE_TEST); + void doStartTag() { + String env = attributeValueOrNull(ATTRIBUTE_ENV) + String test = attributeValueOrNull(ATTRIBUTE_TEST) if ((env == null) && (test == null)) { - throw new GrailsTagException("Tag [" + getName() + - "] must have one or both of the attributes [" + - ATTRIBUTE_TEST + "] or [" + ATTRIBUTE_ENV + "]", parser.getPageName(), parser.getCurrentOutputLineNumber()); + throw new GrailsTagException('Tag [' + getName() + + '] must have one or both of the attributes [' + + ATTRIBUTE_TEST + '] or [' + ATTRIBUTE_ENV + ']', parser.getPageName(), parser.getCurrentOutputLineNumber()) } - String envExpression = environmentExpressionOrTrue(env); - String testExpression = testExpressionOrTrue(test); + String envExpression = environmentExpressionOrTrue(env) + String testExpression = testExpressionOrTrue(test) - outputStartTag(envExpression, testExpression); + outputStartTag(envExpression, testExpression) } - protected abstract void outputStartTag(String envExpression, String testExpression); + protected abstract void outputStartTag(String envExpression, String testExpression) - public void doEndTag() { - out.println("}"); + void doEndTag() { + out.println('}') } protected String attributeValueOrNull(String attributeName) { - String attributeValue = attributes.get(attributeName); - return GrailsStringUtils.isBlank(attributeValue) ? null : attributeValue; + String attributeValue = attributes.get(attributeName) + return GrailsStringUtils.isBlank(attributeValue) ? null : attributeValue } private String environmentExpressionOrTrue(String envAttributeValue) { - String expression = "true"; + String expression = 'true' if (envAttributeValue != null) { - expression = "(grails.util.Environment.current.name == '" + calculateExpression(envAttributeValue) + "')"; + expression = "(grails.util.Environment.current.name == '" + calculateExpression(envAttributeValue) + "')" } - return expression; + return expression } private String testExpressionOrTrue(String testAttributeValue) { - String expression = "true"; + String expression = 'true' if (testAttributeValue != null) { - expression = "(" + testAttributeValue + ")"; + expression = '(' + testAttributeValue + ')' } - return expression; + return expression } @Override - public boolean isKeepPrecedingWhiteSpace() { - return true; + boolean isKeepPrecedingWhiteSpace() { + return true } @Override - public boolean isAllowPrecedingContent() { - return true; + boolean isAllowPrecedingContent() { + return true } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyDefTag.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyDefTag.groovy similarity index 52% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyDefTag.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyDefTag.groovy index 0397ac3dc61..c239900df05 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyDefTag.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyDefTag.groovy @@ -16,53 +16,56 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler.tags; +package org.grails.gsp.compiler.tags -import grails.util.GrailsStringUtils; -import org.grails.taglib.GrailsTagException; +import groovy.transform.CompileStatic + +import grails.util.GrailsStringUtils +import org.grails.taglib.GrailsTagException /** * Allows defining of variables within the page context. * * @author Graeme Rocher */ -public class GroovyDefTag extends GroovySyntaxTag { +@CompileStatic +class GroovyDefTag extends GroovySyntaxTag { - public static final String TAG_NAME = "def"; - private static final String ATTRIBUTE_VALUE = "value"; - private static final String ATTRIBUTE_TYPE = "type"; + public static final String TAG_NAME = 'def' + private static final String ATTRIBUTE_VALUE = 'value' + private static final String ATTRIBUTE_TYPE = 'type' - public void doStartTag() { - String expr = attributes.get(ATTRIBUTE_VALUE); + void doStartTag() { + String expr = attributes.get(ATTRIBUTE_VALUE) if (GrailsStringUtils.isBlank(expr)) { - throw new GrailsTagException("Tag [" + TAG_NAME + "] missing required attribute [" + ATTRIBUTE_VALUE + "]", parser.getPageName(), parser.getCurrentOutputLineNumber()); + throw new GrailsTagException('Tag [' + TAG_NAME + '] missing required attribute [' + ATTRIBUTE_VALUE + ']', parser.getPageName(), parser.getCurrentOutputLineNumber()) } - expr = groovyExpressionFor(expr); + expr = groovyExpressionFor(expr) - String var = attributes.get(ATTRIBUTE_VAR); + String var = attributes.get(ATTRIBUTE_VAR) if (GrailsStringUtils.isBlank(var)) { - throw new GrailsTagException("Tag [" + TAG_NAME + "] missing required attribute [" + ATTRIBUTE_VAR + "]", parser.getPageName(), parser.getCurrentOutputLineNumber()); + throw new GrailsTagException('Tag [' + TAG_NAME + '] missing required attribute [' + ATTRIBUTE_VAR + ']', parser.getPageName(), parser.getCurrentOutputLineNumber()) } - var = extractAttributeValue(var); + var = extractAttributeValue(var) - String typeName = attributes.get(ATTRIBUTE_TYPE); + String typeName = attributes.get(ATTRIBUTE_TYPE) if (GrailsStringUtils.isBlank(typeName)) { - typeName = "def"; + typeName = 'def' } else { - typeName = extractAttributeValue(typeName); + typeName = extractAttributeValue(typeName) } - out.print(typeName + " "); - out.print(var); - out.print('='); + out.print(typeName + ' ') + out.print(var) + out.print('=') - if (typeName.equals("def") || typeName.equals("Object")) { - out.println(expr); + if (typeName.equals('def') || typeName.equals('Object')) { + out.println(expr) } else { // A Groovy cast rather than Class.cast, which only accepts what is already of the type // and so rejects every conversion Groovy would otherwise have made. The expression is // parenthesised because it is written by the page and may be a GString or an operation. - out.println("(" + typeName + ") (" + expr + ")"); + out.println('(' + typeName + ') (' + expr + ')') } } @@ -74,31 +77,32 @@ public void doStartTag() { * the quoting a plain value carries is undone here, so that naming a variable still reads it. */ private static String groovyExpressionFor(String value) { - String text = value.trim(); - if (text.contains("${")) { - return text; + String text = value.trim() + if (text.contains('\${')) { + return text } - if ((text.startsWith("\"") && text.endsWith("\"")) || (text.startsWith("'") && text.endsWith("'"))) { - text = text.substring(1, text.length() - 1).trim(); + if ((text.startsWith('"') && text.endsWith('"')) || (text.startsWith("'") && text.endsWith("'"))) { + text = text.substring(1, text.length() - 1).trim() } - return text; + return text } - public void doEndTag() { + void doEndTag() { // do nothing } - public String getName() { - return TAG_NAME; + String getName() { + return TAG_NAME } @Override - public boolean isKeepPrecedingWhiteSpace() { - return true; + boolean isKeepPrecedingWhiteSpace() { + return true } @Override - public boolean isAllowPrecedingContent() { - return true; + boolean isAllowPrecedingContent() { + return true } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyEachTag.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyEachTag.groovy similarity index 56% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyEachTag.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyEachTag.groovy index e45009bcdc9..aecafe8d348 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyEachTag.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyEachTag.groovy @@ -16,42 +16,46 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler.tags; +package org.grails.gsp.compiler.tags -import grails.util.GrailsStringUtils; -import org.grails.taglib.GrailsTagException; +import groovy.transform.CompileStatic + +import grails.util.GrailsStringUtils +import org.grails.taglib.GrailsTagException /** * @author Graeme Rocher */ -public class GroovyEachTag extends GroovySyntaxTag { +@CompileStatic +class GroovyEachTag extends GroovySyntaxTag { - public static final String TAG_NAME = "each"; + public static final String TAG_NAME = 'each' - public void doStartTag() { - String in = attributes.get(ATTRIBUTE_IN); + void doStartTag() { + String in = attributes.get(ATTRIBUTE_IN) if (GrailsStringUtils.isBlank(in)) { - throw new GrailsTagException("Tag [" + TAG_NAME + "] missing required attribute [" + ATTRIBUTE_IN + "]", parser.getPageName(), parser.getCurrentOutputLineNumber()); + throw new GrailsTagException('Tag [' + TAG_NAME + '] missing required attribute [' + ATTRIBUTE_IN + ']', parser.getPageName(), parser.getCurrentOutputLineNumber()) } - doEachMethod(in); + doEachMethod(in) } - public void doEndTag() { - endEachMethod(); + void doEndTag() { + endEachMethod() } - public String getName() { - return TAG_NAME; + String getName() { + return TAG_NAME } @Override - public boolean isKeepPrecedingWhiteSpace() { - return true; + boolean isKeepPrecedingWhiteSpace() { + return true } @Override - public boolean isAllowPrecedingContent() { - return true; + boolean isAllowPrecedingContent() { + return true } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyElseIfTag.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyElseIfTag.groovy similarity index 64% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyElseIfTag.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyElseIfTag.groovy index 3236f67c1fa..d1151c6254f 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyElseIfTag.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyElseIfTag.groovy @@ -16,37 +16,41 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler.tags; +package org.grails.gsp.compiler.tags -public class GroovyElseIfTag extends GroovyConditionalTag { +import groovy.transform.CompileStatic - public static final String TAG_NAME = "elseif"; +@CompileStatic +class GroovyElseIfTag extends GroovyConditionalTag { + + public static final String TAG_NAME = 'elseif' @Override protected void outputStartTag(String env, String test) { - out.print("else if ("); - out.print(env); - out.print(" && "); - out.print(test); - out.println(") {"); + out.print('else if (') + out.print(env) + out.print(' && ') + out.print(test) + out.println(') {') } @Override - public void doEndTag() { - out.println("}"); + void doEndTag() { + out.println('}') } - public String getName() { - return TAG_NAME; + String getName() { + return TAG_NAME } @Override - public boolean isKeepPrecedingWhiteSpace() { - return false; + boolean isKeepPrecedingWhiteSpace() { + return false } @Override - public boolean isAllowPrecedingContent() { - return false; + boolean isAllowPrecedingContent() { + return false } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyElseTag.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyElseTag.groovy similarity index 66% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyElseTag.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyElseTag.groovy index 621c26ed4a5..c85b4bce675 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyElseTag.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyElseTag.groovy @@ -16,34 +16,38 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler.tags; +package org.grails.gsp.compiler.tags + +import groovy.transform.CompileStatic /** * @author Graeme Rocher */ -public class GroovyElseTag extends GroovySyntaxTag { +@CompileStatic +class GroovyElseTag extends GroovySyntaxTag { - public static final String TAG_NAME = "else"; + public static final String TAG_NAME = 'else' - public void doStartTag() { - out.println("else {"); + void doStartTag() { + out.println('else {') } - public void doEndTag() { - out.println("}"); + void doEndTag() { + out.println('}') } - public String getName() { - return TAG_NAME; + String getName() { + return TAG_NAME } @Override - public boolean isKeepPrecedingWhiteSpace() { - return false; + boolean isKeepPrecedingWhiteSpace() { + return false } @Override - public boolean isAllowPrecedingContent() { - return false; + boolean isAllowPrecedingContent() { + return false } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyFindAllTag.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyFindAllTag.groovy similarity index 65% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyFindAllTag.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyFindAllTag.groovy index a25e0ef1319..3478a86769d 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyFindAllTag.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyFindAllTag.groovy @@ -16,8 +16,11 @@ * specific language governing permissions and limitations * under the License. */ +@SuppressWarnings('UnnecessarySemicolon') package org.grails.gsp.compiler.tags; +import groovy.transform.CompileStatic; + import grails.util.GrailsStringUtils; import org.grails.taglib.GrailsTagException; @@ -25,7 +28,7 @@ * Example: * *
- * {@code 
+ * {@code
  *  
  *        

${it}

*
@@ -35,46 +38,50 @@ * @author Graeme Rocher * @since 19-Jan-2006 */ -public class GroovyFindAllTag extends GroovySyntaxTag { +// TODO(groovyism-cleanup): semicolons kept to preserve rename-similarity against the original .java (see matrei's review on #16576). Removed by the stacked groovyism-cleanup PR. +@SuppressWarnings(['UnnecessarySemicolon']) +@CompileStatic +class GroovyFindAllTag extends GroovySyntaxTag { - public static final String TAG_NAME = "findAll"; - private static final String ATTRIBUTE_EXPR = "expr"; + public static final String TAG_NAME = 'findAll'; + private static final String ATTRIBUTE_EXPR = 'expr'; @Override - public boolean isKeepPrecedingWhiteSpace() { + boolean isKeepPrecedingWhiteSpace() { return false; } @Override - public boolean isAllowPrecedingContent() { + boolean isAllowPrecedingContent() { return true; } - public void doStartTag() { + void doStartTag() { String in = attributes.get(ATTRIBUTE_IN); if (GrailsStringUtils.isBlank(in)) { - throw new GrailsTagException("Tag [" + TAG_NAME + "] missing required attribute [" + ATTRIBUTE_IN + "]", parser.getPageName(), parser.getCurrentOutputLineNumber()); + throw new GrailsTagException('Tag [' + TAG_NAME + '] missing required attribute [' + ATTRIBUTE_IN + ']', parser.getPageName(), parser.getCurrentOutputLineNumber()); } String expr = attributes.get(ATTRIBUTE_EXPR); if (GrailsStringUtils.isBlank(expr)) { - throw new GrailsTagException("Tag [" + TAG_NAME + "] missing required attribute [" + ATTRIBUTE_EXPR + "]", parser.getPageName(), parser.getCurrentOutputLineNumber()); + throw new GrailsTagException('Tag [' + TAG_NAME + '] missing required attribute [' + ATTRIBUTE_EXPR + ']', parser.getPageName(), parser.getCurrentOutputLineNumber()); } StringBuilder builder = new StringBuilder(); builder.append(in); - builder.append(".findAll {"); + builder.append('.findAll {'); expr = calculateExpression(expr); builder.append(expr); - builder.append("}"); + builder.append('}'); doEachMethod(builder.toString()); } - public void doEndTag() { + void doEndTag() { endEachMethod(); } - public String getName() { + String getName() { return TAG_NAME; } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyGrepTag.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyGrepTag.groovy similarity index 65% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyGrepTag.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyGrepTag.groovy index ba61314b7f1..c2de6d83656 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyGrepTag.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyGrepTag.groovy @@ -16,8 +16,11 @@ * specific language governing permissions and limitations * under the License. */ +@SuppressWarnings('UnnecessarySemicolon') package org.grails.gsp.compiler.tags; +import groovy.transform.CompileStatic; + import grails.util.GrailsStringUtils; import org.grails.taglib.GrailsTagException; @@ -26,7 +29,7 @@ * Example: * *
- * {@code 
+ * {@code
  *  
  *        

${it}

*
@@ -35,46 +38,50 @@ * * @author Graeme Rocher */ -public class GroovyGrepTag extends GroovySyntaxTag { +// TODO(groovyism-cleanup): semicolons kept to preserve rename-similarity against the original .java (see matrei's review on #16576). Removed by the stacked groovyism-cleanup PR. +@SuppressWarnings(['UnnecessarySemicolon']) +@CompileStatic +class GroovyGrepTag extends GroovySyntaxTag { - public static final String TAG_NAME = "grep"; - private static final String ATTRIBUTE_FILTER = "filter"; + public static final String TAG_NAME = 'grep'; + private static final String ATTRIBUTE_FILTER = 'filter'; @Override - public boolean isKeepPrecedingWhiteSpace() { + boolean isKeepPrecedingWhiteSpace() { return false; } @Override - public boolean isAllowPrecedingContent() { + boolean isAllowPrecedingContent() { return true; } - public void doStartTag() { + void doStartTag() { String in = attributes.get(ATTRIBUTE_IN); if (GrailsStringUtils.isBlank(in)) { - throw new GrailsTagException("Tag [" + TAG_NAME + "] missing required attribute [" + ATTRIBUTE_IN + "]", parser.getPageName(), parser.getCurrentOutputLineNumber()); + throw new GrailsTagException('Tag [' + TAG_NAME + '] missing required attribute [' + ATTRIBUTE_IN + ']', parser.getPageName(), parser.getCurrentOutputLineNumber()); } String filter = attributes.get(ATTRIBUTE_FILTER); if (GrailsStringUtils.isBlank(filter)) { - throw new GrailsTagException("Tag [" + TAG_NAME + "] missing required attribute [" + ATTRIBUTE_FILTER + "]", parser.getPageName(), parser.getCurrentOutputLineNumber()); + throw new GrailsTagException('Tag [' + TAG_NAME + '] missing required attribute [' + ATTRIBUTE_FILTER + ']', parser.getPageName(), parser.getCurrentOutputLineNumber()); } StringBuilder builder = new StringBuilder(); builder.append(in); - builder.append(".grep("); + builder.append('.grep('); filter = calculateExpression(filter); builder.append(filter); - builder.append(")"); + builder.append(')'); doEachMethod(builder.toString()); } - public void doEndTag() { + void doEndTag() { endEachMethod(); } - public String getName() { + String getName() { return TAG_NAME; } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyIfTag.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyIfTag.groovy similarity index 71% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyIfTag.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyIfTag.groovy index ae67ba35117..f93b48a4fba 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyIfTag.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyIfTag.groovy @@ -16,21 +16,26 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler.tags; +package org.grails.gsp.compiler.tags -public class GroovyIfTag extends GroovyConditionalTag { - public static final String TAG_NAME = "if"; +import groovy.transform.CompileStatic + +@CompileStatic +class GroovyIfTag extends GroovyConditionalTag { + + public static final String TAG_NAME = 'if' @Override protected void outputStartTag(String envExpression, String testExpression) { - out.print("if("); - out.print(envExpression); - out.print(" && "); - out.print(testExpression); - out.println(") {"); + out.print('if(') + out.print(envExpression) + out.print(' && ') + out.print(testExpression) + out.println(') {') } - public String getName() { - return TAG_NAME; + String getName() { + return TAG_NAME } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovySyntaxTag.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovySyntaxTag.groovy similarity index 66% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovySyntaxTag.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovySyntaxTag.groovy index b480f071485..e119003130b 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovySyntaxTag.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovySyntaxTag.groovy @@ -16,14 +16,10 @@ * specific language governing permissions and limitations * under the License. */ +@SuppressWarnings('UnnecessarySemicolon') package org.grails.gsp.compiler.tags; -import java.io.PrintWriter; -import java.io.Writer; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - +import groovy.transform.CompileStatic; import org.springframework.util.Assert; import grails.util.GrailsStringUtils; @@ -40,14 +36,18 @@ * * @author Graeme Rocher */ -public abstract class GroovySyntaxTag implements GrailsTag { - - private static final String ERROR_NO_VAR_WITH_STATUS = "When using with a [status] attribute, you must also define a [var]. eg. "; - private static final String ERROR_NO_VAR_WITH_COMPILE_STATIC = "When using in CompileStatic mode, you must also define a [var]. eg. "; - protected static final String ATTRIBUTE_IN = "in"; - protected static final String ATTRIBUTE_VAR = "var"; - protected static final String ATTRIBUTES_STATUS = "status"; - @SuppressWarnings("rawtypes") +// TODO(groovyism-cleanup): semicolons kept to preserve rename-similarity against the original .java (see matrei's review on #16576). Removed by the stacked groovyism-cleanup PR. +@SuppressWarnings(['UnnecessarySemicolon']) +@CompileStatic +abstract class GroovySyntaxTag implements GrailsTag { + + private static final String ERROR_NO_VAR_WITH_STATUS = 'When using with a [status] attribute, you must also define a [var]. eg. '; + private static final String ERROR_NO_VAR_WITH_COMPILE_STATIC = 'When using in CompileStatic mode, you must also define a [var]. eg. '; + protected static final String ATTRIBUTE_IN = 'in'; + protected static final String ATTRIBUTE_VAR = 'var'; + protected static final String ATTRIBUTES_STATUS = 'status'; + + @SuppressWarnings('rawtypes') protected Map tagContext; protected PrintWriter out; protected Map attributes = new HashMap<>(); @@ -55,10 +55,10 @@ public abstract class GroovySyntaxTag implements GrailsTag { protected String foreachRenamedIt; - @SuppressWarnings("rawtypes") - public void init(Map context) { + @SuppressWarnings('rawtypes') + void init(Map context) { tagContext = context; - parser = (GroovyPageParser) context.get(GroovyPageParser.class); + parser = (GroovyPageParser) context.get(GroovyPageParser); Object outObj = context.get(GroovyPage.OUT); if (outObj instanceof PrintWriter) { out = (PrintWriter) context.get(GroovyPage.OUT); @@ -69,21 +69,21 @@ protected boolean isCompileStaticMode() { return parser != null && parser.isCompileStaticMode(); } - public void setWriter(Writer w) { - Assert.isInstanceOf(PrintWriter.class, w, "A GroovySynax tag requires a java.io.PrintWriter instance"); + void setWriter(Writer w) { + Assert.isInstanceOf(PrintWriter, w, 'A GroovySynax tag requires a java.io.PrintWriter instance'); out = (PrintWriter) w; } - @SuppressWarnings("rawtypes") - public void setAttributes(Map attributes) { + @SuppressWarnings('rawtypes') + void setAttributes(Map attributes) { for (Iterator i = attributes.keySet().iterator(); i.hasNext();) { String attrName = (String) i.next(); setAttribute(attrName, attributes.get(attrName)); } } - public void setAttribute(String name, Object value) { - Assert.isInstanceOf(String.class, value, "A GroovySyntax tag requires only string valued attributes"); + void setAttribute(String name, Object value) { + Assert.isInstanceOf(String, value, 'A GroovySyntax tag requires only string valued attributes'); attributes.put(name.substring(1, name.length() - 1), (String) value); } @@ -94,7 +94,7 @@ public void setAttribute(String name, Object value) { * previous tag, and need to swallow the whitespace between them.

* @return true if any whitespace immediately before the tag should be kept in the output - false if it is to be discarded */ - public abstract boolean isKeepPrecedingWhiteSpace(); + abstract boolean isKeepPrecedingWhiteSpace(); /** *

Tags must return the correct value to indicate whether or not non-whitespace content is permitted before this tag.

@@ -103,18 +103,18 @@ public void setAttribute(String name, Object value) { * TODO rework this and combine with isKeepPrecedingWhiteSpace as really they are used in the same situations * @return true if any content is allowed immediately before the tag - false if it is an error to have such content before it */ - public abstract boolean isAllowPrecedingContent(); + abstract boolean isAllowPrecedingContent(); protected String calculateExpression(String expr) { - Assert.isTrue(!GrailsStringUtils.isBlank(expr), "Argument [expr] cannot be null or blank"); + Assert.isTrue(!GrailsStringUtils.isBlank(expr), 'Argument [expr] cannot be null or blank'); expr = expr.trim(); - if ((expr.startsWith("\"") && expr.endsWith("\"")) || - (expr.startsWith("\'") && expr.endsWith("\'"))) { + if ((expr.startsWith('"') && expr.endsWith('"')) || + (expr.startsWith("'") && expr.endsWith("'"))) { expr = expr.substring(1, expr.length() - 1); expr = expr.trim(); } - if (expr.startsWith("${") && expr.endsWith("}")) { + if (expr.startsWith('\${') && expr.endsWith('}')) { expr = expr.substring(2, expr.length() - 1); expr = expr.trim(); } @@ -124,6 +124,7 @@ protected String calculateExpression(String expr) { /** * @param in */ + @SuppressWarnings('SpaceInsideParentheses') protected void doEachMethod(String in) { String var = attributes.get(ATTRIBUTE_VAR); String status = attributes.get(ATTRIBUTES_STATUS); @@ -137,39 +138,39 @@ protected void doEachMethod(String in) { } if (var.equals(status) && (hasStatus)) { - throw new GrailsTagException("Attribute [" + ATTRIBUTE_VAR + - "] cannot have the same value as attribute [" + ATTRIBUTES_STATUS + "]", parser.getPageName(), parser.getCurrentOutputLineNumber()); + throw new GrailsTagException('Attribute [' + ATTRIBUTE_VAR + + '] cannot have the same value as attribute [' + ATTRIBUTES_STATUS + ']', parser.getPageName(), parser.getCurrentOutputLineNumber()); } if (hasStatus) { - out.println("loop:{"); - out.println("int " + status + " = 0"); + out.println('loop:{'); + out.println('int ' + status + ' = 0'); } if (!hasVar) { if (isCompileStaticMode()) { throw new GrailsTagException(ERROR_NO_VAR_WITH_COMPILE_STATIC, parser.getPageName(), parser.getCurrentOutputLineNumber()); } - var = "_it" + Math.abs(System.identityHashCode(this)); + var = '_it' + Math.abs(System.identityHashCode(this)); foreachRenamedIt = var; } String[] entryVars = null; if (hasVar && var.indexOf(',') > -1) { - entryVars = var.split("\\s*,\\s*"); - var = "_entry" + Math.abs(System.identityHashCode(this)); + entryVars = var.split('\\s*,\\s*'); + var = '_entry' + Math.abs(System.identityHashCode(this)); } - out.print("for( " + var); - out.print(" in "); // dot de-reference + out.print('for( ' + var); + out.print(' in '); // dot de-reference out.print(parser != null ? parser.getExpressionText(in, false) : extractAttributeValue(in)); // object - out.print(" )"); // dot de-reference - out.print(" {"); // start closure + out.print(' )'); // dot de-reference + out.print(' {'); // start closure out.println(); if (!hasVar) { - out.println("changeItVariable(" + foreachRenamedIt + ")"); + out.println('changeItVariable(' + foreachRenamedIt + ')'); } else if (entryVars != null) { - out.println("def " + entryVars[0].trim() + "=" + var + ".getKey()"); - out.println("def " + entryVars[1].trim() + "=" + var + ".getValue()"); + out.println('def ' + entryVars[0].trim() + '=' + var + '.getKey()'); + out.println('def ' + entryVars[1].trim() + '=' + var + '.getValue()'); } } @@ -179,26 +180,27 @@ protected void endEachMethod() { boolean hasStatus = !GrailsStringUtils.isBlank(status); if (hasStatus) { - out.println(status + "++"); - out.println("}"); + out.println(status + '++'); + out.println('}'); } - out.println("}"); + out.println('}'); } protected String extractAttributeValue(String attr) { if (GrailsStringUtils.isBlank(attr)) { - return ""; + return ''; } - if (((attr.startsWith("\"") && attr.endsWith("\"")) || (attr.startsWith("'") && attr.endsWith("'"))) && attr.length() > 1) { + if (((attr.startsWith('"') && attr.endsWith('"')) || (attr.startsWith("'") && attr.endsWith("'"))) && attr.length() > 1) { attr = attr.substring(1, attr.length() - 1); } - if (attr.endsWith("?") && attr.length() > 1) { + if (attr.endsWith('?') && attr.length() > 1) { attr = attr.substring(0, attr.length() - 1); } return attr; } - public String getForeachRenamedIt() { + String getForeachRenamedIt() { return foreachRenamedIt; } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyUnlessTag.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyUnlessTag.groovy similarity index 70% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyUnlessTag.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyUnlessTag.groovy index 05b4dc8453b..ec3e729ddc8 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyUnlessTag.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyUnlessTag.groovy @@ -16,21 +16,26 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler.tags; +package org.grails.gsp.compiler.tags -public class GroovyUnlessTag extends GroovyConditionalTag { - public static final String TAG_NAME = "unless"; +import groovy.transform.CompileStatic + +@CompileStatic +class GroovyUnlessTag extends GroovyConditionalTag { + + public static final String TAG_NAME = 'unless' @Override protected void outputStartTag(String envExpression, String testExpression) { - out.print("if(!("); - out.print(envExpression); - out.print(" && "); - out.print(testExpression); - out.println(")) {"); + out.print('if(!(') + out.print(envExpression) + out.print(' && ') + out.print(testExpression) + out.println(')) {') } - public String getName() { - return TAG_NAME; + String getName() { + return TAG_NAME } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyWhileTag.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyWhileTag.groovy similarity index 52% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyWhileTag.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyWhileTag.groovy index 390154946ac..a9d19104f05 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyWhileTag.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/tags/GroovyWhileTag.groovy @@ -16,45 +16,49 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler.tags; +package org.grails.gsp.compiler.tags -import grails.util.GrailsStringUtils; -import org.grails.taglib.GrailsTagException; +import groovy.transform.CompileStatic + +import grails.util.GrailsStringUtils +import org.grails.taglib.GrailsTagException /** * @author Graeme Rocher */ -public class GroovyWhileTag extends GroovySyntaxTag { +@CompileStatic +class GroovyWhileTag extends GroovySyntaxTag { - public static final String TAG_NAME = "while"; - private static final String ATTRIBUTE_TEST = "test"; + public static final String TAG_NAME = 'while' + private static final String ATTRIBUTE_TEST = 'test' - public void doStartTag() { - String test = attributes.get(ATTRIBUTE_TEST); + void doStartTag() { + String test = attributes.get(ATTRIBUTE_TEST) if (GrailsStringUtils.isBlank(test)) { - throw new GrailsTagException("Tag [" + TAG_NAME + "] missing required attribute [" + - ATTRIBUTE_TEST + "]", parser.getPageName(), parser.getCurrentOutputLineNumber()); + throw new GrailsTagException('Tag [' + TAG_NAME + '] missing required attribute [' + + ATTRIBUTE_TEST + ']', parser.getPageName(), parser.getCurrentOutputLineNumber()) } - out.print("while("); - out.print(test); - out.println(") {"); + out.print('while(') + out.print(test) + out.println(') {') } - public void doEndTag() { - out.println("}"); + void doEndTag() { + out.println('}') } - public String getName() { - return TAG_NAME; + String getName() { + return TAG_NAME } @Override - public boolean isKeepPrecedingWhiteSpace() { - return true; + boolean isKeepPrecedingWhiteSpace() { + return true } @Override - public boolean isAllowPrecedingContent() { - return true; + boolean isAllowPrecedingContent() { + return true } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageBytecodeOptimizer.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageBytecodeOptimizer.groovy similarity index 54% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageBytecodeOptimizer.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageBytecodeOptimizer.groovy index f43edfd9e5c..594c3eb69de 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageBytecodeOptimizer.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageBytecodeOptimizer.groovy @@ -16,49 +16,50 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler.transform; +package org.grails.gsp.compiler.transform -import java.net.URL; +import groovy.transform.CompileStatic +import org.codehaus.groovy.ast.ClassNode +import org.codehaus.groovy.ast.MethodNode +import org.codehaus.groovy.ast.Parameter +import org.codehaus.groovy.ast.stmt.BlockStatement +import org.codehaus.groovy.classgen.GeneratorContext +import org.codehaus.groovy.control.SourceUnit -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.ast.Parameter; -import org.codehaus.groovy.ast.stmt.BlockStatement; -import org.codehaus.groovy.classgen.GeneratorContext; -import org.codehaus.groovy.control.SourceUnit; - -import grails.compiler.ast.AstTransformer; -import grails.compiler.ast.GroovyPageInjector; +import grails.compiler.ast.AstTransformer +import grails.compiler.ast.GroovyPageInjector @AstTransformer -public class GroovyPageBytecodeOptimizer implements GroovyPageInjector { +@CompileStatic +class GroovyPageBytecodeOptimizer implements GroovyPageInjector { - private final static String RUN_METHOD = "run"; + private final static String RUN_METHOD = 'run' - public void performInjection(SourceUnit source, GeneratorContext context, ClassNode classNode) { + void performInjection(SourceUnit source, GeneratorContext context, ClassNode classNode) { // search run method in GSP script and get codeblock - MethodNode runMethod = classNode.getMethod(RUN_METHOD, new Parameter[0]); + MethodNode runMethod = classNode.getMethod(RUN_METHOD, new Parameter[0]) if (runMethod != null && runMethod.getCode() instanceof BlockStatement) { - BlockStatement block = (BlockStatement) runMethod.getCode(); + BlockStatement block = (BlockStatement) runMethod.getCode() //scan all MethodExpressionCalls to optimize them - GroovyPageOptimizerVisitor groovyPageVisitor = new GroovyPageOptimizerVisitor(classNode); - groovyPageVisitor.visitBlockStatement(block); + GroovyPageOptimizerVisitor groovyPageVisitor = new GroovyPageOptimizerVisitor(classNode) + groovyPageVisitor.visitBlockStatement(block) } } - public void performInjection(SourceUnit source, ClassNode classNode) { - performInjection(source, null, classNode); + void performInjection(SourceUnit source, ClassNode classNode) { + performInjection(source, null, classNode) } @Override - public void performInjectionOnAnnotatedClass(SourceUnit source, ClassNode classNode) { - performInjection(source, null, classNode); + void performInjectionOnAnnotatedClass(SourceUnit source, ClassNode classNode) { + performInjection(source, null, classNode) } //Avoid other injection - public boolean shouldInject(URL url) { - return false; + boolean shouldInject(URL url) { + return false } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageInjectionOperation.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageInjectionOperation.groovy similarity index 58% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageInjectionOperation.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageInjectionOperation.groovy index b046d2b1b3b..12aed21e64e 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageInjectionOperation.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageInjectionOperation.groovy @@ -16,19 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler.transform; +package org.grails.gsp.compiler.transform -import java.util.ArrayList; -import java.util.List; +import groovy.transform.CompileStatic +import org.codehaus.groovy.ast.ClassNode +import org.codehaus.groovy.classgen.GeneratorContext +import org.codehaus.groovy.control.CompilationFailedException +import org.codehaus.groovy.control.SourceUnit -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.classgen.GeneratorContext; -import org.codehaus.groovy.control.CompilationFailedException; -import org.codehaus.groovy.control.SourceUnit; - -import grails.compiler.ast.ClassInjector; -import grails.compiler.ast.GroovyPageInjector; -import org.grails.compiler.injection.GrailsAwareInjectionOperation; +import grails.compiler.ast.ClassInjector +import grails.compiler.ast.GroovyPageInjector +import org.grails.compiler.injection.GrailsAwareInjectionOperation /** * A GroovyPage compiler injection operation that uses a specified array of ClassInjector instances to @@ -37,33 +35,35 @@ * @author Stephane Maldini * @since 2.0 */ -public class GroovyPageInjectionOperation extends GrailsAwareInjectionOperation { +@CompileStatic +class GroovyPageInjectionOperation extends GrailsAwareInjectionOperation { - private GroovyPageInjector[] groovyPageInjectors; + private GroovyPageInjector[] groovyPageInjectors @Override - public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException { - for (GroovyPageInjector classInjector : getGroovyPageInjectors()) { + void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException { + for (GroovyPageInjector classInjector in getGroovyPageInjectors()) { try { - classInjector.performInjection(source, context, classNode); + classInjector.performInjection(source, context, classNode) } catch (RuntimeException e) { - System.err.println("Error occurred calling AST injector [" + classInjector.getClass() + "]: " + e.getMessage()); - e.printStackTrace(System.err); - throw e; + System.err.println('Error occurred calling AST injector [' + classInjector.getClass() + ']: ' + e.getMessage()) + e.printStackTrace(System.err) + throw e } } } private GroovyPageInjector[] getGroovyPageInjectors() { if (groovyPageInjectors == null) { - List injectors = new ArrayList<>(); - for (ClassInjector ci : getClassInjectors()) { + List injectors = new ArrayList<>() + for (ClassInjector ci in getClassInjectors()) { if (ci instanceof GroovyPageInjector) { - injectors.add((GroovyPageInjector) ci); + injectors.add((GroovyPageInjector) ci) } } - groovyPageInjectors = injectors.toArray(new GroovyPageInjector[injectors.size()]); + groovyPageInjectors = injectors.toArray(new GroovyPageInjector[injectors.size()]) } - return groovyPageInjectors; + return groovyPageInjectors } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageOptimizerVisitor.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageOptimizerVisitor.groovy similarity index 59% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageOptimizerVisitor.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageOptimizerVisitor.groovy index df05be87c46..111641d6b5a 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageOptimizerVisitor.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/GroovyPageOptimizerVisitor.groovy @@ -16,29 +16,26 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler.transform; - -import java.util.List; -import java.util.Stack; - -import groovy.lang.Closure; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.CodeVisitorSupport; -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.ast.Parameter; -import org.codehaus.groovy.ast.expr.ArgumentListExpression; -import org.codehaus.groovy.ast.expr.ClosureExpression; -import org.codehaus.groovy.ast.expr.DeclarationExpression; -import org.codehaus.groovy.ast.expr.MethodCallExpression; -import org.codehaus.groovy.ast.expr.VariableExpression; -import org.codehaus.groovy.ast.stmt.BlockStatement; -import org.codehaus.groovy.ast.stmt.ExpressionStatement; -import org.codehaus.groovy.ast.stmt.Statement; -import org.codehaus.groovy.syntax.Token; -import org.codehaus.groovy.syntax.Types; - -import org.grails.buffer.GrailsPrintWriter; -import org.grails.gsp.GroovyPage; +package org.grails.gsp.compiler.transform + +import groovy.transform.CompileStatic +import org.codehaus.groovy.ast.ClassNode +import org.codehaus.groovy.ast.CodeVisitorSupport +import org.codehaus.groovy.ast.MethodNode +import org.codehaus.groovy.ast.Parameter +import org.codehaus.groovy.ast.expr.ArgumentListExpression +import org.codehaus.groovy.ast.expr.ClosureExpression +import org.codehaus.groovy.ast.expr.DeclarationExpression +import org.codehaus.groovy.ast.expr.MethodCallExpression +import org.codehaus.groovy.ast.expr.VariableExpression +import org.codehaus.groovy.ast.stmt.BlockStatement +import org.codehaus.groovy.ast.stmt.ExpressionStatement +import org.codehaus.groovy.ast.stmt.Statement +import org.codehaus.groovy.syntax.Token +import org.codehaus.groovy.syntax.Types + +import org.grails.buffer.GrailsPrintWriter +import org.grails.gsp.GroovyPage /** * Scan MethodCallExpression in GSP to convert callsite calls into static calls (printHtmlPart ...) @@ -46,36 +43,37 @@ * @author Stephane Maldini * @since 2.0 */ +@CompileStatic class GroovyPageOptimizerVisitor extends CodeVisitorSupport { - private static final ClassNode groovyPageClassNode = new ClassNode(GroovyPage.class); - private static final MethodNode writerMethodNode = new ClassNode(GrailsPrintWriter.class).getMethod("print", - new Parameter[]{new Parameter(new ClassNode(Object.class), "obj")}); + private static final ClassNode groovyPageClassNode = new ClassNode(GroovyPage) + private static final MethodNode writerMethodNode = new ClassNode(GrailsPrintWriter).getMethod('print', + [new Parameter(new ClassNode(Object), 'obj')] as Parameter[]) - private static final String THIS_RECEIVER = "this"; - private static final String THISOBJECT = "thisObject"; - private static final String OUT_RECEIVER = "out"; - private static final String PRINT_METHOD = "print"; - private static final String EXPRESSIONOUT_RECEIVER = "expressionOut"; + private static final String THIS_RECEIVER = 'this' + private static final String THISOBJECT = 'thisObject' + private static final String OUT_RECEIVER = 'out' + private static final String PRINT_METHOD = 'print' + private static final String EXPRESSIONOUT_RECEIVER = 'expressionOut' - private Stack innerClosures = new Stack<>(); - private ClassNode targetGroovyPageNode; + private Stack innerClosures = new Stack<>() + private ClassNode targetGroovyPageNode - private DeclarationExpression thisObjectDeclaration; - private VariableExpression thisObjectVariable; + private DeclarationExpression thisObjectDeclaration + private VariableExpression thisObjectVariable - public GroovyPageOptimizerVisitor(ClassNode targetGroovyPage) { - this.targetGroovyPageNode = targetGroovyPage; + GroovyPageOptimizerVisitor(ClassNode targetGroovyPage) { + this.targetGroovyPageNode = targetGroovyPage - MethodCallExpression thisObjectMethodCall = new MethodCallExpression(new VariableExpression(THIS_RECEIVER), "getThisObject", MethodCallExpression.NO_ARGUMENTS); - thisObjectMethodCall.setMethodTarget(new ClassNode(Closure.class).getMethods("getThisObject").get(0)); + MethodCallExpression thisObjectMethodCall = new MethodCallExpression(new VariableExpression(THIS_RECEIVER), 'getThisObject', MethodCallExpression.NO_ARGUMENTS) + thisObjectMethodCall.setMethodTarget(new ClassNode(Closure).getMethods('getThisObject').get(0)) - thisObjectVariable = new VariableExpression(THISOBJECT, targetGroovyPageNode); + thisObjectVariable = new VariableExpression(THISOBJECT, targetGroovyPageNode) thisObjectDeclaration = new DeclarationExpression( thisObjectVariable, Token.newSymbol(Types.EQUALS, 0, 0), - thisObjectMethodCall); + thisObjectMethodCall) } /* @@ -89,59 +87,59 @@ public void visitClosureExpression(ClosureExpression expression) { } */ - @SuppressWarnings("unused") + @SuppressWarnings('unused') private void introduceThisObjectVariable(ClosureExpression closureExpression) { if (closureExpression.getCode() instanceof BlockStatement) { - List oldBlock = ((BlockStatement) closureExpression.getCode()).getStatements(); - BlockStatement newBlock = new BlockStatement(); + List oldBlock = ((BlockStatement) closureExpression.getCode()).getStatements() + BlockStatement newBlock = new BlockStatement() - newBlock.addStatement(new ExpressionStatement(thisObjectDeclaration)); - newBlock.addStatements(oldBlock); + newBlock.addStatement(new ExpressionStatement(thisObjectDeclaration)) + newBlock.addStatements(oldBlock) - closureExpression.setCode(newBlock); + closureExpression.setCode(newBlock) } } @Override - public void visitMethodCallExpression(MethodCallExpression call) { + void visitMethodCallExpression(MethodCallExpression call) { if (isCallFromGroovyPageClass(call)) { // TODO: Research why http://jira.grails.org/browse/GRAILS-8679 happens with this enabled. See ElvisAndClosureGroovyPageTests //proceedCallFromGroovyPageClass(call); } else if (isCallFromOutOrCodecOut(call)) { - proceedCallFromOutOrCodecOut(call); + proceedCallFromOutOrCodecOut(call) } - super.visitMethodCallExpression(call); + super.visitMethodCallExpression(call) } private void proceedCallFromOutOrCodecOut(MethodCallExpression call) { - call.setMethodTarget(writerMethodNode); + call.setMethodTarget(writerMethodNode) } private boolean isCallFromOutOrCodecOut(MethodCallExpression expression) { return (expression.getObjectExpression().getText().equals(OUT_RECEIVER) || expression.getObjectExpression().getText().equals(EXPRESSIONOUT_RECEIVER)) && - expression.getMethodAsString().equals(PRINT_METHOD); + expression.getMethodAsString().equals(PRINT_METHOD) } - @SuppressWarnings("unused") + @SuppressWarnings('unused') private void proceedCallFromGroovyPageClass(MethodCallExpression call) { - List methodNodeList = groovyPageClassNode.getMethods(call.getMethodAsString()); + List methodNodeList = groovyPageClassNode.getMethods(call.getMethodAsString()) if (methodNodeList.size() == 1) { - call.setMethodTarget(methodNodeList.get(0)); - changeThisObjectExpressionIfInnerClosure(call); + call.setMethodTarget(methodNodeList.get(0)) + changeThisObjectExpressionIfInnerClosure(call) } else if (methodNodeList.size() > 1 && call.getArguments() instanceof ArgumentListExpression) { //Special case for invokeTag - ArgumentListExpression argsExpr = ((ArgumentListExpression) call.getArguments()); + ArgumentListExpression argsExpr = ((ArgumentListExpression) call.getArguments()) - for (MethodNode methodNode : methodNodeList) { + for (MethodNode methodNode in methodNodeList) { //No need for deep analysis as GroovyPage doesn't have multiple signatures for same args number if (methodNode.getParameters().length == argsExpr.getExpressions().size()) { - call.setMethodTarget(methodNode); - changeThisObjectExpressionIfInnerClosure(call); - break; + call.setMethodTarget(methodNode) + changeThisObjectExpressionIfInnerClosure(call) + break } } } @@ -149,12 +147,13 @@ private void proceedCallFromGroovyPageClass(MethodCallExpression call) { private void changeThisObjectExpressionIfInnerClosure(MethodCallExpression call) { if (!innerClosures.isEmpty()) { - call.setObjectExpression(thisObjectVariable); + call.setObjectExpression(thisObjectVariable) } } private boolean isCallFromGroovyPageClass(MethodCallExpression expression) { return expression.getObjectExpression().getText().equals(THIS_RECEIVER) && - !groovyPageClassNode.getMethods(expression.getMethodAsString()).isEmpty(); + !groovyPageClassNode.getMethods(expression.getMethodAsString()).isEmpty() } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/LineNumber.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/LineNumber.groovy similarity index 70% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/LineNumber.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/LineNumber.groovy index e064a085100..6962fd44105 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/LineNumber.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/LineNumber.groovy @@ -16,22 +16,24 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler.transform; +package org.grails.gsp.compiler.transform -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.ElementType +import java.lang.annotation.Retention +import java.lang.annotation.RetentionPolicy +import java.lang.annotation.Target -import org.codehaus.groovy.transform.GroovyASTTransformationClass; +import org.codehaus.groovy.transform.GroovyASTTransformationClass /** * @author Andrew Eisenberg */ @Retention(RetentionPolicy.SOURCE) -@Target({ ElementType.TYPE }) -@GroovyASTTransformationClass({"org.grails.gsp.compiler.transform.LineNumberTransform"}) -public @interface LineNumber { - int[] lines(); - String sourceName(); +@Target([ ElementType.TYPE ]) +@GroovyASTTransformationClass(['org.grails.gsp.compiler.transform.LineNumberTransform']) +@interface LineNumber { + + int[] lines() + String sourceName() + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/LineNumberTransform.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/LineNumberTransform.groovy similarity index 72% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/LineNumberTransform.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/LineNumberTransform.groovy index 649ba72b5c3..afcb9579185 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/LineNumberTransform.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/transform/LineNumberTransform.groovy @@ -16,61 +16,59 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.compiler.transform; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; - -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.AnnotationNode; -import org.codehaus.groovy.ast.ClassCodeVisitorSupport; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.expr.ArgumentListExpression; -import org.codehaus.groovy.ast.expr.ArrayExpression; -import org.codehaus.groovy.ast.expr.AttributeExpression; -import org.codehaus.groovy.ast.expr.BinaryExpression; -import org.codehaus.groovy.ast.expr.BitwiseNegationExpression; -import org.codehaus.groovy.ast.expr.BooleanExpression; -import org.codehaus.groovy.ast.expr.CastExpression; -import org.codehaus.groovy.ast.expr.ClassExpression; -import org.codehaus.groovy.ast.expr.ClosureExpression; -import org.codehaus.groovy.ast.expr.ClosureListExpression; -import org.codehaus.groovy.ast.expr.ConstantExpression; -import org.codehaus.groovy.ast.expr.ConstructorCallExpression; -import org.codehaus.groovy.ast.expr.DeclarationExpression; -import org.codehaus.groovy.ast.expr.ElvisOperatorExpression; -import org.codehaus.groovy.ast.expr.Expression; -import org.codehaus.groovy.ast.expr.FieldExpression; -import org.codehaus.groovy.ast.expr.GStringExpression; -import org.codehaus.groovy.ast.expr.ListExpression; -import org.codehaus.groovy.ast.expr.MapEntryExpression; -import org.codehaus.groovy.ast.expr.MapExpression; -import org.codehaus.groovy.ast.expr.MethodCallExpression; -import org.codehaus.groovy.ast.expr.MethodPointerExpression; -import org.codehaus.groovy.ast.expr.NotExpression; -import org.codehaus.groovy.ast.expr.PostfixExpression; -import org.codehaus.groovy.ast.expr.PrefixExpression; -import org.codehaus.groovy.ast.expr.PropertyExpression; -import org.codehaus.groovy.ast.expr.RangeExpression; -import org.codehaus.groovy.ast.expr.SpreadExpression; -import org.codehaus.groovy.ast.expr.SpreadMapExpression; -import org.codehaus.groovy.ast.expr.StaticMethodCallExpression; -import org.codehaus.groovy.ast.expr.TernaryExpression; -import org.codehaus.groovy.ast.expr.TupleExpression; -import org.codehaus.groovy.ast.expr.UnaryMinusExpression; -import org.codehaus.groovy.ast.expr.UnaryPlusExpression; -import org.codehaus.groovy.ast.stmt.Statement; -import org.codehaus.groovy.classgen.BytecodeExpression; -import org.codehaus.groovy.control.CompilePhase; -import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.transform.ASTTransformation; -import org.codehaus.groovy.transform.GroovyASTTransformation; -import org.codehaus.groovy.transform.TransformWithPriority; - -import org.springframework.util.ReflectionUtils; - -import org.apache.grails.common.compiler.GroovyTransformOrder; +package org.grails.gsp.compiler.transform + +import java.lang.reflect.Field + +import groovy.transform.CompileStatic +import org.codehaus.groovy.ast.ASTNode +import org.codehaus.groovy.ast.AnnotationNode +import org.codehaus.groovy.ast.ClassCodeVisitorSupport +import org.codehaus.groovy.ast.ClassNode +import org.codehaus.groovy.ast.expr.ArgumentListExpression +import org.codehaus.groovy.ast.expr.ArrayExpression +import org.codehaus.groovy.ast.expr.AttributeExpression +import org.codehaus.groovy.ast.expr.BinaryExpression +import org.codehaus.groovy.ast.expr.BitwiseNegationExpression +import org.codehaus.groovy.ast.expr.BooleanExpression +import org.codehaus.groovy.ast.expr.CastExpression +import org.codehaus.groovy.ast.expr.ClassExpression +import org.codehaus.groovy.ast.expr.ClosureExpression +import org.codehaus.groovy.ast.expr.ClosureListExpression +import org.codehaus.groovy.ast.expr.ConstantExpression +import org.codehaus.groovy.ast.expr.ConstructorCallExpression +import org.codehaus.groovy.ast.expr.DeclarationExpression +import org.codehaus.groovy.ast.expr.ElvisOperatorExpression +import org.codehaus.groovy.ast.expr.Expression +import org.codehaus.groovy.ast.expr.FieldExpression +import org.codehaus.groovy.ast.expr.GStringExpression +import org.codehaus.groovy.ast.expr.ListExpression +import org.codehaus.groovy.ast.expr.MapEntryExpression +import org.codehaus.groovy.ast.expr.MapExpression +import org.codehaus.groovy.ast.expr.MethodCallExpression +import org.codehaus.groovy.ast.expr.MethodPointerExpression +import org.codehaus.groovy.ast.expr.NotExpression +import org.codehaus.groovy.ast.expr.PostfixExpression +import org.codehaus.groovy.ast.expr.PrefixExpression +import org.codehaus.groovy.ast.expr.PropertyExpression +import org.codehaus.groovy.ast.expr.RangeExpression +import org.codehaus.groovy.ast.expr.SpreadExpression +import org.codehaus.groovy.ast.expr.SpreadMapExpression +import org.codehaus.groovy.ast.expr.StaticMethodCallExpression +import org.codehaus.groovy.ast.expr.TernaryExpression +import org.codehaus.groovy.ast.expr.TupleExpression +import org.codehaus.groovy.ast.expr.UnaryMinusExpression +import org.codehaus.groovy.ast.expr.UnaryPlusExpression +import org.codehaus.groovy.ast.stmt.Statement +import org.codehaus.groovy.classgen.BytecodeExpression +import org.codehaus.groovy.control.CompilePhase +import org.codehaus.groovy.control.SourceUnit +import org.codehaus.groovy.transform.ASTTransformation +import org.codehaus.groovy.transform.GroovyASTTransformation +import org.codehaus.groovy.transform.TransformWithPriority +import org.springframework.util.ReflectionUtils + +import org.apache.grails.common.compiler.GroovyTransformOrder /** * Convert line number information to that based on the line number array passed @@ -79,95 +77,96 @@ * @author Andrew Eisenberg */ @GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS) -public class LineNumberTransform implements ASTTransformation, TransformWithPriority { +@CompileStatic +class LineNumberTransform implements ASTTransformation, TransformWithPriority { // LOG statements commented out because they were causing // compilation problems when used outside of grails // static final Log LOG = LogFactory.getLog(LineNumberTransform) - public void visit(ASTNode[] nodes, SourceUnit source) { - List classes = source.getAST().getClasses(); + void visit(ASTNode[] nodes, SourceUnit source) { + List classes = source.getAST().getClasses() - AnnotationNode annotation = null; - for (ClassNode clazz : classes) { - annotation = findAnnotation(clazz); + AnnotationNode annotation = null + for (ClassNode clazz in classes) { + annotation = findAnnotation(clazz) if (annotation != null) { - break; + break } } if (annotation == null) { - return; + return } - int[] array = extractLineNumberArray(annotation); + int[] array = extractLineNumberArray(annotation) if (array != null) { - LineNumberVisitor visitor = new LineNumberVisitor(array); - for (ClassNode clazz : classes) { - visitor.visitClass(clazz); + LineNumberVisitor visitor = new LineNumberVisitor(array) + for (ClassNode clazz in classes) { + visitor.visitClass(clazz) } } - String sourceName = extractSourceName(annotation); + String sourceName = extractSourceName(annotation) if (sourceName != null) { - source.getAST().setDescription(sourceName); + source.getAST().setDescription(sourceName) // source.name = sourceName - Field field = ReflectionUtils.findField(SourceUnit.class, "name"); - field.setAccessible(true); - ReflectionUtils.setField(field, source, sourceName); + Field field = ReflectionUtils.findField(SourceUnit, 'name') + field.setAccessible(true) + ReflectionUtils.setField(field, source, sourceName) } } String extractSourceName(AnnotationNode node) { - ConstantExpression newName = (ConstantExpression) node.getMember("sourceName"); - return (String) newName.getValue(); + ConstantExpression newName = (ConstantExpression) node.getMember('sourceName') + return (String) newName.getValue() } AnnotationNode findAnnotation(ClassNode clazz) { if (clazz != null) { - for (AnnotationNode node : clazz.getAnnotations()) { - if (node.getClassNode().getName().equals(LineNumber.class.getName())) { + for (AnnotationNode node in clazz.getAnnotations()) { + if (node.getClassNode().getName().equals(LineNumber.getName())) { // LOG.debug "Transforming in ${clazz.name}" - return node; + return node } } } - return null; + return null } int[] extractLineNumberArray(AnnotationNode node) { - ListExpression lineNumberArray = (ListExpression) node.getMember("lines"); + ListExpression lineNumberArray = (ListExpression) node.getMember('lines') // make assumption that this is a simple array of constants - List numbers = new ArrayList<>(); - for (Expression e : lineNumberArray.getExpressions()) { + List numbers = new ArrayList<>() + for (Expression e in lineNumberArray.getExpressions()) { if (e instanceof ConstantExpression) { - numbers.add((Integer) ((ConstantExpression) e).getValue()); + numbers.add((Integer) ((ConstantExpression) e).getValue()) } else { - numbers.add(-1); + numbers.add(-1) } } // LOG.debug "We have transformed: ${numbers}" if (numbers.isEmpty()) { - return null; + return null } - int[] array = new int[numbers.size()]; + int[] array = new int[numbers.size()] for (int i = 0, count = numbers.size(); i < count; i++) { - array[i] = numbers.get(i); + array[i] = numbers.get(i) } - return array; + return array } @Override - public int priority() { - return GroovyTransformOrder.GSP_LINE_ORDER; + int priority() { + return GroovyTransformOrder.GSP_LINE_ORDER } class LineNumberVisitor extends ClassCodeVisitorSupport { - int[] lineNumbers; + int[] lineNumbers LineNumberVisitor(int[] lineNumbers) { - this.lineNumbers = lineNumbers; + this.lineNumbers = lineNumbers /* if (LOG.isDebugEnabled()) { String numbers = "Line numbers: "; @@ -185,563 +184,564 @@ protected void visitStatement(Statement statement) { if (statement.getLineNumber() >= 0 && statement.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${statement.lineNumber} to ${lineNumbers[statement.lineNumber]}" - statement.setLineNumber(lineNumbers[statement.getLineNumber() - 1]); + statement.setLineNumber(lineNumbers[statement.getLineNumber() - 1]) } if (statement.getLastLineNumber() > 0 && statement.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${statement.lastLineNumber} to ${lineNumbers[statement.lastLineNumber]}" - statement.setLastLineNumber(lineNumbers[statement.getLastLineNumber() - 1]); + statement.setLastLineNumber(lineNumbers[statement.getLastLineNumber() - 1]) } } @Override - public void visitMethodCallExpression(MethodCallExpression expression) { + void visitMethodCallExpression(MethodCallExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitMethodCallExpression(expression); + super.visitMethodCallExpression(expression) } @Override - public void visitStaticMethodCallExpression(StaticMethodCallExpression expression) { + void visitStaticMethodCallExpression(StaticMethodCallExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitStaticMethodCallExpression(expression); + super.visitStaticMethodCallExpression(expression) } @Override - public void visitConstructorCallExpression(ConstructorCallExpression expression) { + void visitConstructorCallExpression(ConstructorCallExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitConstructorCallExpression(expression); + super.visitConstructorCallExpression(expression) } @Override - public void visitBinaryExpression(BinaryExpression expression) { + void visitBinaryExpression(BinaryExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitBinaryExpression(expression); + super.visitBinaryExpression(expression) } @Override - public void visitTernaryExpression(TernaryExpression expression) { + void visitTernaryExpression(TernaryExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitTernaryExpression(expression); + super.visitTernaryExpression(expression) } @Override - public void visitShortTernaryExpression(ElvisOperatorExpression expression) { + void visitShortTernaryExpression(ElvisOperatorExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitShortTernaryExpression(expression); + super.visitShortTernaryExpression(expression) } @Override - public void visitPostfixExpression(PostfixExpression expression) { + void visitPostfixExpression(PostfixExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitPostfixExpression(expression); + super.visitPostfixExpression(expression) } @Override - public void visitPrefixExpression(PrefixExpression expression) { + void visitPrefixExpression(PrefixExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitPrefixExpression(expression); + super.visitPrefixExpression(expression) } @Override - public void visitBooleanExpression(BooleanExpression expression) { + void visitBooleanExpression(BooleanExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitBooleanExpression(expression); + super.visitBooleanExpression(expression) } @Override - public void visitNotExpression(NotExpression expression) { + void visitNotExpression(NotExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitNotExpression(expression); + super.visitNotExpression(expression) } @Override - public void visitClosureExpression(ClosureExpression expression) { + void visitClosureExpression(ClosureExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitClosureExpression(expression); + super.visitClosureExpression(expression) } @Override - public void visitTupleExpression(TupleExpression expression) { + void visitTupleExpression(TupleExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitTupleExpression(expression); + super.visitTupleExpression(expression) } @Override - public void visitListExpression(ListExpression expression) { + void visitListExpression(ListExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitListExpression(expression); + super.visitListExpression(expression) } @Override - public void visitArrayExpression(ArrayExpression expression) { + void visitArrayExpression(ArrayExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitArrayExpression(expression); + super.visitArrayExpression(expression) } @Override - public void visitMapExpression(MapExpression expression) { + void visitMapExpression(MapExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitMapExpression(expression); + super.visitMapExpression(expression) } @Override - public void visitMapEntryExpression(MapEntryExpression expression) { + void visitMapEntryExpression(MapEntryExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitMapEntryExpression(expression); + super.visitMapEntryExpression(expression) } @Override - public void visitRangeExpression(RangeExpression expression) { + void visitRangeExpression(RangeExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitRangeExpression(expression); + super.visitRangeExpression(expression) } @Override - public void visitSpreadExpression(SpreadExpression expression) { + void visitSpreadExpression(SpreadExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitSpreadExpression(expression); + super.visitSpreadExpression(expression) } @Override - public void visitSpreadMapExpression(SpreadMapExpression expression) { + void visitSpreadMapExpression(SpreadMapExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitSpreadMapExpression(expression); + super.visitSpreadMapExpression(expression) } @Override - public void visitMethodPointerExpression( + void visitMethodPointerExpression( MethodPointerExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitMethodPointerExpression(expression); + super.visitMethodPointerExpression(expression) } @Override - public void visitUnaryMinusExpression(UnaryMinusExpression expression) { + void visitUnaryMinusExpression(UnaryMinusExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitUnaryMinusExpression(expression); + super.visitUnaryMinusExpression(expression) } @Override - public void visitUnaryPlusExpression(UnaryPlusExpression expression) { + void visitUnaryPlusExpression(UnaryPlusExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitUnaryPlusExpression(expression); + super.visitUnaryPlusExpression(expression) } @Override - public void visitBitwiseNegationExpression(BitwiseNegationExpression expression) { + void visitBitwiseNegationExpression(BitwiseNegationExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitBitwiseNegationExpression(expression); + super.visitBitwiseNegationExpression(expression) } @Override - public void visitCastExpression(CastExpression expression) { + void visitCastExpression(CastExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitCastExpression(expression); + super.visitCastExpression(expression) } @Override - public void visitConstantExpression(ConstantExpression expression) { + void visitConstantExpression(ConstantExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitConstantExpression(expression); + super.visitConstantExpression(expression) } @Override - public void visitClassExpression(ClassExpression expression) { + void visitClassExpression(ClassExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitClassExpression(expression); + super.visitClassExpression(expression) } @Override - public void visitDeclarationExpression(DeclarationExpression expression) { + void visitDeclarationExpression(DeclarationExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitDeclarationExpression(expression); + super.visitDeclarationExpression(expression) } @Override - public void visitPropertyExpression(PropertyExpression expression) { + void visitPropertyExpression(PropertyExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitPropertyExpression(expression); + super.visitPropertyExpression(expression) } @Override - public void visitAttributeExpression(AttributeExpression expression) { + void visitAttributeExpression(AttributeExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitAttributeExpression(expression); + super.visitAttributeExpression(expression) } @Override - public void visitFieldExpression(FieldExpression expression) { + void visitFieldExpression(FieldExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitFieldExpression(expression); + super.visitFieldExpression(expression) } @Override - public void visitGStringExpression(GStringExpression expression) { + void visitGStringExpression(GStringExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitGStringExpression(expression); + super.visitGStringExpression(expression) } @Override - public void visitArgumentlistExpression(ArgumentListExpression expression) { + void visitArgumentlistExpression(ArgumentListExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitArgumentlistExpression(expression); + super.visitArgumentlistExpression(expression) } @Override - public void visitClosureListExpression(ClosureListExpression expression) { + void visitClosureListExpression(ClosureListExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitClosureListExpression(expression); + super.visitClosureListExpression(expression) } @Override - public void visitBytecodeExpression(BytecodeExpression expression) { + void visitBytecodeExpression(BytecodeExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber - 1]}" - expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); + expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]) } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to ${lineNumbers[expression.lastLineNumber - 1]}" - expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); + expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]) } - super.visitBytecodeExpression(expression); + super.visitBytecodeExpression(expression) } @Override protected SourceUnit getSourceUnit() { - return null; + return null } } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/io/CachingGroovyPageStaticResourceLocator.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/io/CachingGroovyPageStaticResourceLocator.groovy similarity index 59% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/io/CachingGroovyPageStaticResourceLocator.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/io/CachingGroovyPageStaticResourceLocator.groovy index 7e145ef2d31..3595f56268c 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/io/CachingGroovyPageStaticResourceLocator.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/io/CachingGroovyPageStaticResourceLocator.groovy @@ -16,12 +16,14 @@ * specific language governing permissions and limitations * under the License. */ +@SuppressWarnings('UnnecessarySemicolon') package org.grails.gsp.io; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import groovy.transform.CompileStatic; import org.springframework.core.io.Resource; import grails.util.CacheEntry; @@ -33,17 +35,22 @@ * @author Graeme Rocher * @since 2.0 */ -public class CachingGroovyPageStaticResourceLocator extends GroovyPageStaticResourceLocator { +// TODO(groovyism-cleanup): semicolons kept to preserve rename-similarity against the original .java (see matrei's review on #16576). Removed by the stacked groovyism-cleanup PR. +@SuppressWarnings(['UnnecessarySemicolon']) +@CompileStatic +class CachingGroovyPageStaticResourceLocator extends GroovyPageStaticResourceLocator { + private ConcurrentMap> uriResolveCache = new ConcurrentHashMap<>(); private long cacheTimeout = -1; @Override - public Resource findResourceForURI(final String uri) { - Callable updater = new Callable<>() { - public Resource call() { - Resource resource = CachingGroovyPageStaticResourceLocator.super.findResourceForURI(uri); + Resource findResourceForURI(final String uri) { + final Resource nullResource = NULL_RESOURCE; + Callable updater = new Callable() { + Resource call() { + Resource resource = superFindResourceForURI(uri); if (resource == null) { - resource = NULL_RESOURCE; + resource = nullResource; } return resource; } @@ -53,11 +60,21 @@ public Resource call() { return resource == NULL_RESOURCE ? null : resource; } - public long getCacheTimeout() { + /** + * Groovy has no {@code OuterClass.super.method()} syntax for reaching this class's own + * superclass from the anonymous {@link Callable} above, unlike Java's qualified super. This + * gives that call a name the anonymous class can invoke unambiguously. + */ + private Resource superFindResourceForURI(String uri) { + return super.findResourceForURI(uri); + } + + long getCacheTimeout() { return cacheTimeout; } - public void setCacheTimeout(long cacheTimeout) { + void setCacheTimeout(long cacheTimeout) { this.cacheTimeout = cacheTimeout; } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/io/DefaultGroovyPageLocator.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/io/DefaultGroovyPageLocator.groovy similarity index 57% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/io/DefaultGroovyPageLocator.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/io/DefaultGroovyPageLocator.groovy index 519d5c28a3c..b091e056516 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/io/DefaultGroovyPageLocator.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/io/DefaultGroovyPageLocator.groovy @@ -16,43 +16,36 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.io; - -import java.io.File; -import java.security.PrivilegedAction; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CopyOnWriteArraySet; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.aot.AotDetector; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.ResourceLoaderAware; -import org.springframework.core.io.FileSystemResource; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; - -import grails.plugins.GrailsPlugin; -import grails.plugins.GrailsPluginManager; -import grails.plugins.PluginManagerAware; -import grails.util.CollectionUtils; -import grails.util.Environment; -import org.grails.gsp.GroovyPage; -import org.grails.gsp.GroovyPageBinding; -import org.grails.io.support.GrailsResourceUtils; -import org.grails.plugins.BinaryGrailsPlugin; -import org.grails.taglib.TemplateVariableBinding; +package org.grails.gsp.io + +import java.security.PrivilegedAction +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.ConcurrentLinkedQueue +import java.util.concurrent.ConcurrentMap +import java.util.concurrent.CopyOnWriteArraySet + +import groovy.transform.CompileStatic +import org.apache.commons.logging.Log +import org.apache.commons.logging.LogFactory +import org.springframework.aot.AotDetector +import org.springframework.beans.BeansException +import org.springframework.context.ApplicationContext +import org.springframework.context.ApplicationContextAware +import org.springframework.context.ResourceLoaderAware +import org.springframework.core.io.FileSystemResource +import org.springframework.core.io.Resource +import org.springframework.core.io.ResourceLoader + +import grails.plugins.GrailsPlugin +import grails.plugins.GrailsPluginManager +import grails.plugins.PluginManagerAware +import grails.util.CollectionUtils +import grails.util.Environment +import org.grails.gsp.GroovyPage +import org.grails.gsp.GroovyPageBinding +import org.grails.io.support.GrailsResourceUtils +import org.grails.plugins.BinaryGrailsPlugin +import org.grails.taglib.TemplateVariableBinding /** * Used to locate GSPs whether in development or WAR deployed mode from static @@ -61,354 +54,355 @@ * @author Graeme Rocher * @since 2.0 */ -public class DefaultGroovyPageLocator implements GroovyPageLocator, ResourceLoaderAware, ApplicationContextAware, PluginManagerAware { - - private static final Log LOG = LogFactory.getLog(DefaultGroovyPageLocator.class); - public static final String PATH_TO_WEB_INF_VIEWS = "/WEB-INF/grails-app/views"; - private static final String SLASHED_VIEWS_DIR_PATH = "/" + GrailsResourceUtils.VIEWS_DIR_PATH; - private static final String PLUGINS_PATH = "/plugins/"; - private static final String BLANK = ""; - protected Collection resourceLoaders = new ConcurrentLinkedQueue<>(); - protected GrailsPluginManager pluginManager; - private ConcurrentMap precompiledGspMap; - protected boolean warDeployed = Environment.isWarDeployed(); - protected boolean reloadEnabled = !warDeployed; - private Set reloadedPrecompiledGspClassNames = new CopyOnWriteArraySet<>(); - - public void setResourceLoader(ResourceLoader resourceLoader) { - addResourceLoader(resourceLoader); - } - - public void addResourceLoader(ResourceLoader resourceLoader) { +@CompileStatic +class DefaultGroovyPageLocator implements GroovyPageLocator, ResourceLoaderAware, ApplicationContextAware, PluginManagerAware { + + private static final Log LOG = LogFactory.getLog(DefaultGroovyPageLocator) + public static final String PATH_TO_WEB_INF_VIEWS = '/WEB-INF/grails-app/views' + private static final String SLASHED_VIEWS_DIR_PATH = '/' + GrailsResourceUtils.VIEWS_DIR_PATH + private static final String PLUGINS_PATH = '/plugins/' + private static final String BLANK = '' + protected Collection resourceLoaders = new ConcurrentLinkedQueue<>() + protected GrailsPluginManager pluginManager + private ConcurrentMap precompiledGspMap + protected boolean warDeployed = Environment.isWarDeployed() + protected boolean reloadEnabled = !warDeployed + private Set reloadedPrecompiledGspClassNames = new CopyOnWriteArraySet<>() + + void setResourceLoader(ResourceLoader resourceLoader) { + addResourceLoader(resourceLoader) + } + + void addResourceLoader(ResourceLoader resourceLoader) { if (resourceLoader != null && !resourceLoaders.contains(resourceLoader)) { - resourceLoaders.add(resourceLoader); + resourceLoaders.add(resourceLoader) } } - public void setPrecompiledGspMap(Map precompiledGspMap) { + void setPrecompiledGspMap(Map precompiledGspMap) { if (precompiledGspMap == null) { - this.precompiledGspMap = null; + this.precompiledGspMap = null } else { - this.precompiledGspMap = new ConcurrentHashMap<>(precompiledGspMap); + this.precompiledGspMap = new ConcurrentHashMap<>(precompiledGspMap) } } - public GroovyPageScriptSource findPage(final String uri) { - GroovyPageScriptSource scriptSource = findResourceScriptSource(uri); + GroovyPageScriptSource findPage(final String uri) { + GroovyPageScriptSource scriptSource = findResourceScriptSource(uri) if (scriptSource == null) { - scriptSource = findBinaryScriptSource(uri); + scriptSource = findBinaryScriptSource(uri) } if (scriptSource == null) { - scriptSource = findResourceScriptSourceInPlugins(uri); + scriptSource = findResourceScriptSourceInPlugins(uri) } - return scriptSource; + return scriptSource } protected Resource findReloadablePage(final String uri) { - Resource resource = findResource(uri); + Resource resource = findResource(uri) if (resource == null) { - resource = findResourceInPlugins(uri); + resource = findResourceInPlugins(uri) } - return resource; + return resource } - public GroovyPageScriptSource findPageInBinding(String pluginName, String uri, TemplateVariableBinding binding) { + GroovyPageScriptSource findPageInBinding(String pluginName, String uri, TemplateVariableBinding binding) { - GroovyPageScriptSource scriptSource = null; - String contextPath = resolveContextPath(pluginName, uri, binding); - String fullURI = GrailsResourceUtils.appendPiecesForUri(contextPath, uri); + GroovyPageScriptSource scriptSource = null + String contextPath = resolveContextPath(pluginName, uri, binding) + String fullURI = GrailsResourceUtils.appendPiecesForUri(contextPath, uri) if (pluginManager != null) { - GrailsPlugin grailsPlugin = pluginManager.getGrailsPlugin(pluginName); + GrailsPlugin grailsPlugin = pluginManager.getGrailsPlugin(pluginName) if (grailsPlugin instanceof BinaryGrailsPlugin) { - BinaryGrailsPlugin binaryGrailsPlugin = (BinaryGrailsPlugin) grailsPlugin; - File projectDirectory = binaryGrailsPlugin.getProjectDirectory(); + BinaryGrailsPlugin binaryGrailsPlugin = (BinaryGrailsPlugin) grailsPlugin + File projectDirectory = binaryGrailsPlugin.getProjectDirectory() if (projectDirectory != null) { - File f = new File(projectDirectory, GrailsResourceUtils.VIEWS_DIR_PATH + uri); + File f = new File(projectDirectory, GrailsResourceUtils.VIEWS_DIR_PATH + uri) if (f.exists()) { - scriptSource = new GroovyPageResourceScriptSource(uri, new FileSystemResource(f)); + scriptSource = new GroovyPageResourceScriptSource(uri, new FileSystemResource(f)) } } else { - scriptSource = resolveViewInBinaryPlugin(binaryGrailsPlugin, uri); + scriptSource = resolveViewInBinaryPlugin(binaryGrailsPlugin, uri) } } } if (scriptSource == null) { - scriptSource = findPageInBinding(fullURI, binding); + scriptSource = findPageInBinding(fullURI, binding) } if (scriptSource == null) { - scriptSource = findResourceScriptSource(uri); + scriptSource = findResourceScriptSource(uri) } //last effort to resolve and force name of plugin to use camel case if (scriptSource == null) { - contextPath = resolveContextPath(pluginName, uri, binding, true); - scriptSource = findPageInBinding(GrailsResourceUtils.appendPiecesForUri(contextPath, uri), binding); + contextPath = resolveContextPath(pluginName, uri, binding, true) + scriptSource = findPageInBinding(GrailsResourceUtils.appendPiecesForUri(contextPath, uri), binding) } - return scriptSource; + return scriptSource } protected String resolveContextPath(String pluginName, String uri, TemplateVariableBinding binding) { - return resolveContextPath(pluginName, uri, binding, false); + return resolveContextPath(pluginName, uri, binding, false) } protected String resolveContextPath(String pluginName, String uri, TemplateVariableBinding binding, boolean forceCamelCase) { - String contextPath = null; + String contextPath = null - if (uri.startsWith("/plugins/")) { - contextPath = BLANK; + if (uri.startsWith('/plugins/')) { + contextPath = BLANK } else if (pluginName != null && pluginManager != null) { - contextPath = pluginManager.getPluginPath(pluginName); + contextPath = pluginManager.getPluginPath(pluginName) } else if (binding instanceof GroovyPageBinding) { - String pluginContextPath = ((GroovyPageBinding) binding).getPluginContextPath(); - contextPath = pluginContextPath != null ? pluginContextPath : BLANK; + String pluginContextPath = ((GroovyPageBinding) binding).getPluginContextPath() + contextPath = pluginContextPath != null ? pluginContextPath : BLANK } else { - contextPath = BLANK; + contextPath = BLANK } - return contextPath; + return contextPath } - public void removePrecompiledPage(GroovyPageCompiledScriptSource scriptSource) { - reloadedPrecompiledGspClassNames.add(scriptSource.getCompiledClass().getName()); + void removePrecompiledPage(GroovyPageCompiledScriptSource scriptSource) { + reloadedPrecompiledGspClassNames.add(scriptSource.getCompiledClass().getName()) if (scriptSource.getURI() != null && precompiledGspMap != null) { - precompiledGspMap.remove(scriptSource.getURI()); + precompiledGspMap.remove(scriptSource.getURI()) } } - public GroovyPageScriptSource findPageInBinding(String uri, TemplateVariableBinding binding) { - GroovyPageScriptSource scriptSource = findResourceScriptSource(uri); + GroovyPageScriptSource findPageInBinding(String uri, TemplateVariableBinding binding) { + GroovyPageScriptSource scriptSource = findResourceScriptSource(uri) if (scriptSource == null) { - GrailsPlugin pagePlugin = binding instanceof GroovyPageBinding ? ((GroovyPageBinding) binding).getPagePlugin() : null; + GrailsPlugin pagePlugin = binding instanceof GroovyPageBinding ? ((GroovyPageBinding) binding).getPagePlugin() : null if (pagePlugin instanceof BinaryGrailsPlugin) { - BinaryGrailsPlugin binaryPlugin = (BinaryGrailsPlugin) pagePlugin; - scriptSource = resolveViewInBinaryPlugin(binaryPlugin, uri); + BinaryGrailsPlugin binaryPlugin = (BinaryGrailsPlugin) pagePlugin + scriptSource = resolveViewInBinaryPlugin(binaryPlugin, uri) } else if (pagePlugin != null) { - scriptSource = findResourceScriptSource(resolvePluginViewPath(uri, pagePlugin)); + scriptSource = findResourceScriptSource(resolvePluginViewPath(uri, pagePlugin)) } } if (scriptSource == null) { - scriptSource = findBinaryScriptSource(uri); + scriptSource = findBinaryScriptSource(uri) } - return scriptSource; + return scriptSource } protected GroovyPageScriptSource resolveViewInBinaryPlugin(BinaryGrailsPlugin binaryPlugin, String uri) { - GroovyPageScriptSource scriptSource = null; - uri = removeViewLocationPrefixes(uri); - uri = GrailsResourceUtils.appendPiecesForUri(PATH_TO_WEB_INF_VIEWS, uri); - Class viewClass = binaryPlugin.resolveView(uri); + GroovyPageScriptSource scriptSource = null + uri = removeViewLocationPrefixes(uri) + uri = GrailsResourceUtils.appendPiecesForUri(PATH_TO_WEB_INF_VIEWS, uri) + Class viewClass = binaryPlugin.resolveView(uri) if (viewClass != null && !reloadedPrecompiledGspClassNames.contains(viewClass.getName())) { - scriptSource = createGroovyPageCompiledScriptSource(uri, uri, viewClass); + scriptSource = createGroovyPageCompiledScriptSource(uri, uri, viewClass) // we know we have binary plugin, sp setting to null in the resourceCallable to skip reloading. - ((GroovyPageCompiledScriptSource) scriptSource).setResourceCallable(null); + ((GroovyPageCompiledScriptSource) scriptSource).setResourceCallable(null) } - return scriptSource; + return scriptSource } protected GroovyPageCompiledScriptSource createGroovyPageCompiledScriptSource(final String uri, String fullPath, Class viewClass) { - GroovyPageCompiledScriptSource scriptSource = new GroovyPageCompiledScriptSource(uri, fullPath, viewClass); + GroovyPageCompiledScriptSource scriptSource = new GroovyPageCompiledScriptSource(uri, fullPath, viewClass) if (reloadEnabled) { - scriptSource.setResourceCallable(new PrivilegedAction<>() { - public Resource run() { - return findReloadablePage(uri); + scriptSource.setResourceCallable(new PrivilegedAction() { + Resource run() { + return findReloadablePage(uri) } - }); + }) } - return scriptSource; + return scriptSource } protected GroovyPageScriptSource findBinaryScriptSource(String uri) { if (pluginManager == null) { - return null; + return null } - List allPlugins = Arrays.asList(pluginManager.getAllPlugins()); - Collections.reverse(allPlugins); + List allPlugins = Arrays.asList(pluginManager.getAllPlugins()) + Collections.reverse(allPlugins) - for (GrailsPlugin plugin : allPlugins) { + for (GrailsPlugin plugin in allPlugins) { if (!(plugin instanceof BinaryGrailsPlugin)) { - continue; + continue } - BinaryGrailsPlugin binaryPlugin = (BinaryGrailsPlugin) plugin; + BinaryGrailsPlugin binaryPlugin = (BinaryGrailsPlugin) plugin if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Searching plugin [%s] for GSP view [%s]", plugin.getName(), uri)); + LOG.debug(String.format('Searching plugin [%s] for GSP view [%s]', plugin.getName(), uri)) } - GroovyPageScriptSource scriptSource = resolveViewInBinaryPlugin(binaryPlugin, uri); + GroovyPageScriptSource scriptSource = resolveViewInBinaryPlugin(binaryPlugin, uri) if (scriptSource != null) { if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Found GSP view [%s] in plugin [%s]", uri, plugin.getName())); + LOG.debug(String.format('Found GSP view [%s] in plugin [%s]', uri, plugin.getName())) } - return scriptSource; + return scriptSource } else if (binaryPlugin.getProjectDirectory() != null) { - scriptSource = resolveViewInPluginProjectDirectory(binaryPlugin, uri); + scriptSource = resolveViewInPluginProjectDirectory(binaryPlugin, uri) if (scriptSource != null) { - return scriptSource; + return scriptSource } } } - return null; + return null } private GroovyPageScriptSource resolveViewInPluginProjectDirectory(BinaryGrailsPlugin binaryPlugin, String uri) { - File projectDirectory = binaryPlugin.getProjectDirectory(); - File f = new File(projectDirectory, "grails-app/views" + uri); + File projectDirectory = binaryPlugin.getProjectDirectory() + File f = new File(projectDirectory, 'grails-app/views' + uri) if (f.exists()) { - return new GroovyPageResourceScriptSource(uri, new FileSystemResource(f)); + return new GroovyPageResourceScriptSource(uri, new FileSystemResource(f)) } - return null; + return null } protected GroovyPageScriptSource findResourceScriptSourceInPlugins(String uri) { if (pluginManager == null) { - return null; + return null } - for (GrailsPlugin plugin : pluginManager.getAllPlugins()) { + for (GrailsPlugin plugin in pluginManager.getAllPlugins()) { if (plugin instanceof BinaryGrailsPlugin) { - continue; + continue } - GroovyPageScriptSource scriptSource = findResourceScriptSource(resolvePluginViewPath(uri, plugin)); + GroovyPageScriptSource scriptSource = findResourceScriptSource(resolvePluginViewPath(uri, plugin)) if (scriptSource != null) { - return scriptSource; + return scriptSource } } - return null; + return null } protected Resource findResourceInPlugins(String uri) { if (pluginManager == null) { - return null; + return null } - for (GrailsPlugin plugin : pluginManager.getAllPlugins()) { + for (GrailsPlugin plugin in pluginManager.getAllPlugins()) { if (plugin instanceof BinaryGrailsPlugin) { - continue; + continue } - Resource resource = findResource(resolvePluginViewPath(uri, plugin)); + Resource resource = findResource(resolvePluginViewPath(uri, plugin)) if (resource != null) { - return resource; + return resource } } - return null; + return null } protected String resolvePluginViewPath(String uri, GrailsPlugin plugin) { - uri = removeViewLocationPrefixes(uri); - return GrailsResourceUtils.appendPiecesForUri(plugin.getPluginPath(), GrailsResourceUtils.VIEWS_DIR_PATH, uri); + uri = removeViewLocationPrefixes(uri) + return GrailsResourceUtils.appendPiecesForUri(plugin.getPluginPath(), GrailsResourceUtils.VIEWS_DIR_PATH, uri) } protected String removeViewLocationPrefixes(String uri) { - uri = removePrefix(uri, GrailsResourceUtils.WEB_INF); - uri = removePrefix(uri, SLASHED_VIEWS_DIR_PATH); - uri = removePrefix(uri, GrailsResourceUtils.VIEWS_DIR_PATH); - return uri; + uri = removePrefix(uri, GrailsResourceUtils.WEB_INF) + uri = removePrefix(uri, SLASHED_VIEWS_DIR_PATH) + uri = removePrefix(uri, GrailsResourceUtils.VIEWS_DIR_PATH) + return uri } protected String removePrefix(String uri, String prefix) { if (uri.startsWith(prefix)) { - uri = uri.substring(prefix.length()); + uri = uri.substring(prefix.length()) } - return uri; + return uri } protected GroovyPageScriptSource findResourceScriptSource(final String uri) { - List searchPaths = resolveSearchPaths(uri); + List searchPaths = resolveSearchPaths(uri) - return findResourceScriptPathForSearchPaths(uri, searchPaths); + return findResourceScriptPathForSearchPaths(uri, searchPaths) } protected List resolveSearchPaths(String uri) { - List searchPaths = null; + List searchPaths = null - uri = removeViewLocationPrefixes(uri); + uri = removeViewLocationPrefixes(uri) if (warDeployed) { if (uri.startsWith(PLUGINS_PATH)) { - PluginViewPathInfo pathInfo = getPluginViewPathInfo(uri); + PluginViewPathInfo pathInfo = getPluginViewPathInfo(uri) searchPaths = CollectionUtils.newList( GrailsResourceUtils.appendPiecesForUri(GrailsResourceUtils.WEB_INF, PLUGINS_PATH, pathInfo.pluginName, GrailsResourceUtils.VIEWS_DIR_PATH, pathInfo.path), GrailsResourceUtils.appendPiecesForUri(GrailsResourceUtils.WEB_INF, uri), - uri); + uri) } else { searchPaths = CollectionUtils.newList( GrailsResourceUtils.appendPiecesForUri(PATH_TO_WEB_INF_VIEWS, uri), - uri); + uri) } } else { searchPaths = CollectionUtils.newList( GrailsResourceUtils.appendPiecesForUri(SLASHED_VIEWS_DIR_PATH, uri), GrailsResourceUtils.appendPiecesForUri(PATH_TO_WEB_INF_VIEWS, uri), - uri); + uri) } - return searchPaths; + return searchPaths } - @SuppressWarnings("unchecked") + @SuppressWarnings('unchecked') protected GroovyPageScriptSource findResourceScriptPathForSearchPaths(String uri, List searchPaths) { if (isPrecompiledAvailable()) { - for (String searchPath : searchPaths) { - String gspClassName = precompiledGspMap.get(searchPath); + for (String searchPath in searchPaths) { + String gspClassName = precompiledGspMap.get(searchPath) if (gspClassName != null && !reloadedPrecompiledGspClassNames.contains(gspClassName)) { if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Found pre-compiled GSP template [%s] for path [%s]", gspClassName, searchPath)); + LOG.debug(String.format('Found pre-compiled GSP template [%s] for path [%s]', gspClassName, searchPath)) } - Class gspClass = null; + Class gspClass = null try { if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Loading GSP template [%s]", gspClassName)); + LOG.debug(String.format('Loading GSP template [%s]', gspClassName)) } - gspClass = (Class) Class.forName(gspClassName, true, Thread.currentThread().getContextClassLoader()); + gspClass = (Class) Class.forName(gspClassName, true, Thread.currentThread().getContextClassLoader()) } catch (ClassNotFoundException e) { - LOG.warn("Cannot load class " + gspClassName + ". Resuming on non-precompiled implementation.", e); + LOG.warn('Cannot load class ' + gspClassName + '. Resuming on non-precompiled implementation.', e) } if (gspClass != null) { - GroovyPageCompiledScriptSource groovyPageCompiledScriptSource = createGroovyPageCompiledScriptSource(uri, searchPath, gspClass); + GroovyPageCompiledScriptSource groovyPageCompiledScriptSource = createGroovyPageCompiledScriptSource(uri, searchPath, gspClass) if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Returning new GSP script source for class [%s]", gspClassName)); + LOG.debug(String.format('Returning new GSP script source for class [%s]', gspClassName)) } - return groovyPageCompiledScriptSource; + return groovyPageCompiledScriptSource } } } } - Resource foundResource = findResource(searchPaths); - return foundResource == null ? null : new GroovyPageResourceScriptSource(uri, foundResource); + Resource foundResource = findResource(searchPaths) + return foundResource == null ? null : new GroovyPageResourceScriptSource(uri, foundResource) } protected Resource findResource(String uri) { - return findResource(resolveSearchPaths(uri)); + return findResource(resolveSearchPaths(uri)) } protected Resource findResource(List searchPaths) { - Resource foundResource = null; - Resource resource; - for (ResourceLoader loader : resourceLoaders) { - for (String path : searchPaths) { - resource = loader.getResource(path); + Resource foundResource = null + Resource resource + for (ResourceLoader loader in resourceLoaders) { + for (String path in searchPaths) { + resource = loader.getResource(path) if (resource != null && resource.exists()) { - foundResource = resource; - break; + foundResource = resource + break } } - if (foundResource != null) break; + if (foundResource != null) break } - return foundResource; + return foundResource } /** @@ -423,11 +417,11 @@ protected Resource findResource(List searchPaths) { * * @return whether a page is looked up among the pages compiled at build time */ - public boolean isPrecompiledAvailable() { + boolean isPrecompiledAvailable() { if (precompiledGspMap == null || precompiledGspMap.isEmpty()) { - return false; + return false } - return !isDevelopmentMode() || AotDetector.useGeneratedArtifacts(); + return !isDevelopmentMode() || AotDetector.useGeneratedArtifacts() } /** @@ -436,41 +430,42 @@ public boolean isPrecompiledAvailable() { * loaded, and so cannot be varied any other way. */ protected boolean isDevelopmentMode() { - return Environment.isDevelopmentMode(); + return Environment.isDevelopmentMode() } - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - addResourceLoader(applicationContext); + void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + addResourceLoader(applicationContext) } - public void setPluginManager(GrailsPluginManager pluginManager) { - this.pluginManager = pluginManager; + void setPluginManager(GrailsPluginManager pluginManager) { + this.pluginManager = pluginManager } - public static PluginViewPathInfo getPluginViewPathInfo(String uri) { - return new PluginViewPathInfo(uri); + static PluginViewPathInfo getPluginViewPathInfo(String uri) { + return new PluginViewPathInfo(uri) } - public static class PluginViewPathInfo { - public String basePath; - public String pluginName; - public String path; + static class PluginViewPathInfo { + public String basePath + public String pluginName + public String path - public PluginViewPathInfo(String uri) { - basePath = uri.substring(PLUGINS_PATH.length(), uri.length()); - int i = basePath.indexOf("/"); + PluginViewPathInfo(String uri) { + basePath = uri.substring(PLUGINS_PATH.length(), uri.length()) + int i = basePath.indexOf('/') if (i > -1) { - pluginName = basePath.substring(0, i); - path = basePath.substring(i, basePath.length()); + pluginName = basePath.substring(0, i) + path = basePath.substring(i, basePath.length()) } } } - public boolean isReloadEnabled() { - return reloadEnabled; + boolean isReloadEnabled() { + return reloadEnabled } - public void setReloadEnabled(boolean reloadEnabled) { - this.reloadEnabled = reloadEnabled; + void setReloadEnabled(boolean reloadEnabled) { + this.reloadEnabled = reloadEnabled } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageCompiledScriptSource.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageCompiledScriptSource.groovy similarity index 50% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageCompiledScriptSource.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageCompiledScriptSource.groovy index 21cd4a08a65..0b42874def1 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageCompiledScriptSource.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageCompiledScriptSource.groovy @@ -16,14 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.io; +package org.grails.gsp.io -import java.io.IOException; -import java.security.PrivilegedAction; +import java.security.PrivilegedAction -import org.springframework.core.io.Resource; +import groovy.transform.CompileStatic +import org.springframework.core.io.Resource -import org.grails.gsp.GroovyPageMetaInfo; +import org.grails.gsp.GroovyPageMetaInfo /** * Represents a pre-compiled GSP. @@ -31,22 +31,24 @@ * @author Graeme Rocher * @since 2.0 */ -public class GroovyPageCompiledScriptSource implements GroovyPageScriptSource { - private String uri; - private Class compiledClass; - private GroovyPageMetaInfo groovyPageMetaInfo; - private PrivilegedAction resourceCallable; - private boolean isPublic; - - public GroovyPageCompiledScriptSource(String uri, String fullPath, Class compiledClass) { - this.uri = uri; - this.isPublic = GroovyPageResourceScriptSource.isPublicPath(fullPath); - this.compiledClass = compiledClass; - this.groovyPageMetaInfo = new GroovyPageMetaInfo(compiledClass); +@CompileStatic +class GroovyPageCompiledScriptSource implements GroovyPageScriptSource { + + private String uri + private Class compiledClass + private GroovyPageMetaInfo groovyPageMetaInfo + private PrivilegedAction resourceCallable + private boolean isPublic + + GroovyPageCompiledScriptSource(String uri, String fullPath, Class compiledClass) { + this.uri = uri + this.isPublic = GroovyPageResourceScriptSource.isPublicPath(fullPath) + this.compiledClass = compiledClass + this.groovyPageMetaInfo = new GroovyPageMetaInfo(compiledClass) } - public String getURI() { - return uri; + String getURI() { + return uri } /** @@ -54,43 +56,44 @@ public String getURI() { * * @return true if it can be rendered publicly */ - public boolean isPublic() { - return isPublic; + boolean isPublic() { + return isPublic } /** * @return The compiled class */ - public Class getCompiledClass() { - return compiledClass; + Class getCompiledClass() { + return compiledClass } - public String getScriptAsString() throws IOException { - throw new UnsupportedOperationException("You cannot retrieve the source of a pre-compiled GSP script: " + uri); + String getScriptAsString() throws IOException { + throw new UnsupportedOperationException('You cannot retrieve the source of a pre-compiled GSP script: ' + uri) } - public boolean isModified() { + boolean isModified() { if (resourceCallable == null) { - return false; + return false } - return groovyPageMetaInfo.shouldReload(resourceCallable); + return groovyPageMetaInfo.shouldReload(resourceCallable) } - public GroovyPageResourceScriptSource getReloadableScriptSource() { - if (resourceCallable == null) return null; - Resource resource = groovyPageMetaInfo.checkIfReloadableResourceHasChanged(resourceCallable); - return resource == null ? null : new GroovyPageResourceScriptSource(uri, resource); + GroovyPageResourceScriptSource getReloadableScriptSource() { + if (resourceCallable == null) return null + Resource resource = groovyPageMetaInfo.checkIfReloadableResourceHasChanged(resourceCallable) + return resource == null ? null : new GroovyPageResourceScriptSource(uri, resource) } - public String suggestedClassName() { - return compiledClass.getName(); + String suggestedClassName() { + return compiledClass.getName() } - public GroovyPageMetaInfo getGroovyPageMetaInfo() { - return groovyPageMetaInfo; + GroovyPageMetaInfo getGroovyPageMetaInfo() { + return groovyPageMetaInfo } - public void setResourceCallable(PrivilegedAction resourceCallable) { - this.resourceCallable = resourceCallable; + void setResourceCallable(PrivilegedAction resourceCallable) { + this.resourceCallable = resourceCallable } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageLocator.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageLocator.groovy similarity index 84% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageLocator.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageLocator.groovy index 092758e7146..fb5174dd484 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageLocator.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageLocator.groovy @@ -16,11 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.io; +package org.grails.gsp.io -import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.ResourceLoader -import org.grails.taglib.TemplateVariableBinding; +import org.grails.taglib.TemplateVariableBinding /** * Used to locate GSPs whether in development or WAR deployed mode. @@ -28,14 +28,14 @@ * @author Graeme Rocher * @since 2.0 */ -public interface GroovyPageLocator { +interface GroovyPageLocator { /** * Adds a new resource loader to search * * @param resourceLoader The resource loader to search */ - void addResourceLoader(ResourceLoader resourceLoader); + void addResourceLoader(ResourceLoader resourceLoader) /** * Finds a page for the given URI @@ -43,7 +43,7 @@ public interface GroovyPageLocator { * @param uri The URI * @return A script source */ - GroovyPageScriptSource findPage(String uri); + GroovyPageScriptSource findPage(String uri) /** * Finds a page for the given URI @@ -53,7 +53,7 @@ public interface GroovyPageLocator { * @param binding The biding to use * @return A script source */ - GroovyPageScriptSource findPageInBinding(String pluginName, String uri, TemplateVariableBinding binding); + GroovyPageScriptSource findPageInBinding(String pluginName, String uri, TemplateVariableBinding binding) /** * Finds a page for the URI and binding @@ -62,12 +62,13 @@ public interface GroovyPageLocator { * @param binding The binding * @return The page source */ - GroovyPageScriptSource findPageInBinding(String uri, TemplateVariableBinding binding); + GroovyPageScriptSource findPageInBinding(String uri, TemplateVariableBinding binding) /** * Removes any precompiled pages for the given URI so that they can be replaced by dynamic pages * * @param compiledScriptSource The compiled script source */ - void removePrecompiledPage(GroovyPageCompiledScriptSource compiledScriptSource); + void removePrecompiledPage(GroovyPageCompiledScriptSource compiledScriptSource) + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageResourceScriptSource.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageResourceScriptSource.groovy similarity index 63% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageResourceScriptSource.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageResourceScriptSource.groovy index c0a0ffbcb2e..c5995a59fa6 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageResourceScriptSource.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageResourceScriptSource.groovy @@ -16,20 +16,19 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.io; +package org.grails.gsp.io -import java.io.IOException; -import java.net.URL; +import groovy.transform.CompileStatic +import org.springframework.core.io.Resource +import org.springframework.scripting.support.ResourceScriptSource -import org.springframework.core.io.Resource; -import org.springframework.scripting.support.ResourceScriptSource; +import org.grails.io.support.GrailsResourceUtils -import org.grails.io.support.GrailsResourceUtils; +@CompileStatic +class GroovyPageResourceScriptSource extends ResourceScriptSource implements GroovyPageScriptSource { -public class GroovyPageResourceScriptSource extends ResourceScriptSource implements GroovyPageScriptSource { - - private String uri; - private boolean isPublic; + private String uri + private boolean isPublic /** * Create a new ResourceScriptSource for the given resource. @@ -37,28 +36,28 @@ public class GroovyPageResourceScriptSource extends ResourceScriptSource impleme * @param uri The URI of the resource * @param resource the Resource to load the script from */ - public GroovyPageResourceScriptSource(String uri, Resource resource) { - super(resource); - this.uri = uri; + GroovyPageResourceScriptSource(String uri, Resource resource) { + super(resource) + this.uri = uri try { - URL u = getResource().getURL(); + URL u = getResource().getURL() if (u == null) { - isPublic = isPublicPath(uri); + isPublic = isPublicPath(uri) } else { - isPublic = isPublicPath(u.getPath()); + isPublic = isPublicPath(u.getPath()) } } catch (IOException e) { - isPublic = isPublicPath(uri); + isPublic = isPublicPath(uri) } } - public static boolean isPublicPath(String path) { - return !(path.contains(GrailsResourceUtils.WEB_INF) || path.contains(GrailsResourceUtils.VIEWS_DIR_PATH)); + static boolean isPublicPath(String path) { + return !(path.contains(GrailsResourceUtils.WEB_INF) || path.contains(GrailsResourceUtils.VIEWS_DIR_PATH)) } - public String getURI() { - return uri; + String getURI() { + return uri } /** @@ -66,7 +65,8 @@ public String getURI() { * * @return true if it can be rendered publicly */ - public boolean isPublic() { - return isPublic; + boolean isPublic() { + return isPublic } + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageScriptSource.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageScriptSource.groovy similarity index 85% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageScriptSource.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageScriptSource.groovy index a48b5a94d1f..b8358d39b64 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageScriptSource.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageScriptSource.groovy @@ -16,25 +16,26 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.io; +package org.grails.gsp.io -import org.springframework.scripting.ScriptSource; +import org.springframework.scripting.ScriptSource /** * @author Graeme Rocher * @since 2.0 */ -public interface GroovyPageScriptSource extends ScriptSource { +interface GroovyPageScriptSource extends ScriptSource { /** * @return The URI of the Groovy page */ - String getURI(); + String getURI() /** * Whether the GSP is publicly accessible directly, or only usable using internal rendering * * @return true if it can be rendered publicly */ - boolean isPublic(); + boolean isPublic() + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageStaticResourceLocator.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageStaticResourceLocator.groovy similarity index 67% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageStaticResourceLocator.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageStaticResourceLocator.groovy index dcec8c5f242..748837339bb 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageStaticResourceLocator.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/io/GroovyPageStaticResourceLocator.groovy @@ -16,17 +16,18 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.io; +package org.grails.gsp.io -import org.springframework.core.io.Resource; +import groovy.transform.CompileStatic +import org.springframework.core.io.Resource -import grails.plugins.GrailsPlugin; -import org.grails.core.io.DefaultResourceLocator; -import org.grails.gsp.GroovyPageBinding; -import org.grails.io.support.GrailsResourceUtils; -import org.grails.taglib.AbstractTemplateVariableBinding; -import org.grails.taglib.encoder.OutputContext; -import org.grails.taglib.encoder.OutputContextLookupHelper; +import grails.plugins.GrailsPlugin +import org.grails.core.io.DefaultResourceLocator +import org.grails.gsp.GroovyPageBinding +import org.grails.io.support.GrailsResourceUtils +import org.grails.taglib.AbstractTemplateVariableBinding +import org.grails.taglib.encoder.OutputContext +import org.grails.taglib.encoder.OutputContextLookupHelper /** *

@@ -38,45 +39,46 @@ * @author Graeme Rocher * @since 2.0 */ -public class GroovyPageStaticResourceLocator extends DefaultResourceLocator { +@CompileStatic +class GroovyPageStaticResourceLocator extends DefaultResourceLocator { @Override - public Resource findResourceForURI(String uri) { - Resource resource = super.findResourceForURI(uri); + Resource findResourceForURI(String uri) { + Resource resource = super.findResourceForURI(uri) if (resource == null || !resource.exists()) { - AbstractTemplateVariableBinding binding = findBindingInOutputContext(); + AbstractTemplateVariableBinding binding = findBindingInOutputContext() if (binding instanceof GroovyPageBinding) { - GrailsPlugin pagePlugin = ((GroovyPageBinding) binding).getPagePlugin(); + GrailsPlugin pagePlugin = ((GroovyPageBinding) binding).getPagePlugin() if (pagePlugin != null && pluginManager != null) { - resource = findResourceForPlugin(pagePlugin, uri); + resource = findResourceForPlugin(pagePlugin, uri) } } else if (pluginManager != null) { // attempt brute force search of all plugins - for (GrailsPlugin plugin : pluginManager.getAllPlugins()) { - resource = findResourceForPlugin(plugin, uri); - if (resource != null) break; + for (GrailsPlugin plugin in pluginManager.getAllPlugins()) { + resource = findResourceForPlugin(plugin, uri) + if (resource != null) break } } } - return resource; + return resource } private Resource findResourceForPlugin(GrailsPlugin plugin, String uri) { - Resource resource; - String pluginPath = pluginManager.getPluginPath(plugin.getName()); - String pluginUri = GrailsResourceUtils.appendPiecesForUri(pluginPath, uri); - resource = super.findResourceForURI(pluginUri); - return resource; + Resource resource + String pluginPath = pluginManager.getPluginPath(plugin.getName()) + String pluginUri = GrailsResourceUtils.appendPiecesForUri(pluginPath, uri) + resource = super.findResourceForURI(pluginUri) + return resource } protected AbstractTemplateVariableBinding findBindingInOutputContext() { - OutputContext outputContext = OutputContextLookupHelper.lookupOutputContext(); + OutputContext outputContext = OutputContextLookupHelper.lookupOutputContext() if (outputContext != null) { - return outputContext.getBinding(); + return outputContext.getBinding() } - return null; + return null } } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/JspTag.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/JspTag.groovy similarity index 87% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/JspTag.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/JspTag.groovy index 827dd1b7698..ee1e3c93b82 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/JspTag.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/JspTag.groovy @@ -16,17 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.jsp; - -import java.io.Writer; -import java.util.Map; - -import groovy.lang.Closure; +package org.grails.gsp.jsp /** * An interface that represents a JSP tag that can be invoked by Grails */ -public interface JspTag { +interface JspTag { /** * Main method to invoke a tag library and output to the target write @@ -34,7 +29,7 @@ public interface JspTag { * @param targetWriter The writer the tag should write to * @param attributes The tag attributes */ - void doTag(Writer targetWriter, Map attributes); + void doTag(Writer targetWriter, Map attributes) /** * Invokes a tag with a closure representing the body of the tag @@ -42,20 +37,21 @@ public interface JspTag { * @param attributes The tag attributes * @param body The body of the tag */ - void doTag(Writer targetWriter, Map attributes, Closure body); + void doTag(Writer targetWriter, Map attributes, Closure body) /** * @return Return true if the tag class implements the TryCatchFinally interface */ - boolean isTryCatchFinallyTag(); + boolean isTryCatchFinallyTag() /** * @return Return true if the tag class implements the IterationTag interface */ - boolean isIterationTag(); + boolean isIterationTag() /** * @return Return true if the tag class implements the BodyTag interface */ - boolean isBodyTag(); + boolean isBodyTag() + } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/JspTagLib.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/JspTagLib.groovy similarity index 91% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/JspTagLib.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/JspTagLib.groovy index 06fb2d309d0..b8655dbe323 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/JspTagLib.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/JspTagLib.groovy @@ -16,19 +16,19 @@ * specific language governing permissions and limitations * under the License. */ -package org.grails.gsp.jsp; +package org.grails.gsp.jsp /** * An interface that represents a Jsp taglib * * @author Graeme Rocher */ -public interface JspTagLib { +interface JspTagLib { /** * @return The URI of the tag library */ - String getURI(); + String getURI() /** * Obtains a reference to a JspTag instance contained within the library @@ -36,6 +36,6 @@ public interface JspTagLib { * @param name The name of the tag * @return A JspTag instance or null if it doesn't exist */ - JspTag getTag(String name); + JspTag getTag(String name) } diff --git a/grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/TagLibraryResolver.java b/grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/TagLibraryResolver.groovy similarity index 88% rename from grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/TagLibraryResolver.java rename to grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/TagLibraryResolver.groovy index f4c923fc99b..e6b2880f07f 100644 --- a/grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/TagLibraryResolver.java +++ b/grails-gsp/core/src/main/groovy/org/grails/gsp/jsp/TagLibraryResolver.groovy @@ -17,10 +17,10 @@ * under the License. */ -package org.grails.gsp.jsp; +package org.grails.gsp.jsp -public interface TagLibraryResolver { +interface TagLibraryResolver { - JspTagLib resolveTagLibrary(String uri); + JspTagLib resolveTagLibrary(String uri) }