1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.fatwire.gst.foundation.groovy;
18
19 import groovy.util.GroovyScriptEngine;
20 import groovy.util.ResourceException;
21 import groovy.util.ScriptException;
22
23 import java.io.File;
24 import java.io.FileFilter;
25 import java.net.MalformedURLException;
26 import java.net.URI;
27 import java.net.URL;
28
29 import javax.servlet.ServletContext;
30
31 import org.apache.commons.lang.StringUtils;
32 import org.apache.commons.logging.Log;
33 import org.codehaus.groovy.control.CompilationFailedException;
34
35 import com.fatwire.gst.foundation.facade.logging.LogUtil;
36
37
38
39
40
41
42
43
44
45
46
47 public class DiskGroovyLoader implements GroovyLoader {
48
49 private Log logger = LogUtil.getLog(getClass());
50 private GroovyScriptEngine groovyScriptEngine;
51
52 private File scriptPath;
53 private String configPath = "/WEB-INF/gsf-groovy";
54 private int minimumRecompilationInterval = 0;
55
56 public DiskGroovyLoader() {
57 super();
58
59 }
60
61 public DiskGroovyLoader(ServletContext servletContext) {
62 bootEngine(servletContext.getRealPath(configPath));
63
64 }
65
66 public void bootEngine(String path) {
67 scriptPath = new File(path).getAbsoluteFile();
68 scriptPath.mkdirs();
69 if (!scriptPath.exists() || !scriptPath.isDirectory())
70 throw new IllegalStateException("The realPath " + scriptPath + " is not a directory.");
71 URI u = scriptPath.toURI();
72 URL[] paths;
73 try {
74 paths = new URL[] { u.toURL() };
75 groovyScriptEngine = new GroovyScriptEngine(paths, Thread.currentThread().getContextClassLoader());
76 groovyScriptEngine.getConfig().setRecompileGroovySource(true);
77 groovyScriptEngine.getConfig().setMinimumRecompilationInterval(minimumRecompilationInterval);
78 } catch (MalformedURLException e) {
79 throw new IllegalStateException("The realPath " + scriptPath + " can't be made into a URL. "
80 + e.getMessage(), e);
81 }
82
83 }
84
85 @Override
86 public Object load(final String name) throws Exception {
87
88 Class<?> c;
89 try {
90 c = groovyScriptEngine.loadScriptByName(toScriptName(name));
91 } catch (ResourceException e) {
92
93 if (logger.isDebugEnabled())
94 logger.debug("GroovyScriptEngine was not able to load " + name + " as a script: " + e.getMessage()
95 + ". Now trying as a class.");
96 String className = name.replace('/', '.');
97 try {
98 c = groovyScriptEngine.getGroovyClassLoader().loadClass(className);
99 } catch (ClassNotFoundException cnfe) {
100 if (logger.isDebugEnabled())
101 logger.debug("GroovyClassLoader was not able to load " + className + ": " + cnfe.getMessage()
102 + ". Aborting.");
103 return null;
104
105 }
106 }
107
108 return c.newInstance();
109 }
110
111 protected String toScriptName(String name) {
112 if (name.endsWith(".groovy")) {
113 return StringUtils.removeEnd(name, ".groovy").replace('.', '/') + ".groovy";
114 } else
115 return name.replace('.', '/') + ".groovy";
116 }
117
118 protected String toClassName(String name) {
119
120 return name.replace('/', '.').replace('\\', '.').substring(0, name.length() - 7);
121 }
122
123 public void precompile() {
124 doDir(scriptPath);
125
126 }
127
128 protected void doDir(File dir) {
129 File[] listFiles = dir.listFiles(new FileFilter() {
130
131 @Override
132 public boolean accept(File pathname) {
133 return pathname.isDirectory() || pathname.getName().endsWith(".groovy");
134 }
135
136 });
137 for (File file : listFiles) {
138 if (file.isDirectory()) {
139 doDir(file);
140 } else {
141 String name = file.getAbsolutePath().substring(scriptPath.getAbsolutePath().length() + 1);
142 try {
143
144 groovyScriptEngine.loadScriptByName(name);
145 } catch (CompilationFailedException e) {
146 logger.warn(e.getMessage() + " on " + name + " during precompilation.");
147 } catch (ResourceException e) {
148 logger.warn(e.getMessage() + " on " + name + " during precompilation.");
149 } catch (ScriptException e) {
150 logger.warn(e.getMessage() + " on " + name + " during precompilation.");
151 }
152 }
153 }
154 }
155
156
157
158
159 public String getConfigPath() {
160 return configPath;
161 }
162
163
164
165
166 public void setConfigPath(String configPath) {
167 this.configPath = configPath;
168 }
169
170
171
172
173 public int getMinimumRecompilationInterval() {
174 return minimumRecompilationInterval;
175 }
176
177
178
179
180
181
182
183
184 public void setMinimumRecompilationInterval(int minimumRecompilationInterval) {
185 this.minimumRecompilationInterval = minimumRecompilationInterval;
186 GroovyScriptEngine g = getGroovyScriptEngine();
187 if (g != null) {
188 g.getConfig().setMinimumRecompilationInterval(minimumRecompilationInterval);
189 }
190 }
191
192 public GroovyScriptEngine getGroovyScriptEngine() {
193 return groovyScriptEngine;
194 }
195
196 public void setGroovyScriptEngine(GroovyScriptEngine groovyScrptEngine) {
197 this.groovyScriptEngine = groovyScrptEngine;
198 }
199
200 }