gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.lib / org.gvsig.scripting.lib.impl / src / main / java / org / gvsig / scripting / impl / DefaultScriptingManager.java @ 1120
History | View | Annotate | Download (27.9 KB)
1 | 164 | jobacas | package org.gvsig.scripting.impl; |
---|---|---|---|
2 | |||
3 | import java.io.File; |
||
4 | 669 | jjdelcerro | import java.io.IOException; |
5 | 1068 | jjdelcerro | import java.net.URI; |
6 | 164 | jobacas | import java.util.ArrayList; |
7 | 468 | jjdelcerro | import java.util.Collections; |
8 | 164 | jobacas | import java.util.HashMap; |
9 | import java.util.Iterator; |
||
10 | import java.util.List; |
||
11 | import java.util.Map; |
||
12 | 799 | jjdelcerro | import java.util.Set; |
13 | 1120 | jjdelcerro | import java.util.regex.Matcher; |
14 | import java.util.regex.Pattern; |
||
15 | 164 | jobacas | |
16 | import javax.script.ScriptContext; |
||
17 | import javax.script.ScriptEngine; |
||
18 | 220 | cordinyana | import javax.script.ScriptEngineFactory; |
19 | 164 | jobacas | import javax.script.ScriptEngineManager; |
20 | import javax.script.SimpleBindings; |
||
21 | import javax.swing.ImageIcon; |
||
22 | 1120 | jjdelcerro | import org.apache.commons.io.IOUtils; |
23 | 164 | jobacas | |
24 | 799 | jjdelcerro | import org.apache.commons.lang3.StringUtils; |
25 | 1084 | jjdelcerro | import org.gvsig.scripting.DataFolderFound; |
26 | 164 | jobacas | import org.gvsig.scripting.ScriptingBaseScript; |
27 | import org.gvsig.scripting.ScriptingDialog; |
||
28 | 702 | jjdelcerro | import org.gvsig.scripting.ScriptingExternalFile; |
29 | 164 | jobacas | import org.gvsig.scripting.ScriptingFolder; |
30 | import org.gvsig.scripting.ScriptingManager; |
||
31 | import org.gvsig.scripting.ScriptingScript; |
||
32 | import org.gvsig.scripting.ScriptingUnit; |
||
33 | 1084 | jjdelcerro | import org.gvsig.tools.packageutils.Version; |
34 | 1120 | jjdelcerro | import org.gvsig.tools.resourcesstorage.ResourcesStorage; |
35 | 630 | jjdelcerro | import org.gvsig.tools.script.Script; |
36 | 468 | jjdelcerro | import org.gvsig.tools.service.spi.ProviderFactory; |
37 | 1084 | jjdelcerro | import org.gvsig.tools.util.FolderSet; |
38 | 679 | jjdelcerro | import org.python.jsr223.MyPyScriptEngine; |
39 | 301 | jjdelcerro | import org.slf4j.Logger; |
40 | import org.slf4j.LoggerFactory; |
||
41 | 164 | jobacas | |
42 | 630 | jjdelcerro | |
43 | 1084 | jjdelcerro | @SuppressWarnings("UseSpecificCatch") |
44 | 464 | jjdelcerro | public class DefaultScriptingManager implements ScriptingManager { |
45 | 164 | jobacas | |
46 | 468 | jjdelcerro | public static class RegisterSystemFolder { |
47 | |||
48 | public String name; |
||
49 | public File folder; |
||
50 | |||
51 | public RegisterSystemFolder(String name, File folder) { |
||
52 | this.name = name;
|
||
53 | this.folder = folder;
|
||
54 | } |
||
55 | } |
||
56 | |||
57 | 814 | jjdelcerro | static final Logger LOG = LoggerFactory |
58 | 464 | jjdelcerro | .getLogger(DefaultScriptingManager.class); |
59 | 799 | jjdelcerro | |
60 | 212 | cordinyana | protected Map<String, ImageIcon> icons; |
61 | 468 | jjdelcerro | protected List<RegisterSystemFolder> systemFolders = new ArrayList<>(); |
62 | 464 | jjdelcerro | protected ScriptEngineManager engineManager = null; |
63 | private final SimpleBindings bindings = new SimpleBindings(); |
||
64 | private List<String> unitTypes = null; |
||
65 | 220 | cordinyana | private ClassLoader classLoader = null; |
66 | 799 | jjdelcerro | private final List<File> libFolders = new ArrayList<>(); |
67 | 301 | jjdelcerro | private File home = null; |
68 | 799 | jjdelcerro | private final List<ScriptingFolder> alternativeUserFolders = new ArrayList<>(); |
69 | 468 | jjdelcerro | private Map<String, String> extensionOfLanguage = null; |
70 | private Map<String, String> languageOfExtension = null; |
||
71 | private File packagesFolder; |
||
72 | 724 | jjdelcerro | private final Map properties = new HashMap(); |
73 | 799 | jjdelcerro | private final Map<String,ScriptEngine> engineGroups = new HashMap<>(); |
74 | 1084 | jjdelcerro | private DataFolderManager dataFolderManager = null; |
75 | private ScriptingFolder userFolder = null; |
||
76 | private ScriptingFolder systemFolder = null; |
||
77 | 799 | jjdelcerro | |
78 | 1020 | jjdelcerro | @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"}) |
79 | 220 | cordinyana | public DefaultScriptingManager() {
|
80 | 301 | jjdelcerro | this.classLoader = getClass().getClassLoader();
|
81 | this.setHomeFolder(null); |
||
82 | this.bindings.put("ScriptingManager", this); |
||
83 | 220 | cordinyana | } |
84 | 164 | jobacas | |
85 | 220 | cordinyana | public DefaultScriptingManager(ClassLoader classLoader) { |
86 | this();
|
||
87 | this.classLoader = classLoader;
|
||
88 | } |
||
89 | |||
90 | 724 | jjdelcerro | @Override
|
91 | public Object getProperty(Object key) { |
||
92 | return properties.get(key);
|
||
93 | } |
||
94 | |||
95 | @Override
|
||
96 | public void setProperty(Object key, Object val) { |
||
97 | properties.put(key, val); |
||
98 | } |
||
99 | |||
100 | @Override
|
||
101 | public Map getExtendedProperties() { |
||
102 | return properties;
|
||
103 | } |
||
104 | |||
105 | 464 | jjdelcerro | private void createFolder(File f) { |
106 | if (!f.exists()) {
|
||
107 | try {
|
||
108 | FileUtils.forceMkdir(f); |
||
109 | LOG.info("Created scripting folder '" + f.getAbsolutePath() + "'"); |
||
110 | } catch (Throwable e) { |
||
111 | LOG.warn("Can't Create scripting folder '" + f.getAbsolutePath() + "'"); |
||
112 | } |
||
113 | } |
||
114 | 301 | jjdelcerro | } |
115 | 220 | cordinyana | |
116 | 301 | jjdelcerro | private void createDefaultFolders(File home) { |
117 | 464 | jjdelcerro | createFolder(new File(home, "scripts")); |
118 | createFolder(new File(home, "lib")); |
||
119 | 975 | jjdelcerro | createFolder(new File(home, "data")); |
120 | 220 | cordinyana | } |
121 | 464 | jjdelcerro | |
122 | 468 | jjdelcerro | @Override
|
123 | 301 | jjdelcerro | public File getHomeFolder() { |
124 | 464 | jjdelcerro | if (!this.home.exists()) { |
125 | createFolder(home); |
||
126 | createDefaultFolders(home); |
||
127 | } |
||
128 | return this.home; |
||
129 | 301 | jjdelcerro | } |
130 | 464 | jjdelcerro | |
131 | 468 | jjdelcerro | @Override
|
132 | 301 | jjdelcerro | public void setHomeFolder(File home) { |
133 | 464 | jjdelcerro | if (home == null) { |
134 | this.home = new File(System.getProperty("user.home"), ".gvsig-scripting"); |
||
135 | } else {
|
||
136 | this.home = home;
|
||
137 | } |
||
138 | createDefaultFolders(this.home);
|
||
139 | LOG.info("Set scripting home to '" + this.home.getAbsolutePath() + "'"); |
||
140 | this.addLibFolder(new File(this.home, "lib")); |
||
141 | 301 | jjdelcerro | } |
142 | 975 | jjdelcerro | |
143 | 1084 | jjdelcerro | private DataFolderManager getDataFolderManager() {
|
144 | if( this.dataFolderManager==null ) { |
||
145 | this.dataFolderManager = new DataFolderManager(this); |
||
146 | } |
||
147 | return this.dataFolderManager; |
||
148 | } |
||
149 | |||
150 | 986 | jjdelcerro | @Override
|
151 | 975 | jjdelcerro | public File getDataFolder(String id) { |
152 | 1084 | jjdelcerro | return this.getDataFolderManager().getDataFolder(id); |
153 | 975 | jjdelcerro | } |
154 | 464 | jjdelcerro | |
155 | 1084 | jjdelcerro | public void registerDataFolder(ScriptingFolder folderScript, String id ) { |
156 | this.getDataFolderManager().registerDataFolder(folderScript, id);
|
||
157 | } |
||
158 | |||
159 | @Override
|
||
160 | public List<DataFolderFound> searchOldVersions(Version currentVersion, FolderSet folder) { |
||
161 | return this.getDataFolderManager().searchOldVersions(currentVersion, folder); |
||
162 | } |
||
163 | |||
164 | 799 | jjdelcerro | protected synchronized ScriptEngineManager getEngineManager() { |
165 | 464 | jjdelcerro | if (this.engineManager == null) { |
166 | this.engineManager
|
||
167 | = classLoader == null ? new ScriptEngineManager() |
||
168 | : new ScriptEngineManager(classLoader);
|
||
169 | 220 | cordinyana | showEnginesInfo(engineManager); |
170 | 464 | jjdelcerro | } |
171 | return this.engineManager; |
||
172 | } |
||
173 | |||
174 | 220 | cordinyana | private void showEnginesInfo(ScriptEngineManager mgr) { |
175 | if (LOG.isInfoEnabled()) {
|
||
176 | List<ScriptEngineFactory> factories = mgr.getEngineFactories();
|
||
177 | 468 | jjdelcerro | StringBuilder buffer = new StringBuilder(); |
178 | List<Object> values = new ArrayList<>(); |
||
179 | 220 | cordinyana | buffer.append("Scripting engines available:");
|
180 | for (ScriptEngineFactory factory : factories) {
|
||
181 | |||
182 | // Main engine info
|
||
183 | buffer |
||
184 | 464 | jjdelcerro | .append("\n- {}: version = {}, language = {}, langVersion = {}");
|
185 | 220 | cordinyana | values.add(factory.getEngineName()); |
186 | values.add(factory.getEngineVersion()); |
||
187 | values.add(factory.getLanguageName()); |
||
188 | values.add(factory.getLanguageVersion()); |
||
189 | |||
190 | // Aliases
|
||
191 | buffer.append("\n\t- Aliases: ");
|
||
192 | List<String> engNames = factory.getNames(); |
||
193 | int size = engNames.size();
|
||
194 | for (String name : engNames) { |
||
195 | size--; |
||
196 | buffer.append("{}");
|
||
197 | if (size > 0) { |
||
198 | buffer.append(", ");
|
||
199 | } |
||
200 | values.add(name); |
||
201 | } |
||
202 | buffer.append("\n\t- File extensions: ");
|
||
203 | List<String> extNames = factory.getExtensions(); |
||
204 | size = extNames.size(); |
||
205 | for (String name : extNames) { |
||
206 | size--; |
||
207 | buffer.append("{}");
|
||
208 | if (size > 0) { |
||
209 | buffer.append(", ");
|
||
210 | } |
||
211 | values.add(name); |
||
212 | } |
||
213 | buffer.append("\n\t- Mime types: ");
|
||
214 | List<String> mimeNames = factory.getMimeTypes(); |
||
215 | size = mimeNames.size(); |
||
216 | for (String name : mimeNames) { |
||
217 | size--; |
||
218 | buffer.append("{}");
|
||
219 | if (size > 0) { |
||
220 | buffer.append(", ");
|
||
221 | } |
||
222 | values.add(name); |
||
223 | } |
||
224 | |||
225 | } |
||
226 | LOG.info(buffer.toString(), values.toArray()); |
||
227 | } |
||
228 | } |
||
229 | |||
230 | 799 | jjdelcerro | @Override
|
231 | public synchronized void loadEngines() { |
||
232 | 583 | jjdelcerro | this.getEngineManager();
|
233 | } |
||
234 | |||
235 | 799 | jjdelcerro | private ScriptEngine createJythonEngine() {
|
236 | ScriptEngineFactory factory = this.getEngineFactoryByLanguage(PYTHON_LANGUAGE_NAME);
|
||
237 | 679 | jjdelcerro | ScriptEngine engine = new MyPyScriptEngine(factory);
|
238 | 464 | jjdelcerro | return engine;
|
239 | } |
||
240 | 679 | jjdelcerro | |
241 | 464 | jjdelcerro | public ImageIcon getIcon(String name) { |
242 | return this.icons.get(name); |
||
243 | } |
||
244 | |||
245 | 468 | jjdelcerro | @Override
|
246 | public String getEngineNameByLanguage(String langName) { |
||
247 | 679 | jjdelcerro | ScriptEngineFactory factory = this.getEngineFactoryByLanguage(langName);
|
248 | if( factory == null ) { |
||
249 | return null; |
||
250 | } |
||
251 | return factory.getEngineName();
|
||
252 | } |
||
253 | 799 | jjdelcerro | |
254 | public ScriptEngine getEngineByLanguage(String langName) { |
||
255 | return this.getEngineByLanguage(langName, null); |
||
256 | 724 | jjdelcerro | } |
257 | 799 | jjdelcerro | |
258 | public synchronized ScriptEngine getEngineByLanguage(String langName, String isolationGroup) { |
||
259 | ScriptEngine engine = null;
|
||
260 | if( !StringUtils.isEmpty(isolationGroup) ) {
|
||
261 | isolationGroup += "-" + langName;
|
||
262 | engine = this.engineGroups.get(isolationGroup.toLowerCase());
|
||
263 | } |
||
264 | if( engine == null ) { |
||
265 | if( PYTHON_LANGUAGE_NAME.equalsIgnoreCase(langName) ) {
|
||
266 | engine = createJythonEngine(); |
||
267 | } else {
|
||
268 | ScriptEngineFactory factory = this.getEngineFactoryByLanguage(langName);
|
||
269 | if( factory == null ) { |
||
270 | return null; |
||
271 | } |
||
272 | engine = factory.getScriptEngine(); |
||
273 | 226 | cordinyana | } |
274 | 1020 | jjdelcerro | // if( SCALA_LANGUAGE_NAME.equalsIgnoreCase(langName) ) {
|
275 | // try {
|
||
276 | // // https://gist.github.com/takawitter/5479445
|
||
277 | // Object settings = engine.getClass().getMethod("settings", new Class[0]).invoke(engine, new Object[0]);
|
||
278 | // settings.getClass().getMethod("processArgumentString", new Class[] { String.class }).invoke(settings, new String[] { "-usejavacp"});
|
||
279 | // } catch(Throwable th) {
|
||
280 | // LOG.warn("Can't initialice scala setting -usejavacp",th);
|
||
281 | // }
|
||
282 | // }
|
||
283 | 799 | jjdelcerro | if( !StringUtils.isEmpty(isolationGroup) ) {
|
284 | this.engineGroups.put(isolationGroup.toLowerCase(), engine);
|
||
285 | } |
||
286 | 226 | cordinyana | } |
287 | 679 | jjdelcerro | engine.getBindings(ScriptContext.ENGINE_SCOPE).putAll(bindings); |
288 | return engine;
|
||
289 | 464 | jjdelcerro | } |
290 | |||
291 | 799 | jjdelcerro | @Override
|
292 | public synchronized Set<String> getEnginesIsolationGroups() { |
||
293 | return this.engineGroups.keySet(); |
||
294 | } |
||
295 | |||
296 | 679 | jjdelcerro | public ScriptEngineFactory getEngineFactoryByLanguage(String langName) { |
297 | 468 | jjdelcerro | List<ScriptEngineFactory> factories
|
298 | = getEngineManager().getEngineFactories(); |
||
299 | |||
300 | for (ScriptEngineFactory factory : factories) {
|
||
301 | if (factory.getLanguageName().equalsIgnoreCase(langName)) {
|
||
302 | 679 | jjdelcerro | return factory;
|
303 | 468 | jjdelcerro | } |
304 | 464 | jjdelcerro | } |
305 | 468 | jjdelcerro | return null; |
306 | 464 | jjdelcerro | } |
307 | |||
308 | 468 | jjdelcerro | @Override
|
309 | 464 | jjdelcerro | public boolean validateUnitId(ScriptingFolder folder, String id) { |
310 | 724 | jjdelcerro | File f = new File(folder.getFile(),id+".inf"); |
311 | 1020 | jjdelcerro | return !f.exists();
|
312 | 464 | jjdelcerro | } |
313 | 164 | jobacas | |
314 | 464 | jjdelcerro | public ScriptingScript createScript(ScriptingFolder folder, String id) { |
315 | return this.createScript(folder, id, null); |
||
316 | } |
||
317 | 630 | jjdelcerro | |
318 | 799 | jjdelcerro | @Override
|
319 | 630 | jjdelcerro | public Script createScript(String name, String code, String languaje) { |
320 | 1120 | jjdelcerro | ScriptingScript script = new DefaultScriptingScript(this.getUserFolder(), this, name, languaje); |
321 | 630 | jjdelcerro | script.setCode(code); |
322 | script.setSaved(true);
|
||
323 | return script;
|
||
324 | } |
||
325 | 164 | jobacas | |
326 | 464 | jjdelcerro | private ScriptingScript createScript(ScriptingFolder folder, String id, String language) { |
327 | DefaultScriptingScript script = new DefaultScriptingScript(folder, this, id); |
||
328 | if (!script.getFile().exists()) {
|
||
329 | script.create(folder, id, language); |
||
330 | } else {
|
||
331 | script.load(folder, id); |
||
332 | } |
||
333 | return script;
|
||
334 | } |
||
335 | 164 | jobacas | |
336 | 464 | jjdelcerro | public ScriptingDialog createDialog(ScriptingFolder folder, String id) { |
337 | return this.createDialog(folder, id, null); |
||
338 | } |
||
339 | 164 | jobacas | |
340 | 464 | jjdelcerro | private ScriptingDialog createDialog(ScriptingFolder folder, String id, String language) { |
341 | DefaultScriptingDialog dialog = new DefaultScriptingDialog(folder, this, id); |
||
342 | if (!dialog.getFile().exists()) {
|
||
343 | dialog.create(folder, id, language); |
||
344 | } else {
|
||
345 | dialog.load(folder, id); |
||
346 | } |
||
347 | return dialog;
|
||
348 | } |
||
349 | 164 | jobacas | |
350 | 464 | jjdelcerro | public ScriptingFolder createFolder(ScriptingFolder folder, String id) { |
351 | DefaultScriptingFolder unit = new DefaultScriptingFolder(folder, this, new File(folder.getFile(), id)); |
||
352 | 471 | jjdelcerro | unit.load(folder, id); |
353 | 585 | jjdelcerro | if (!unit.getFile().exists()) {
|
354 | unit.create(folder, id); |
||
355 | } |
||
356 | 464 | jjdelcerro | return unit;
|
357 | } |
||
358 | 164 | jobacas | |
359 | 702 | jjdelcerro | public ScriptingExternalFile createExternalFile(ScriptingFolder folder, String id) { |
360 | DefaultScriptingExternalFile unit = new DefaultScriptingExternalFile(folder, this, id); |
||
361 | 952 | jjdelcerro | if( unit.getExternalFile()!=null && !unit.getExternalFile().exists() ) { |
362 | unit.create(folder, id); |
||
363 | } |
||
364 | 702 | jjdelcerro | return unit;
|
365 | } |
||
366 | |||
367 | 468 | jjdelcerro | @Override
|
368 | 464 | jjdelcerro | public ScriptingBaseScript getScript(File file) { |
369 | ScriptingBaseScript script = (ScriptingBaseScript) this.getUnit(file);
|
||
370 | if (script == null) { |
||
371 | throw new ScriptNotFoundException(file); |
||
372 | } |
||
373 | return script;
|
||
374 | } |
||
375 | 1068 | jjdelcerro | |
376 | @Override
|
||
377 | public Script loadScript(URI uri) { |
||
378 | File f = new File(uri); |
||
379 | try {
|
||
380 | return (Script) this.getScript(f); |
||
381 | } catch(ScriptNotFoundException ex) {
|
||
382 | throw ex;
|
||
383 | } catch(Throwable th) { |
||
384 | throw new ScriptNotFoundException(f); |
||
385 | } |
||
386 | } |
||
387 | 164 | jobacas | |
388 | 1120 | jjdelcerro | private static final Pattern RE_LANG = Pattern.compile(".*lang[:]\\s*([a-zA-Z_][a-zA-Z_0-9]*)"); |
389 | private static final Pattern RE_ENCODING = Pattern.compile(".*encoding[:]\\s*([a-zA-Z_][a-zA-Z_0-9]*)"); |
||
390 | |||
391 | public Script loadScript(ResourcesStorage storage, String name) { |
||
392 | ResourcesStorage.Resource res = null;
|
||
393 | try {
|
||
394 | if( storage==null ) { |
||
395 | return null; |
||
396 | } |
||
397 | res = storage.getResource(name); |
||
398 | if( res == null || !res.exists() ) { |
||
399 | return null; |
||
400 | } |
||
401 | byte[] head_bytes = new byte[500]; |
||
402 | IOUtils.read(res.asInputStream(), head_bytes); |
||
403 | IOUtils.closeQuietly(res); |
||
404 | String head = new String(head_bytes); |
||
405 | if( StringUtils.isEmpty(head) ) {
|
||
406 | return null; |
||
407 | } |
||
408 | head = StringUtils.split("\n")[0]; |
||
409 | |||
410 | String lang = "python"; |
||
411 | String encoding = null; |
||
412 | Matcher m = RE_LANG.matcher(head);
|
||
413 | if( m.groupCount()==1 ) { |
||
414 | String s = m.group(1); |
||
415 | if( !StringUtils.isBlank(s) ) {
|
||
416 | lang = s; |
||
417 | } |
||
418 | } |
||
419 | m = RE_ENCODING.matcher(head); |
||
420 | if( m.groupCount()==1 ) { |
||
421 | String s = m.group(1); |
||
422 | if( !StringUtils.isBlank(s) ) {
|
||
423 | encoding = s; |
||
424 | } |
||
425 | } |
||
426 | 1068 | jjdelcerro | |
427 | 1120 | jjdelcerro | String source;
|
428 | if( StringUtils.isBlank(encoding) ) {
|
||
429 | source = IOUtils.toString(res.asInputStream()); |
||
430 | } else {
|
||
431 | source = IOUtils.toString(res.asInputStream(), encoding); |
||
432 | } |
||
433 | Script script = this.createScript(name, source, lang);
|
||
434 | return script;
|
||
435 | } catch (Exception ex) { |
||
436 | LOG.warn("Can't load script from resources storage.", ex);
|
||
437 | return null; |
||
438 | } finally {
|
||
439 | IOUtils.closeQuietly(res); |
||
440 | } |
||
441 | } |
||
442 | 989 | jjdelcerro | |
443 | 468 | jjdelcerro | @Override
|
444 | 464 | jjdelcerro | public ScriptingFolder getFolder(File file) { |
445 | 989 | jjdelcerro | if( file == null ) { |
446 | throw new IllegalArgumentException("file argument can't be null"); |
||
447 | } |
||
448 | file = this.getLinkSource(file);
|
||
449 | if( FileUtils.isSameFile(this.getRootUserFolder(),file) ) { |
||
450 | return this.getUserFolder(); |
||
451 | } |
||
452 | |||
453 | 464 | jjdelcerro | ScriptingFolder folder = (ScriptingFolder) this.getUnit(file);
|
454 | if (folder == null) { |
||
455 | 989 | jjdelcerro | throw new IllegalArgumentException("Can't get ScriptFolder from '"+file.getAbsolutePath()+"'."); |
456 | 464 | jjdelcerro | } |
457 | return folder;
|
||
458 | } |
||
459 | 301 | jjdelcerro | |
460 | 1084 | jjdelcerro | public ScriptingUnit getUnit(String pathName) { |
461 | ScriptingUnit unit = null;
|
||
462 | String[] parts = StringUtils.split(pathName, '/'); |
||
463 | 1085 | jjdelcerro | if( parts[0].equals(this.getUserFolder().getName()) ) { |
464 | 1084 | jjdelcerro | unit = this.getUserFolder().getUnit(
|
465 | StringUtils.join(parts, "/", 1, parts.length) |
||
466 | ); |
||
467 | 1085 | jjdelcerro | } else if( parts[0].equals(this.getSystemFolder().getName()) ) { |
468 | 1084 | jjdelcerro | unit = this.getSystemFolder().getUnit(
|
469 | StringUtils.join(parts, "/", 1, parts.length) |
||
470 | ); |
||
471 | } |
||
472 | return unit;
|
||
473 | } |
||
474 | |||
475 | 464 | jjdelcerro | public ScriptingUnit getUnit(File file) { |
476 | 468 | jjdelcerro | ScriptingFolder folder; |
477 | ScriptingUnit unit; |
||
478 | 164 | jobacas | |
479 | 464 | jjdelcerro | if (file.isAbsolute()) {
|
480 | 1084 | jjdelcerro | if( FileUtils.isSameFile(this.getRootUserFolder(), file.getParentFile()) ) { |
481 | folder = this.getUserFolder();
|
||
482 | // FIXME: que pasa si esta en SystemFolder ???
|
||
483 | } else {
|
||
484 | folder = new DefaultScriptingFolder(null, this, file.getParentFile()); |
||
485 | } |
||
486 | 464 | jjdelcerro | unit = folder.getUnit(file); |
487 | return unit;
|
||
488 | } else {
|
||
489 | folder = this.getUserFolder();
|
||
490 | unit = folder.getUnit(file); |
||
491 | if (unit != null) { |
||
492 | return unit;
|
||
493 | } |
||
494 | 164 | jobacas | |
495 | 464 | jjdelcerro | folder = this.getSystemFolder();
|
496 | unit = folder.getUnit(file); |
||
497 | if (unit != null) { |
||
498 | return unit;
|
||
499 | } |
||
500 | } |
||
501 | return null; |
||
502 | } |
||
503 | |||
504 | 468 | jjdelcerro | @Override
|
505 | 464 | jjdelcerro | public ScriptingFolder getSystemFolder() {
|
506 | 1084 | jjdelcerro | if( this.systemFolder == null ) { |
507 | this.systemFolder = new SystemFolder(this); |
||
508 | } |
||
509 | return this.systemFolder; |
||
510 | 464 | jjdelcerro | } |
511 | |||
512 | 468 | jjdelcerro | @Override
|
513 | 464 | jjdelcerro | public ScriptingFolder getUserFolder() {
|
514 | 1084 | jjdelcerro | if( this.userFolder == null ) { |
515 | this.userFolder = new UserFolder(this, this.getRootUserFolder()); |
||
516 | } |
||
517 | return this.userFolder; |
||
518 | 464 | jjdelcerro | } |
519 | |||
520 | 468 | jjdelcerro | @Override
|
521 | 464 | jjdelcerro | public ScriptingBaseScript getScript(String name) { |
522 | return (ScriptingBaseScript) findScript(null, name); |
||
523 | } |
||
524 | |||
525 | 986 | jjdelcerro | @Override
|
526 | 814 | jjdelcerro | public Script locateScript(String name) { |
527 | ScriptingUnit script = findScript(null, name);
|
||
528 | if( script instanceof Script ) { |
||
529 | return (Script) script;
|
||
530 | } |
||
531 | return null; |
||
532 | } |
||
533 | |||
534 | 464 | jjdelcerro | private ScriptingUnit findScript(ScriptingFolder folder, String name) { |
535 | if (name == null) { |
||
536 | return null; |
||
537 | } |
||
538 | if (name.trim().length() == 0) { |
||
539 | return null; |
||
540 | } |
||
541 | 468 | jjdelcerro | ScriptingUnit unit; |
542 | 464 | jjdelcerro | if (folder == null) { |
543 | unit = findScript(this.getUserFolder(), name);
|
||
544 | if (unit != null) { |
||
545 | return unit;
|
||
546 | } |
||
547 | unit = findScript(this.getSystemFolder(), name);
|
||
548 | return unit;
|
||
549 | } |
||
550 | List<ScriptingUnit> units = folder.getUnits();
|
||
551 | Iterator<ScriptingUnit> it = units.iterator();
|
||
552 | while (it.hasNext()) {
|
||
553 | unit = it.next(); |
||
554 | if (unit instanceof ScriptingFolder) { |
||
555 | unit = findScript((ScriptingFolder) unit, name); |
||
556 | if (unit != null) { |
||
557 | return unit;
|
||
558 | } |
||
559 | } else if (unit instanceof ScriptingBaseScript) { |
||
560 | if (name.equalsIgnoreCase(unit.getId())) {
|
||
561 | return unit;
|
||
562 | } |
||
563 | } |
||
564 | } |
||
565 | return null; |
||
566 | } |
||
567 | |||
568 | 468 | jjdelcerro | @Override
|
569 | 464 | jjdelcerro | public File getRootUserFolder() { |
570 | return new File(this.getHomeFolder(), "scripts"); |
||
571 | } |
||
572 | |||
573 | 468 | jjdelcerro | @Override
|
574 | 464 | jjdelcerro | public void registerSystemFolder(String name, File folder) { |
575 | this.systemFolders.add(new RegisterSystemFolder(name, folder)); |
||
576 | LOG.info("Register system folder name '" + name + "' folder " + folder.getAbsolutePath() + "'"); |
||
577 | |||
578 | } |
||
579 | |||
580 | public List<RegisterSystemFolder> getSystemFolders() { |
||
581 | return this.systemFolders; |
||
582 | } |
||
583 | |||
584 | 468 | jjdelcerro | @Override
|
585 | 465 | jjdelcerro | public List<ScriptingFolder> getAlternativeUserFolders() { |
586 | return this.alternativeUserFolders; |
||
587 | } |
||
588 | |||
589 | 468 | jjdelcerro | @Override
|
590 | 465 | jjdelcerro | public void addAlternativeUserFolder(File f, String name, String description) { |
591 | UserFolder x = new UserFolder(this, f); |
||
592 | 468 | jjdelcerro | x.setName(name); |
593 | 465 | jjdelcerro | x.setDescription(description); |
594 | 468 | jjdelcerro | x.setId("UserFolder_" + this.alternativeUserFolders.size() + 1); |
595 | 465 | jjdelcerro | this.alternativeUserFolders.add(x);
|
596 | } |
||
597 | 478 | jjdelcerro | |
598 | private void initLanguages() { |
||
599 | 468 | jjdelcerro | if (this.extensionOfLanguage == null) { |
600 | 1020 | jjdelcerro | Map<String, String> theExtensionOfLanguage = new HashMap<>(); |
601 | 468 | jjdelcerro | List<ScriptEngineFactory> factories = getEngineManager().getEngineFactories();
|
602 | for (ScriptEngineFactory factory : factories) {
|
||
603 | 597 | jjdelcerro | if( "ognl".equals(factory.getLanguageName()) ) { |
604 | continue;
|
||
605 | } |
||
606 | 468 | jjdelcerro | List<String> extensions = factory.getExtensions(); |
607 | if (extensions != null && !extensions.isEmpty()) { |
||
608 | 1020 | jjdelcerro | theExtensionOfLanguage.put( |
609 | 468 | jjdelcerro | factory.getLanguageName().toLowerCase(), |
610 | extensions.get(0).toLowerCase()
|
||
611 | ); |
||
612 | } |
||
613 | } |
||
614 | 1020 | jjdelcerro | this.extensionOfLanguage = theExtensionOfLanguage;
|
615 | 464 | jjdelcerro | } |
616 | 478 | jjdelcerro | if (this.languageOfExtension == null) { |
617 | 1020 | jjdelcerro | Map<String, String> theLanguageOfExtension = new HashMap<>(); |
618 | 478 | jjdelcerro | List<ScriptEngineFactory> factories = getEngineManager().getEngineFactories();
|
619 | for (ScriptEngineFactory factory : factories) {
|
||
620 | 597 | jjdelcerro | if( "ognl".equals(factory.getLanguageName()) ) { |
621 | continue;
|
||
622 | } |
||
623 | 478 | jjdelcerro | List<String> extensions = factory.getExtensions(); |
624 | if (extensions != null) { |
||
625 | for (String extension1 : extensions) { |
||
626 | 1020 | jjdelcerro | theLanguageOfExtension.put( |
627 | 478 | jjdelcerro | extension1.toLowerCase(), |
628 | factory.getLanguageName().toLowerCase() |
||
629 | ); |
||
630 | } |
||
631 | } |
||
632 | } |
||
633 | 1020 | jjdelcerro | this.languageOfExtension = theLanguageOfExtension;
|
634 | 478 | jjdelcerro | } |
635 | } |
||
636 | |||
637 | @Override
|
||
638 | public String getExtensionOfLanguage(String langName) { |
||
639 | 468 | jjdelcerro | if (langName == null) { |
640 | return null; |
||
641 | } |
||
642 | langName = langName.toLowerCase(); |
||
643 | 478 | jjdelcerro | initLanguages(); |
644 | 468 | jjdelcerro | return this.extensionOfLanguage.get(langName); |
645 | 464 | jjdelcerro | } |
646 | |||
647 | 468 | jjdelcerro | @Override
|
648 | public List<String> getSupportedLanguages() { |
||
649 | List<String> languages = new ArrayList<>(); |
||
650 | 464 | jjdelcerro | |
651 | 478 | jjdelcerro | initLanguages(); |
652 | 468 | jjdelcerro | languages.addAll(this.extensionOfLanguage.keySet());
|
653 | Collections.sort(languages);
|
||
654 | return languages;
|
||
655 | } |
||
656 | 164 | jobacas | |
657 | 468 | jjdelcerro | public String getLanguageOfExtension(String extension) { |
658 | if (extension == null) { |
||
659 | return null; |
||
660 | 464 | jjdelcerro | } |
661 | 468 | jjdelcerro | extension = extension.toLowerCase(); |
662 | if (extension.startsWith(".")) { |
||
663 | extension = extension.substring(1);
|
||
664 | } |
||
665 | 478 | jjdelcerro | initLanguages(); |
666 | 468 | jjdelcerro | return this.languageOfExtension.get(extension); |
667 | 464 | jjdelcerro | } |
668 | 175 | jobacas | |
669 | 799 | jjdelcerro | @Override
|
670 | 464 | jjdelcerro | public Object get(String key) { |
671 | return this.bindings.get(key); |
||
672 | } |
||
673 | 441 | jjdelcerro | |
674 | 799 | jjdelcerro | @Override
|
675 | 464 | jjdelcerro | public void put(String key, Object value) { |
676 | this.bindings.put(key, value);
|
||
677 | 175 | jobacas | |
678 | 464 | jjdelcerro | } |
679 | 301 | jjdelcerro | |
680 | 468 | jjdelcerro | @Override
|
681 | 464 | jjdelcerro | public ScriptingUnit createUnit(String unitType, ScriptingFolder folder, String id) { |
682 | return createUnit(unitType, folder, id, null); |
||
683 | } |
||
684 | |||
685 | 468 | jjdelcerro | @Override
|
686 | 464 | jjdelcerro | public ScriptingUnit createUnit(String unitType, ScriptingFolder folder, String id, String language) { |
687 | if (unitType.equals(UNIT_SCRIPT)) {
|
||
688 | return this.createScript(folder, id, language); |
||
689 | } |
||
690 | if (unitType.equals(UNIT_DIALOG)) {
|
||
691 | return this.createDialog(folder, id, language); |
||
692 | } |
||
693 | if (unitType.equals(UNIT_FOLDER)) {
|
||
694 | return this.createFolder(folder, id); |
||
695 | } |
||
696 | 702 | jjdelcerro | if (unitType.equals(UNIT_EXTERNALFILE)) {
|
697 | return this.createExternalFile(folder, id); |
||
698 | } |
||
699 | 464 | jjdelcerro | return null; |
700 | } |
||
701 | |||
702 | 468 | jjdelcerro | @Override
|
703 | 464 | jjdelcerro | public List<String> getUnitTypes() { |
704 | if (this.unitTypes == null) { |
||
705 | 468 | jjdelcerro | this.unitTypes = new ArrayList<>(); |
706 | 464 | jjdelcerro | this.unitTypes.add(UNIT_SCRIPT);
|
707 | this.unitTypes.add(UNIT_DIALOG);
|
||
708 | this.unitTypes.add(UNIT_FOLDER);
|
||
709 | 702 | jjdelcerro | this.unitTypes.add(UNIT_EXTERNALFILE);
|
710 | 464 | jjdelcerro | } |
711 | return this.unitTypes; |
||
712 | } |
||
713 | |||
714 | 468 | jjdelcerro | @Override
|
715 | 464 | jjdelcerro | public void addLibFolder(File lib) { |
716 | if (lib.exists()) {
|
||
717 | LOG.info("Add scripting lib folder '" + lib.getAbsolutePath() + "'"); |
||
718 | this.libFolders.add(lib);
|
||
719 | } else {
|
||
720 | LOG.info("Skip add scripting lib folder '" + lib.getAbsolutePath() + "', folder don't exist"); |
||
721 | } |
||
722 | } |
||
723 | |||
724 | 669 | jjdelcerro | @Override
|
725 | 464 | jjdelcerro | public List<File> getLibFolders() { |
726 | 669 | jjdelcerro | return new ArrayList(this.libFolders); |
727 | 464 | jjdelcerro | } |
728 | 468 | jjdelcerro | |
729 | 669 | jjdelcerro | @Override
|
730 | public Map<String, String> getLibFoldersVersions() { |
||
731 | Map<String, String>versions = new HashMap<>(); |
||
732 | List<File> folders = this.getLibFolders(); |
||
733 | for (File folder : folders) { |
||
734 | File parent = folder.getParentFile();
|
||
735 | File libVersions = new File(parent,folder.getName()+".versions"); |
||
736 | if( libVersions.exists() ) {
|
||
737 | this.loadLibVersions(versions, libVersions);
|
||
738 | } |
||
739 | } |
||
740 | if( versions.isEmpty() ) {
|
||
741 | return null; |
||
742 | } |
||
743 | return versions;
|
||
744 | } |
||
745 | |||
746 | private void loadLibVersions(Map<String,String>versions, File file) { |
||
747 | List<String> lines; |
||
748 | try {
|
||
749 | lines = FileUtils.readLines(file); |
||
750 | } catch (IOException ex) { |
||
751 | LOG.warn("Can't load lib versions from '"+file+".",ex); |
||
752 | return;
|
||
753 | } |
||
754 | for (String line : lines) { |
||
755 | String[] x = line.split("="); |
||
756 | if( x.length==2 ) { |
||
757 | versions.put(x[0], x[1]); |
||
758 | } |
||
759 | } |
||
760 | } |
||
761 | |||
762 | @Override
|
||
763 | 468 | jjdelcerro | public ProviderFactory getInstallerFactory() {
|
764 | return new ScriptingInstallerProviderFactory(); |
||
765 | } |
||
766 | |||
767 | 799 | jjdelcerro | @Override
|
768 | 468 | jjdelcerro | public File getPackagesFolder() { |
769 | return this.packagesFolder; |
||
770 | } |
||
771 | |||
772 | @Override
|
||
773 | public void setPackagesFolder(File folder) { |
||
774 | this.packagesFolder = folder;
|
||
775 | } |
||
776 | |||
777 | 989 | jjdelcerro | @Override
|
778 | public ScriptingFolder createLink(String name, File link, String targetPathName) { |
||
779 | StringBuilder contents = new StringBuilder(); |
||
780 | contents.append("[Unit]\n")
|
||
781 | .append("type = Folder\n")
|
||
782 | .append("name = ").append(name).append("\n") |
||
783 | .append("description =\n")
|
||
784 | .append("createdBy =\n")
|
||
785 | .append("version =\n")
|
||
786 | .append("\n")
|
||
787 | .append("[Folder]\n")
|
||
788 | .append("path =").append(targetPathName).append("\n") |
||
789 | .append("\n\n");
|
||
790 | |||
791 | if( link.isDirectory() ) {
|
||
792 | link = new File(link,name+".inf"); |
||
793 | } else if( !link.getName().endsWith(".inf") ) { |
||
794 | link = new File( link.getPath() + ".inf"); |
||
795 | } |
||
796 | if( !link.exists() ) {
|
||
797 | try {
|
||
798 | FileUtils.writeStringToFile(link, contents.toString()); |
||
799 | } catch (IOException ex) { |
||
800 | LOG.warn("Can't create ScriptingFolder file in '" + link.getAbsolutePath() + "'.", ex); |
||
801 | } |
||
802 | } |
||
803 | ScriptingFolder folder = this.getFolder(link);
|
||
804 | return folder;
|
||
805 | } |
||
806 | |||
807 | @Override
|
||
808 | public ScriptingFolder createLink(String name, ScriptingFolder link, String targetPathName) { |
||
809 | return this.createLink(name, link.getFile(), targetPathName); |
||
810 | } |
||
811 | |||
812 | 1020 | jjdelcerro | private final Map<File,File> links = new HashMap<>(); |
813 | 989 | jjdelcerro | |
814 | public void addLink(File source, File target) { |
||
815 | this.links.put(FileUtils.getRealFile(target), source);
|
||
816 | } |
||
817 | |||
818 | public File getLinkSource(File target) { |
||
819 | File source = this.links.get(FileUtils.getRealFile(target)); |
||
820 | if( source == null ) { |
||
821 | return target;
|
||
822 | } |
||
823 | if( source.exists() ) {
|
||
824 | return source;
|
||
825 | } |
||
826 | return target;
|
||
827 | } |
||
828 | |||
829 | public boolean isInUserFolder(File f) { |
||
830 | if( FileUtils.isSubfolder(this.getRootUserFolder(), f) ) { |
||
831 | return true; |
||
832 | } |
||
833 | for( File file : this.links.keySet()) { |
||
834 | if( FileUtils.isSubfolder(file, f) ) {
|
||
835 | return true; |
||
836 | } |
||
837 | } |
||
838 | return false; |
||
839 | } |
||
840 | 164 | jobacas | } |