Skip to content

Commit a0058b8

Browse files
committed
Merge branch '3.0.x'
2 parents 9f55d9a + 02e993e commit a0058b8

File tree

60 files changed

+1143
-342
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1143
-342
lines changed

grails-bom/plugins.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ hibernate4=5.0.0.RC3
33
mongodb=5.0.0.RC3
44
cassandra=5.0.0.RC3
55
neo4j=5.0.0.RC3
6-
cache=3.0.1
7-
asset-pipeline=3.0.14
6+
cache=3.0.2
7+
asset-pipeline=3.0.15
88
scaffolding=3.1.2
99
fields=2.1.1
1010
geb=1.0.1

grails-bootstrap/src/main/groovy/grails/io/IOUtils.groovy

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,22 @@ class IOUtils extends SpringIOUtils {
142142
targetClass.getResource('/' + targetClass.name.replace(".", "/") + ".class")
143143
}
144144

145+
/**
146+
* Returns a URL that represents the root classpath resource where the given class was loaded from
147+
*
148+
* @param targetClass The target class
149+
* @return The URL to class file or null
150+
*/
151+
static URL findRootResource(Class targetClass) {
152+
def pathToClassFile = '/' + targetClass.name.replace(".", "/") + ".class"
153+
def classRes = targetClass.getResource(pathToClassFile)
154+
if(classRes) {
155+
def rootPath = classRes.toString() - pathToClassFile
156+
return new URL("$rootPath/")
157+
}
158+
throw new IllegalStateException("Root classpath resource not found! Check your disk permissions")
159+
160+
}
145161

146162
/**
147163
* Returns the URL resource for the location on disk of the given class or null if it cannot be found

grails-bootstrap/src/main/groovy/grails/io/ResourceUtils.groovy

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package grails.io
1717

1818
import grails.util.BuildSettings
1919
import groovy.transform.CompileStatic
20+
import groovy.transform.Memoized
2021
import org.grails.io.support.GrailsResourceUtils
2122

2223

@@ -38,6 +39,7 @@ class ResourceUtils extends GrailsResourceUtils {
3839
return getProjectPackageNames(BuildSettings.BASE_DIR)
3940
}
4041

42+
@Memoized
4143
static Iterable<String> getProjectPackageNames(File baseDir) {
4244
File rootDir = baseDir ? new File(baseDir, "grails-app") : null
4345
Set<String> packageNames = []

grails-bootstrap/src/main/groovy/grails/util/Environment.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,17 @@
2121
import groovy.lang.MissingMethodException;
2222
import org.codehaus.groovy.control.MultipleCompilationErrorsException;
2323
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
24+
import org.grails.io.support.Resource;
25+
import org.grails.io.support.UrlResource;
2426

2527
import java.io.File;
28+
import java.io.IOException;
29+
import java.io.InputStream;
2630
import java.net.URL;
2731
import java.util.Locale;
2832
import java.util.Map;
33+
import java.util.jar.Attributes;
34+
import java.util.jar.Manifest;
2935

3036
/**
3137
* Represents the current environment.
@@ -105,6 +111,54 @@ public enum Environment {
105111
private static Holder<Environment> cachedCurrentEnvironment = new Holder<Environment>("Environment");
106112
private static final boolean DEVELOPMENT_MODE = getCurrent() == DEVELOPMENT && BuildSettings.GRAILS_APP_DIR_PRESENT;
107113
private static boolean initializingState = false;
114+
115+
private static final String GRAILS_IMPLEMENTATION_TITLE = "Grails";
116+
private static final String GRAILS_VERSION;
117+
118+
static {
119+
Package p = Environment.class.getPackage();
120+
String version = p != null ? p.getImplementationVersion() : null;
121+
if (version == null || isBlank(version)) {
122+
try {
123+
URL manifestURL = IOUtils.findResourceRelativeToClass(Environment.class, "/META-INF/MANIFEST.MF");
124+
Manifest grailsManifest = null;
125+
if(manifestURL != null) {
126+
Resource r = new UrlResource(manifestURL);
127+
if(r.exists()) {
128+
InputStream inputStream = null;
129+
Manifest mf = null;
130+
try {
131+
inputStream = r.getInputStream();
132+
mf = new Manifest(inputStream);
133+
} finally {
134+
try {
135+
inputStream.close();
136+
} catch (IOException e) {
137+
// ignore
138+
}
139+
}
140+
String implTitle = mf.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_TITLE);
141+
if (!isBlank(implTitle) && implTitle.equals(GRAILS_IMPLEMENTATION_TITLE)) {
142+
grailsManifest = mf;
143+
}
144+
}
145+
}
146+
147+
if (grailsManifest != null) {
148+
version = grailsManifest.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION);
149+
}
150+
151+
if (isBlank(version)) {
152+
version = "Unknown";
153+
}
154+
}
155+
catch (Exception e) {
156+
version = "Unknown";
157+
}
158+
}
159+
GRAILS_VERSION = version;
160+
}
161+
108162
public static Throwable currentReloadError = null;
109163
public static MultipleCompilationErrorsException currentCompilationError = null;
110164
private String name;
@@ -114,6 +168,12 @@ public enum Environment {
114168
initialize();
115169
}
116170

171+
/**
172+
* @return The current Grails version
173+
*/
174+
public static String getGrailsVersion() {
175+
return GRAILS_VERSION;
176+
}
117177
public static void setCurrentReloadError(Throwable currentReloadError) {
118178
Environment.currentReloadError = currentReloadError;
119179
}

grails-bootstrap/src/main/groovy/org/grails/io/support/GrailsResourceUtils.java

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
package org.grails.io.support;
1717

1818
import grails.util.BuildSettings;
19+
import groovy.lang.Closure;
1920
import groovy.util.ConfigObject;
21+
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
2022

2123
import java.io.File;
2224
import java.io.FileNotFoundException;
@@ -26,12 +28,7 @@
2628
import java.net.URISyntaxException;
2729
import java.net.URL;
2830
import java.net.URLConnection;
29-
import java.util.ArrayList;
30-
import java.util.Collection;
31-
import java.util.Iterator;
32-
import java.util.LinkedList;
33-
import java.util.List;
34-
import java.util.Map;
31+
import java.util.*;
3532
import java.util.regex.Matcher;
3633
import java.util.regex.Pattern;
3734

@@ -179,6 +176,27 @@ public class GrailsResourceUtils {
179176
GRAILS_RESOURCE_PATTERN_ELEVENTH_MATCH
180177
};
181178

179+
private static Map<String, Boolean> KNOWN_PATHS = new LinkedHashMap<String, Boolean>() {
180+
@Override
181+
protected boolean removeEldestEntry(Map.Entry eldest) {
182+
return this.size() > 100;
183+
}
184+
};
185+
186+
private static Map<String, Boolean> KNOWN_DOMAIN_CLASSES = DefaultGroovyMethods.withDefault(new LinkedHashMap<String, Boolean>(){
187+
@Override
188+
protected boolean removeEldestEntry(Map.Entry<String, Boolean> eldest) {
189+
return this.size() > 100;
190+
}
191+
}, new Closure(GrailsResourceUtils.class) {
192+
193+
@Override
194+
public Object call(Object... args) {
195+
String path = args[0].toString();
196+
return DOMAIN_PATH_PATTERN.matcher(path).find();
197+
}
198+
});
199+
182200
private static String createGrailsResourcePattern(String separator, String base) {
183201
return ".+" + separator + base + separator + "(.+)\\.(groovy|java)$";
184202
}
@@ -189,10 +207,10 @@ private static String createGrailsResourcePattern(String separator, String base)
189207
* @param url The URL instance
190208
* @return true if it is a domain class
191209
*/
210+
192211
public static boolean isDomainClass(URL url) {
193212
if (url == null) return false;
194-
195-
return DOMAIN_PATH_PATTERN.matcher(url.getFile()).find();
213+
return KNOWN_DOMAIN_CLASSES.get(url.getFile());
196214
}
197215

198216
/**
@@ -634,13 +652,19 @@ public static URI toURI(String location) throws URISyntaxException {
634652
* @param path The path to check
635653
* @return true if it is a Grails path
636654
*/
655+
637656
public static boolean isGrailsPath(String path) {
657+
if(KNOWN_PATHS.containsKey(path)) {
658+
return KNOWN_PATHS.get(path);
659+
}
638660
for (Pattern grailsAppResourcePattern : grailsAppResourcePatterns) {
639661
Matcher m = grailsAppResourcePattern.matcher(path);
640662
if (m.find()) {
663+
KNOWN_PATHS.put(path, true);
641664
return true;
642665
}
643666
}
667+
KNOWN_PATHS.put(path, false);
644668
return false;
645669
}
646670

grails-bootstrap/src/main/groovy/org/grails/io/support/SpringIOUtils.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import javax.xml.XMLConstants;
2525
import javax.xml.parsers.ParserConfigurationException;
26+
import javax.xml.parsers.SAXParser;
2627
import javax.xml.parsers.SAXParserFactory;
2728
import java.io.*;
2829
import java.lang.reflect.Array;
@@ -389,8 +390,12 @@ public static String copyToString(Reader in) throws IOException {
389390
}
390391

391392
public static XmlSlurper createXmlSlurper() throws ParserConfigurationException, SAXException {
393+
return new XmlSlurper(newSAXParser());
394+
}
395+
396+
public static SAXParser newSAXParser() throws ParserConfigurationException, SAXException {
392397
SAXParserFactory factory = createParserFactory();
393-
return new XmlSlurper(factory.newSAXParser());
398+
return factory.newSAXParser();
394399
}
395400

396401
private static SAXParserFactory saxParserFactory = null;

grails-console/src/main/groovy/grails/ui/console/support/GroovyConsoleWebApplicationContext.groovy

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package grails.ui.console.support
22

33
import grails.core.GrailsApplication
4+
import grails.persistence.support.PersistenceContextInterceptor
45
import grails.ui.support.DevelopmentWebApplicationContext
56
import grails.util.BuildSettings
67
import groovy.transform.CompileStatic
@@ -56,6 +57,18 @@ class GroovyConsoleWebApplicationContext extends DevelopmentWebApplicationContex
5657
}
5758
}
5859

60+
def interceptors = getBeansOfType(PersistenceContextInterceptor).values()
61+
groovyConsole.beforeExecution = {
62+
for(i in interceptors) {
63+
i.init()
64+
}
65+
}
66+
67+
groovyConsole.afterExecution = {
68+
for(i in interceptors) {
69+
i.destroy()
70+
}
71+
}
5972
groovyConsole.run()
6073

6174
}

grails-core/src/main/groovy/grails/boot/GrailsApp.groovy

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import org.codehaus.groovy.control.CompilerConfiguration
1818
import org.grails.boot.internal.JavaCompiler
1919
import org.grails.compiler.injection.AbstractGrailsArtefactTransformer
2020
import org.grails.compiler.injection.GrailsAwareInjectionOperation
21+
import org.grails.core.util.BeanCreationProfilingPostProcessor
2122
import org.grails.io.watch.DirectoryWatcher
2223
import org.grails.io.watch.FileExtensionFileChangeListener
2324
import org.grails.plugins.support.WatchPattern
@@ -46,6 +47,8 @@ class GrailsApp extends SpringApplication {
4647
private static boolean developmentModeActive = false
4748
private static DirectoryWatcher directoryWatcher
4849

50+
boolean enableBeanCreationProfiler = false
51+
4952
@Override
5053
ConfigurableApplicationContext run(String... args) {
5154
def applicationContext = super.run(args)
@@ -68,7 +71,13 @@ class GrailsApp extends SpringApplication {
6871
@Override
6972
protected ConfigurableApplicationContext createApplicationContext() {
7073
ConfigurableApplicationContext applicationContext = super.createApplicationContext()
74+
7175
applyAutowireByNamePerformanceOptimization(applicationContext)
76+
if(enableBeanCreationProfiler) {
77+
def processor = new BeanCreationProfilingPostProcessor()
78+
applicationContext.getBeanFactory().addBeanPostProcessor(processor)
79+
applicationContext.addApplicationListener(processor)
80+
}
7281
return applicationContext
7382
}
7483

@@ -77,7 +86,9 @@ class GrailsApp extends SpringApplication {
7786
if(configurableApplicationContext instanceof GenericApplicationContext) {
7887
Field beanFactoryField = ReflectionUtils.findField(GenericApplicationContext, "beanFactory", DefaultListableBeanFactory)
7988
ReflectionUtils.makeAccessible(beanFactoryField)
80-
ReflectionUtils.setField(beanFactoryField, configurableApplicationContext, new OptimizedAutowireCapableBeanFactory())
89+
90+
def beanFactory = new OptimizedAutowireCapableBeanFactory()
91+
ReflectionUtils.setField(beanFactoryField, configurableApplicationContext, beanFactory)
8192
}
8293
}
8394

grails-core/src/main/groovy/grails/boot/config/GrailsApplicationPostProcessor.groovy

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ class GrailsApplicationPostProcessor implements BeanDefinitionRegistryPostProces
6161
boolean loadExternalBeans = true
6262
boolean reloadingEnabled = RELOADING_ENABLED
6363

64-
6564
GrailsApplicationPostProcessor(GrailsApplicationLifeCycle lifeCycle, ApplicationContext applicationContext, Class...classes) {
6665
this.lifeCycle = lifeCycle
6766
if(lifeCycle instanceof GrailsApplicationClass) {
@@ -106,7 +105,6 @@ class GrailsApplicationPostProcessor implements BeanDefinitionRegistryPostProces
106105
for(cls in classes) {
107106
grailsApplication.addArtefact(cls)
108107
}
109-
110108
pluginManager.registerProvidedArtefacts(grailsApplication)
111109
}
112110

0 commit comments

Comments
 (0)