Skip to content

Commit b0e5375

Browse files
committed
Improvements to subproject reloading in multi-project builds
1 parent 68504d7 commit b0e5375

File tree

5 files changed

+105
-12
lines changed

5 files changed

+105
-12
lines changed

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,32 @@ class IOUtils extends SpringIOUtils {
125125
return new URL("$rootPath/")
126126
}
127127
throw new IllegalStateException("Root classpath resource not found! Check your disk permissions")
128+
}
129+
128130

131+
/**
132+
* This method differs from {@link #findRootResource(java.lang.Class)} in that it will find the root URL where to load resources defined in src/main/resources
133+
*
134+
* At development time this with be build/main/resources, but in production it will be relative to the class.
135+
*
136+
* @param targetClass
137+
* @param path
138+
* @return
139+
*/
140+
static URL findRootResourcesURL(Class targetClass) {
141+
def pathToClassFile = '/' + targetClass.name.replace(".", "/") + ".class"
142+
def classRes = targetClass.getResource(pathToClassFile)
143+
if(classRes) {
144+
String rootPath = classRes.toString() - pathToClassFile
145+
if(rootPath.endsWith(BuildSettings.BUILD_CLASSES_PATH)) {
146+
rootPath = rootPath.replace('/build/classes/', '/build/resources/')
147+
}
148+
else {
149+
rootPath = "$rootPath/"
150+
}
151+
return new URL(rootPath)
152+
}
153+
return null
129154
}
130155

131156
/**
@@ -149,6 +174,7 @@ class IOUtils extends SpringIOUtils {
149174
}
150175
/**
151176
* Finds a URL within a JAR relative (from the root) to the given class
177+
*
152178
* @param targetClass
153179
* @param path
154180
* @return
@@ -166,6 +192,7 @@ class IOUtils extends SpringIOUtils {
166192
return null
167193
}
168194

195+
169196
@Memoized
170197
public static File findApplicationDirectoryFile() {
171198
def directory = findApplicationDirectory()
@@ -179,6 +206,27 @@ class IOUtils extends SpringIOUtils {
179206
return null
180207
}
181208

209+
/**
210+
* Finds the application directory for the given class
211+
*
212+
* @param targetClass The target class
213+
* @return The application directory or null if it can't be found
214+
*/
215+
public static File findApplicationDirectoryFile(Class targetClass) {
216+
217+
def rootResource = findRootResource(targetClass)
218+
if(rootResource != null) {
219+
220+
def rootFile = new UrlResource(rootResource).file.canonicalFile
221+
222+
def rootPath = rootFile.path
223+
if(rootPath.contains(BuildSettings.BUILD_CLASSES_PATH)) {
224+
return new File(rootPath - BuildSettings.BUILD_CLASSES_PATH)
225+
}
226+
}
227+
return null
228+
}
229+
182230
@Memoized
183231
public static String findApplicationDirectory() {
184232
if(applicationDirectory) {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,8 @@ public static boolean isDevelopmentEnvironmentAvailable() {
280280
* @return True if the development sources are present
281281
*/
282282
public static boolean isDevelopmentRun() {
283-
return BuildSettings.GRAILS_APP_DIR_PRESENT && Boolean.getBoolean(RUN_ACTIVE);
283+
Environment env = Environment.getCurrent();
284+
return BuildSettings.GRAILS_APP_DIR_PRESENT && Boolean.getBoolean(RUN_ACTIVE) && (env == Environment.DEVELOPMENT || env == Environment.TEST);
284285
}
285286
/**
286287
* Check whether the application is deployed

grails-core/src/main/groovy/org/grails/plugins/BinaryGrailsPlugin.java

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.springframework.core.io.support.ResourcePatternResolver;
2626
import org.springframework.util.StringUtils;
2727

28+
import java.io.File;
2829
import java.io.IOException;
2930
import java.io.InputStream;
3031
import java.net.URL;
@@ -46,9 +47,14 @@ public class BinaryGrailsPlugin extends DefaultGrailsPlugin {
4647
public static final char UNDERSCORE = '_';
4748
public static final String PROPERTIES_EXTENSION = ".properties";
4849

49-
private BinaryGrailsPluginDescriptor descriptor;
50+
private final BinaryGrailsPluginDescriptor descriptor;
5051
private Class[] providedArtefacts = {};
51-
private Map<String, Class> precompiledViewMap = new HashMap<String, Class>();
52+
private final Map<String, Class> precompiledViewMap = new HashMap<String, Class>();
53+
private final Resource baseResource;
54+
private final Resource baseResourcesResource;
55+
private final String baseResourceString;
56+
private final boolean isJar;
57+
private final File projectDirectory;
5258

5359
/**
5460
* Creates a binary plugin instance.
@@ -60,13 +66,36 @@ public class BinaryGrailsPlugin extends DefaultGrailsPlugin {
6066
public BinaryGrailsPlugin(Class<?> pluginClass, BinaryGrailsPluginDescriptor descriptor, GrailsApplication application) {
6167
super(pluginClass, application);
6268
this.descriptor = descriptor;
69+
URL rootResource = IOUtils.findRootResource(pluginClass);
70+
if(rootResource == null) {
71+
throw new PluginException("Cannot evaluate plugin location for plugin " + pluginClass);
72+
}
73+
this.baseResource = new UrlResource(rootResource);
74+
try {
75+
this.baseResourceString = baseResource.getURL().toString();
76+
} catch (IOException e) {
77+
throw new PluginException("Cannot evaluate plugin location for plugin " + pluginClass, e);
78+
}
79+
80+
this.isJar = baseResourceString.startsWith("jar:");
81+
this.projectDirectory = isJar ? null : IOUtils.findApplicationDirectoryFile(pluginClass);
82+
83+
URL rootResourcesURL = IOUtils.findRootResourcesURL(pluginClass);
84+
if(rootResourcesURL == null) {
85+
throw new PluginException("Cannot evaluate plugin location for plugin " + pluginClass);
86+
}
6387

88+
this.baseResourcesResource= new UrlResource(rootResourcesURL);
6489
if (descriptor != null) {
6590
initializeProvidedArtefacts(descriptor.getProvidedlassNames());
6691
initializeViewMap(descriptor);
6792
}
6893
}
6994

95+
public File getProjectDirectory() {
96+
return projectDirectory;
97+
}
98+
7099
protected void initializeViewMap(BinaryGrailsPluginDescriptor descriptor) {
71100
final Resource descriptorResource = descriptor.getResource();
72101

@@ -174,7 +203,7 @@ public Resource getResource(String path) {
174203
* @return The properties or null if non exist
175204
*/
176205
public Properties getProperties(final Locale locale) {
177-
Resource url = findPluginJar();
206+
Resource url = this.baseResourcesResource;
178207
Properties properties = null;
179208
if(url != null) {
180209
StaticResourceLoader resourceLoader = new StaticResourceLoader();
@@ -186,6 +215,8 @@ public Properties getProperties(final Locale locale) {
186215
resources = filterResources(resources, locale);
187216
properties = new Properties();
188217

218+
// message bundles are locale specific. The more underscores the locale has the more specific the locale
219+
// so we order by the number of underscores present so that the most specific appears
189220
Arrays.sort(resources, new Comparator<Resource>() {
190221
@Override
191222
public int compare(Resource o1, Resource o2) {
@@ -212,13 +243,6 @@ public int compare(Resource o1, Resource o2) {
212243
return properties;
213244
}
214245

215-
protected Resource findPluginJar() {
216-
URL url = IOUtils.findJarResource(pluginClass);
217-
if(url != null) {
218-
return new UrlResource(url);
219-
}
220-
return null;
221-
}
222246

223247
private Resource[] filterResources(Resource[] resources, Locale locale) {
224248
List<Resource> finalResources = new ArrayList<Resource>(resources.length);

grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/core/GrailsPluginGradlePlugin.groovy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ class GrailsPluginGradlePlugin extends GrailsGradlePlugin {
193193
processResources.dependsOn(*processResourcesDependencies)
194194
project.processResources {
195195
exclude "spring/resources.groovy"
196+
exclude "**/*.gsp"
196197
}
197198
}
198199

grails-gsp/src/main/groovy/org/grails/gsp/io/DefaultGroovyPageLocator.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@
3232
import org.springframework.context.ApplicationContext;
3333
import org.springframework.context.ApplicationContextAware;
3434
import org.springframework.context.ResourceLoaderAware;
35+
import org.springframework.core.io.FileSystemResource;
3536
import org.springframework.core.io.Resource;
3637
import org.springframework.core.io.ResourceLoader;
3738

39+
import java.io.File;
3840
import java.security.PrivilegedAction;
3941
import java.util.Collection;
4042
import java.util.List;
@@ -200,15 +202,32 @@ protected GroovyPageScriptSource findBinaryScriptSource(String uri) {
200202
if (!(plugin instanceof BinaryGrailsPlugin)) {
201203
continue;
202204
}
203-
GroovyPageScriptSource scriptSource = resolveViewInBinaryPlugin((BinaryGrailsPlugin) plugin, uri);
205+
206+
BinaryGrailsPlugin binaryPlugin = (BinaryGrailsPlugin) plugin;
207+
GroovyPageScriptSource scriptSource = resolveViewInBinaryPlugin(binaryPlugin, uri);
204208
if (scriptSource != null) {
205209
return scriptSource;
206210
}
211+
else if(binaryPlugin.getProjectDirectory() != null) {
212+
scriptSource = resolveViewInPluginProjectDirectory(binaryPlugin, uri);
213+
if(scriptSource != null) {
214+
return scriptSource;
215+
}
216+
}
207217
}
208218

209219
return null;
210220
}
211221

222+
private GroovyPageScriptSource resolveViewInPluginProjectDirectory(BinaryGrailsPlugin binaryPlugin, String uri) {
223+
File projectDirectory = binaryPlugin.getProjectDirectory();
224+
File f = new File(projectDirectory, "grails-app/views" + uri);
225+
if(f.exists()) {
226+
return new GroovyPageResourceScriptSource(uri, new FileSystemResource(f));
227+
}
228+
return null;
229+
}
230+
212231
protected GroovyPageScriptSource findResourceScriptSourceInPlugins(String uri) {
213232
if (pluginManager == null) {
214233
return null;

0 commit comments

Comments
 (0)