001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package javax.script;
018    
019    import java.io.*;
020    import java.lang.annotation.AnnotationFormatError;
021    import java.net.URL;
022    import java.util.*;
023    
024    public class ScriptEngineManager {
025            
026        private final Set engineSpis = new HashSet();
027        private final Map<String, ScriptEngineFactory> byName = new HashMap<String, ScriptEngineFactory>();
028        private final Map<String, ScriptEngineFactory> registeredByName = new HashMap();
029        private final Map<String, ScriptEngineFactory> byExtension = new HashMap<String, ScriptEngineFactory>();
030        private final Map<String, ScriptEngineFactory> registeredByExtension = new HashMap<String, ScriptEngineFactory>();
031        private final Map<String, ScriptEngineFactory> byMimeType = new HashMap<String, ScriptEngineFactory>();
032        private final Map<String, ScriptEngineFactory> registeredByMimeType = new HashMap<String, ScriptEngineFactory>();
033        private Bindings globalScope;
034    
035            public ScriptEngineManager() {
036                    this(Thread.currentThread().getContextClassLoader());
037            }
038            
039            public ScriptEngineManager(ClassLoader classLoader) {
040            try
041            {
042                for (Enumeration factoryResources = classLoader.getResources("META-INF/services/javax.script.ScriptEngineFactory"); 
043                                     factoryResources.hasMoreElements();) {
044                    URL url = (URL) factoryResources.nextElement();
045                                    for (String className : getClassNames(url)) {
046                        try {
047                            Class factoryClass = classLoader.loadClass(className);
048                            Object object = factoryClass.newInstance();
049                            if (object instanceof ScriptEngineFactory) {
050                                ScriptEngineFactory factory = (ScriptEngineFactory) object;
051                                for (String name : factory.getNames()) {
052                                                                    byName.put(name, factory);
053                                                            }
054                                                            for (String extension : factory.getExtensions()) {
055                                                                    byExtension.put(extension, factory);
056                                                            }
057                                                            for (String mimeType : factory.getMimeTypes()) {
058                                                                    byMimeType.put(mimeType, factory);
059                                                            }
060                                engineSpis.add(factory);
061                            }
062                        } catch(ClassNotFoundException doNothing) { 
063                                            } catch(IllegalAccessException doNothing) { 
064                                            } catch(InstantiationException doNothing) { 
065                                            } catch(LinkageError doNothing) { 
066                                            } catch(AnnotationFormatError doNothing) { 
067                                            }
068                    }
069                }
070            } catch(IOException doNothing) { 
071                    }
072            }
073    
074        public Bindings getGlobalScope() {
075            return globalScope;
076        }
077    
078        public void setGlobalScope(Bindings globalScope) {
079            this.globalScope = globalScope;
080        }
081    
082        public void put(String key, Object value) {
083            if (globalScope != null) {
084                globalScope.put(key, value);
085                    }
086        }
087    
088        public Object get(String key) {
089            if (globalScope != null) {
090                return globalScope.get(key);
091            } else {
092                return null;
093                    }
094        }
095    
096        public ScriptEngine getEngineByName(String shortName) {
097                    ScriptEngineFactory factory = null;
098            List<Class> factoryClasses = org.apache.servicemix.specs.locator.OsgiLocator.locateAll("javax.script.ScriptEngineFactory");
099            for (Class factoryClass : factoryClasses) {
100                            try {
101                                    ScriptEngineFactory f = (ScriptEngineFactory) factoryClass.newInstance();
102                                    if (f.getNames().contains(shortName)) {
103                                            factory = f;
104                                            break;
105                                    }
106                            } catch (Throwable doNothing) {
107                            }
108                    }
109            if (factory == null) {
110                            factory = registeredByName.get(shortName);
111                    }
112            if (factory == null) {
113                factory = byName.get(shortName);
114                    }
115            if (factory == null) {
116                return null;
117            } else {
118                ScriptEngine engine = factory.getScriptEngine();
119                engine.setBindings(globalScope, ScriptContext.GLOBAL_SCOPE);
120                return engine;
121            }
122        }
123    
124        public ScriptEngine getEngineByExtension(String extension) {
125                    ScriptEngineFactory factory = null;
126            List<Class> factoryClasses = org.apache.servicemix.specs.locator.OsgiLocator.locateAll("javax.script.ScriptEngineFactory");
127            for (Class factoryClass : factoryClasses) {
128                            try {
129                                    ScriptEngineFactory f = (ScriptEngineFactory) factoryClass.newInstance();
130                                    if (f.getExtensions().contains(extension)) {
131                                            factory = f;
132                                            break;
133                                    }
134                            } catch (Throwable doNothing) {
135                            }
136                    }
137            if (factory == null) {
138                            factory = registeredByExtension.get(extension);
139                    }
140            if (factory == null) {
141                factory = byExtension.get(extension);
142                    }
143            if (factory == null) {
144                return null;
145            } else {
146                ScriptEngine engine = factory.getScriptEngine();
147                engine.setBindings(globalScope, ScriptContext.GLOBAL_SCOPE);
148                return engine;
149            }
150        }
151    
152        public ScriptEngine getEngineByMimeType(String mimeType) {
153                    ScriptEngineFactory factory = null;
154            List<Class> factoryClasses = org.apache.servicemix.specs.locator.OsgiLocator.locateAll("javax.script.ScriptEngineFactory");
155            for (Class factoryClass : factoryClasses) {
156                            try {
157                                    ScriptEngineFactory f = (ScriptEngineFactory) factoryClass.newInstance();
158                                    if (f.getMimeTypes().contains(mimeType)) {
159                                            factory = f;
160                                            break;
161                                    }
162                            } catch (Throwable doNothing) {
163                            }
164                    }
165            if (factory == null) {
166                            factory = registeredByMimeType.get(mimeType);
167                    }
168            if(factory == null) {
169                factory = byMimeType.get(mimeType);
170                    }
171            if (factory == null) {
172                return null;
173            } else {
174                ScriptEngine engine = factory.getScriptEngine();
175                engine.setBindings(globalScope, ScriptContext.GLOBAL_SCOPE);
176                return engine;
177            }
178        }
179    
180        public List<ScriptEngineFactory> getEngineFactories() {
181            List<ScriptEngineFactory> factories = new ArrayList();
182            List<Class> factoryClasses = org.apache.servicemix.specs.locator.OsgiLocator.locateAll("javax.script.ScriptEngineFactory");
183            for (Class factoryClass : factoryClasses) {
184                            try {
185                                    factories.add((ScriptEngineFactory) factoryClass.newInstance());
186                            } catch (Throwable doNothing) {
187                            }
188                    }
189                    factories.addAll(engineSpis);
190                    return factories;
191        }
192    
193        public void registerEngineName(String name, ScriptEngineFactory factory) {
194            registeredByName.put(name, factory);
195        }
196    
197        public void registerEngineMimeType(String type, ScriptEngineFactory factory) {
198            registeredByMimeType.put(type, factory);
199        }
200    
201        public void registerEngineExtension(String extension, ScriptEngineFactory factory) {
202            registeredByExtension.put(extension, factory);
203        }
204    
205        private Iterable<String> getClassNames(URL url) {
206            Stack<String> stack = new Stack<String>();
207            try {
208                BufferedReader r = new BufferedReader(new InputStreamReader(url.openStream()));
209                String line;
210                while ((line = r.readLine()) != null) {
211                    int comment = line.indexOf('#');
212                    if (comment != -1) {
213                        line = line.substring(0, comment);
214                                    }
215                    stack.push(line.trim());
216                }
217            } catch(IOException doNothing) { 
218                    }
219            return stack;
220        }
221    
222    }