Permalink
Browse files

Merge branch '3.2.x' into GRAILS-10141

  • Loading branch information...
2 parents 211a907 + bc0d233 commit 35dd00e42428e043dcb515e7792de6bdbf473a21 @jameskleeh jameskleeh committed Oct 5, 2016
Showing with 3,142 additions and 212 deletions.
  1. +1 −1 build.gradle
  2. +10 −2 grails-bom/build.gradle
  3. +1 −1 grails-bom/profiles.properties
  4. +29 −7 grails-bootstrap/src/main/groovy/grails/io/ResourceUtils.groovy
  5. +3 −1 grails-core/src/main/groovy/grails/boot/config/GrailsApplicationPostProcessor.groovy
  6. +20 −9 grails-core/src/main/groovy/grails/boot/config/GrailsAutoConfiguration.groovy
  7. +16 −0 grails-core/src/main/groovy/grails/core/DefaultGrailsApplication.java
  8. +117 −0 grails-core/src/main/groovy/org/grails/asm/AnnotationMetadataReader.java
  9. +258 −0 grails-core/src/main/groovy/org/grails/asm/Attribute.java
  10. +339 −0 grails-core/src/main/groovy/org/grails/asm/ByteVector.java
  11. +1,056 −0 grails-core/src/main/groovy/org/grails/asm/ClassReader.java
  12. +147 −0 grails-core/src/main/groovy/org/grails/asm/Context.java
  13. +197 −0 grails-core/src/main/groovy/org/grails/asm/TypePath.java
  14. +2 −0 grails-core/src/main/groovy/org/grails/beans/support/CachedIntrospectionResults.java
  15. +5 −1 grails-core/src/main/groovy/org/grails/compiler/injection/ApplicationClassInjector.groovy
  16. +1 −1 grails-core/src/main/groovy/org/grails/core/DefaultGrailsServiceClass.java
  17. +0 −3 grails-core/src/main/groovy/org/grails/core/artefact/ControllerArtefactHandler.java
  18. +70 −0 grails-core/src/main/groovy/org/grails/core/support/internal/tools/ClassRelativeClassLoader.java
  19. +24 −0 .../src/main/groovy/org/grails/core/support/internal/tools/ClassRelativeResourcePatternResolver.java
  20. +111 −119 grails-core/src/main/groovy/org/grails/core/util/ClassPropertyFetcher.java
  21. +20 −24 grails-core/src/main/groovy/org/grails/plugins/CorePluginFinder.java
  22. +44 −6 ...ore/src/main/groovy/org/grails/spring/context/support/PluginAwareResourceBundleMessageSource.java
  23. +1 −1 grails-core/src/test/groovy/grails/util/GrailsUtilTests.java
  24. +20 −0 ...s-core/src/test/groovy/org/grails/core/support/internal/tools/ClassRelativeClassLoaderSpec.groovy
  25. +24 −0 grails-core/src/test/groovy/org/grails/core/util/ClassPropertyFetcherSpec.groovy
  26. +2 −0 ...-plugin-databinding/src/main/groovy/org/grails/plugins/databinding/DataBindingGrailsPlugin.groovy
  27. +28 −29 grails-plugin-i18n/src/main/groovy/org/grails/plugins/i18n/I18nGrailsPlugin.groovy
  28. +2 −2 ...ls-plugin-testing/src/main/groovy/org/grails/compiler/injection/test/TestMixinTransformation.java
  29. +6 −4 ...plugin-url-mappings/src/main/groovy/org/grails/plugins/web/mapping/UrlMappingsGrailsPlugin.groovy
  30. +31 −0 grails-test-suite-uber/src/test/groovy/grails/test/mixin/ServiceTestMixinInheritanceSpec.groovy
  31. +1 −0 grails-web-common/src/main/groovy/grails/web/mime/MimeType.groovy
  32. +80 −0 ...g/src/main/groovy/org/grails/web/databinding/bindingsource/JsonApiDataBindingSourceCreator.groovy
  33. +185 −0 ...oovy/org/grails/web/databinding/bindingsource/json/api/JsonApiDataBindingSourceCreatorSpec.groovy
  34. +1 −1 grails-web-fileupload/build.gradle
  35. +74 −0 grails-web-url-mappings/src/main/groovy/grails/web/mapping/cors/GrailsCorsConfiguration.groovy
  36. +48 −0 grails-web-url-mappings/src/main/groovy/grails/web/mapping/cors/GrailsDefaultCorsMapping.groovy
  37. +5 −0 grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/mvc/UrlMappingsHandlerMapping.groovy
  38. +163 −0 grails-web-url-mappings/src/test/groovy/grails/web/mapping/cors/GrailsCorsConfigurationSpec.groovy
View
@@ -22,7 +22,7 @@ apply plugin: 'idea'
ext {
bintrayPublish = false
// Sets release version
- grailsVersion = '3.2.0.BUILD-SNAPSHOT'
+ grailsVersion = '3.2.1.BUILD-SNAPSHOT'
isBuildSnapshot = grailsVersion.endsWith(".BUILD-SNAPSHOT")
isTravisBuild = System.getenv().get("TRAVIS") == 'true'
@@ -165,15 +165,23 @@ publishing {
mkp.dependency {
mkp.groupId 'org.grails.plugins'
mkp.artifactId plugin.key
- mkp.version( plugin.value )
+ def version = plugin.value
+ if(!isBuildSnapshot && version.toString().endsWith("-SNAPSHOT")) {
+ throw new RuntimeException("Cannot have a snapshot dependency on a plugin [$plugin.key] for a release!")
+ }
+ mkp.version(version)
}
}
for(profile in profiles) {
mkp.dependency {
mkp.groupId 'org.grails.profiles'
mkp.artifactId profile.key
- mkp.version( profile.value )
+ def version = profile.value
+ if(!isBuildSnapshot && version.toString().endsWith("-SNAPSHOT")) {
+ throw new RuntimeException("Cannot have a snapshot dependency on a profile [$profile.key] for a release!")
+ }
+ mkp.version(version)
}
}
}
@@ -4,5 +4,5 @@ rest-api-plugin=3.2.0
base=3.2.0
plugin=3.2.0
web-plugin=3.2.0
-web=3.2.0
+web=3.2.1.BUILD-SNAPSHOT
profile=3.2.0
@@ -44,24 +44,46 @@ class ResourceUtils extends GrailsResourceUtils {
File rootDir = baseDir ? new File(baseDir, "grails-app") : null
Set<String> packageNames = []
if (rootDir?.exists()) {
+ File[] allFiles = rootDir.listFiles()
rootDir.eachDir { File dir ->
def dirName = dir.name
if (!dir.hidden && !dirName.startsWith('.') && !['conf', 'i18n', 'assets', 'views'].contains(dirName)) {
- populatePackages(dir, packageNames, "")
+ File[] files = dir.listFiles()
+ populatePackages(dir,files, packageNames, "")
}
}
}
return packageNames
}
- protected static populatePackages(File rootDir, Collection<String> packageNames, String prefix) {
- rootDir.eachDir { File dir ->
- def dirName = dir.name
- if (!dir.hidden && !dirName.startsWith('.')) {
- packageNames << "${prefix}${dirName}".toString()
+ protected static populatePackages(File rootDir, File[] files, Collection<String> packageNames, String prefix) {
- populatePackages(dir, packageNames, "${prefix}${dirName}.")
+ if(files != null) {
+ for(dir in files ) {
+ if(dir.isDirectory()) {
+ String dirName = dir.name
+ if (!dir.hidden && !dirName.startsWith('.')) {
+ def dirFiles = dir.listFiles()
+ if(dirFiles != null) {
+ boolean hasGroovySources = dirFiles?.find() { File f -> f.name.endsWith('.groovy') }
+ if(hasGroovySources) {
+ // if there are Groovy sources stop here, no need to add child packages
+ packageNames.add "${prefix}${dirName}".toString()
+ }
+ else {
+ // otherwise recurse into a child package
+ populatePackages(dir, dirFiles, packageNames, "${prefix}${dirName}.")
+ }
+ }
+
+ }
+ }
+ else {
+ if(dir.name.endsWith('.groovy') && prefix == "") {
+ packageNames.add("")
+ }
+ }
}
}
}
@@ -19,6 +19,7 @@ import org.grails.config.PrefixedMapPropertySource
import org.grails.config.PropertySourcesConfig
import org.grails.core.exceptions.GrailsConfigurationException
import org.grails.core.lifecycle.ShutdownOperations
+import org.grails.core.util.ClassPropertyFetcher
import org.grails.dev.support.GrailsSpringLoadedPlugin
import org.grails.spring.DefaultRuntimeSpringConfiguration
import org.grails.spring.RuntimeSpringConfigUtilities
@@ -70,7 +71,7 @@ class GrailsApplicationPostProcessor implements BeanDefinitionRegistryPostProces
this.applicationClass = null
}
this.classes = classes != null ? classes : [] as Class[]
- grailsApplication = new DefaultGrailsApplication()
+ grailsApplication = applicationClass != null ? new DefaultGrailsApplication(applicationClass) : new DefaultGrailsApplication()
pluginManager = new DefaultGrailsPluginManager(grailsApplication)
if(applicationContext != null) {
setApplicationContext(applicationContext)
@@ -89,6 +90,7 @@ class GrailsApplicationPostProcessor implements BeanDefinitionRegistryPostProces
loadApplicationConfig()
customizeGrailsApplication(grailsApplication)
performGrailsInitializationSequence()
+ ClassPropertyFetcher.clearClassPropertyFetcherCache()
}
protected void customizePluginManager(GrailsPluginManager grailsApplication) {
@@ -9,6 +9,7 @@ import groovy.transform.CompileStatic
import groovy.transform.InheritConstructors
import groovy.transform.Memoized
import groovy.util.logging.Slf4j
+import org.grails.asm.AnnotationMetadataReader
import org.grails.compiler.injection.AbstractGrailsArtefactTransformer
import org.grails.spring.aop.autoproxy.GroovyAwareAspectJAwareAdvisorAutoProxyCreator
import org.springframework.aop.config.AopConfigUtils
@@ -33,6 +34,7 @@ import java.lang.reflect.Field
*
*/
@CompileStatic
+@Slf4j
class GrailsAutoConfiguration implements GrailsApplicationClass, ApplicationContextAware {
private static final String APC_PRIORITY_LIST_FIELD = "APC_PRIORITY_LIST";
@@ -77,15 +79,24 @@ class GrailsAutoConfiguration implements GrailsApplicationClass, ApplicationCont
if(ignoredRootPackages().contains(pkg)) {
continue
}
- String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
- ClassUtils.convertClassNameToResourcePath(pkg) + Settings.CLASS_RESOURCE_PATTERN;
+ // if it is the default package
+ if(pkg == "") {
+ // try the default package in case of a script without recursing into subpackages
+ log.error("The application defines a Groovy source using the default package. Please move all Groovy sources into a package.")
+ String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + "*.class"
+ classes.addAll scanUsingPattern(pattern, readerFactory)
+ }
+ else {
+
+ String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
+ ClassUtils.convertClassNameToResourcePath(pkg) + Settings.CLASS_RESOURCE_PATTERN;
+
+
+ classes.addAll scanUsingPattern(pattern, readerFactory)
+ }
- classes.addAll scanUsingPattern(pattern, readerFactory)
}
- // try the default package in case of a script without recursing into subpackages
- String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + "*.class"
- classes.addAll scanUsingPattern(pattern, readerFactory)
def classLoader = Thread.currentThread().contextClassLoader
for(cls in AbstractGrailsArtefactTransformer.transformedClassNames) {
@@ -139,7 +150,7 @@ class GrailsAutoConfiguration implements GrailsApplicationClass, ApplicationCont
for (Resource res in resources) {
// ignore closures / inner classes
if(!res.filename.contains('$') && !res.filename.startsWith("gsp_")) {
- def reader = readerFactory.getMetadataReader(res)
+ def reader = new AnnotationMetadataReader(res, classLoader)
def metadata = reader.annotationMetadata
if (metadata.annotationTypes.any() { String annotation -> annotation.startsWith('grails.') }) {
classes << classLoader.loadClass(reader.classMetadata.className)
@@ -234,10 +245,10 @@ class GrailsAutoConfiguration implements GrailsApplicationClass, ApplicationCont
this.rootResource = getURLs()[0]
this.applicationClass = applicationClass
- def urlStr = rootResource.toString()
+ String urlStr = rootResource.toString()
jarDeployed = urlStr.startsWith("jar:")
try {
- def withoutBang = new URL("${urlStr.substring(0, urlStr.length() - 2)}/")
+ URL withoutBang = new URL("${urlStr.substring(0, urlStr.length() - 2)}/")
addURL(withoutBang)
} catch (MalformedURLException e) {
@@ -91,13 +91,22 @@
protected Class<?>[] allArtefactClassesArray;
protected Resource[] resources;
protected boolean initialised = false;
+ protected GrailsApplicationClass applicationClass;
/**
* Creates a new empty Grails application.
*/
public DefaultGrailsApplication() {
this(new GroovyClassLoader());
}
+
+ /**
+ * Creates a new empty Grails application.
+ */
+ public DefaultGrailsApplication(GrailsApplicationClass applicationClass) {
+ this(new GroovyClassLoader());
+ this.applicationClass = applicationClass;
+ }
public DefaultGrailsApplication(ClassLoader classLoader) {
super();
@@ -169,6 +178,13 @@ public DefaultGrailsApplication(org.grails.io.support.Resource[] resources) {
}
/**
+ * @return The application class
+ */
+ public GrailsApplicationClass getApplicationClass() {
+ return applicationClass;
+ }
+
+ /**
* Initialises the default set of ArtefactHandler instances.
*
* @see grails.core.ArtefactHandler
@@ -0,0 +1,117 @@
+package org.grails.asm;
+
+import org.springframework.asm.AnnotationVisitor;
+import org.springframework.asm.SpringAsmInfo;
+import org.springframework.asm.Type;
+import org.springframework.core.NestedIOException;
+import org.springframework.core.io.Resource;
+import org.springframework.core.type.AnnotationMetadata;
+import org.springframework.core.type.ClassMetadata;
+import org.springframework.core.type.classreading.AnnotationMetadataReadingVisitor;
+import org.springframework.core.type.classreading.MetadataReader;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A more limited version of Spring's annotation reader that only reads annotations on classes
+ *
+ * @author Graeme Rocher
+ * @since 3.1.13
+ */
+public class AnnotationMetadataReader implements MetadataReader {
+ private final Resource resource;
+
+ private final ClassMetadata classMetadata;
+
+ private final AnnotationMetadata annotationMetadata;
+
+ /**
+ * Reads only the annotation names from a class resource
+ * @param resource The resource
+ * @param classLoader The classloader
+ * @throws IOException
+ */
+ public AnnotationMetadataReader(Resource resource, ClassLoader classLoader) throws IOException {
+ this(resource, classLoader, false);
+ }
+ /**
+ * Constructs a new annotation metadata reader
+ *
+ * @param resource The resource
+ * @param classLoader The classloader
+ * @param readAttributeValues Whether to read the attributes in addition or just the annotation class names
+ * @throws IOException
+ */
+ public AnnotationMetadataReader(Resource resource, ClassLoader classLoader, boolean readAttributeValues) throws IOException {
+ InputStream is = new BufferedInputStream(resource.getInputStream());
+ ClassReader classReader;
+ try {
+ classReader = new ClassReader(is);
+ }
+ catch (IllegalArgumentException ex) {
+ throw new NestedIOException("ASM ClassReader failed to parse class file - " +
+ "probably due to a new Java class file version that isn't supported yet: " + resource, ex);
+ }
+ finally {
+ is.close();
+ }
+
+
+ AnnotationMetadataReadingVisitor visitor;
+
+ if(readAttributeValues) {
+ visitor = new AnnotationMetadataReadingVisitor(classLoader);
+ }
+ else {
+ visitor = new AnnotationMetadataReadingVisitor(classLoader) {
+ @Override
+ public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
+ String className = Type.getType(desc).getClassName();
+ this.annotationSet.add(className);
+ return new EmptyAnnotationVisitor();
+ }
+ };
+ }
+ classReader.accept(visitor, ClassReader.SKIP_DEBUG);
+
+ this.annotationMetadata = visitor;
+ // (since AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor)
+ this.classMetadata = visitor;
+ this.resource = resource;
+ }
+
+
+ @Override
+ public Resource getResource() {
+ return this.resource;
+ }
+
+ @Override
+ public ClassMetadata getClassMetadata() {
+ return this.classMetadata;
+ }
+
+ @Override
+ public AnnotationMetadata getAnnotationMetadata() {
+ return this.annotationMetadata;
+ }
+
+ private static class EmptyAnnotationVisitor extends AnnotationVisitor {
+
+ public EmptyAnnotationVisitor() {
+ super(SpringAsmInfo.ASM_VERSION);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(String name, String desc) {
+ return this;
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(String name) {
+ return this;
+ }
+ }
+}
Oops, something went wrong.

0 comments on commit 35dd00e

Please sign in to comment.