Coverage Report - org.webslinger.bsf.AbstractManager
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractManager
43%
40/93
57%
8/14
0
AbstractManager$1
100%
3/3
N/A
0
AbstractManager$2
0%
0/2
N/A
0
AbstractManager$3
100%
2/2
N/A
0
 
 1  
 package org.webslinger.bsf;
 2  
 
 3  
 import java.util.HashMap;
 4  
 import java.util.Iterator;
 5  
 import java.util.StringTokenizer;
 6  
 import java.util.logging.Logger;
 7  
 import java.util.concurrent.ConcurrentHashMap;
 8  
 import java.security.AccessController;
 9  
 import java.security.PrivilegedActionException;
 10  
 import java.security.PrivilegedExceptionAction;
 11  
 
 12  
 import org.apache.bsf.BSFEngine;
 13  
 import org.apache.bsf.BSFException;
 14  
 import org.apache.bsf.BSFManager;
 15  
 
 16  
 import org.webslinger.vfs.VFSDelegate;
 17  
 
 18  67
 public abstract class AbstractManager extends BSFManager {
 19  51
     protected final ConcurrentHashMap<String, String> registeredLanguages = new ConcurrentHashMap<String, String>();
 20  51
     protected final ConcurrentHashMap<String, String> languagesByExtension = new ConcurrentHashMap<String, String>();
 21  
     protected final VFSDelegate<?, Object, ?> vfsDelegate;
 22  
     protected final Logger logger;
 23  51
     protected final ConcurrentHashMap<String, LanguageEngine> loadedLanguages = new ConcurrentHashMap<String, LanguageEngine>();
 24  
 
 25  
     protected AbstractManager(VFSDelegate<?, Object, ?> vfsDelegate, Logger logger) throws BSFException {
 26  51
         super();
 27  51
         this.vfsDelegate = vfsDelegate;
 28  51
         this.logger = logger != null ? logger : Logger.getLogger(getClass().getName());
 29  51
         registerBean("vfsDelegate", vfsDelegate);
 30  51
     }
 31  
 
 32  
     protected void postConstruct() throws BSFException {
 33  51
         findLanguageEngines(getClass().getClassLoader());
 34  51
         findLanguageEngines(Thread.currentThread().getContextClassLoader());
 35  51
     }
 36  
 
 37  
     public Logger getLogger() {
 38  0
         return logger;
 39  
     }
 40  
 
 41  
     public abstract void findLanguageEngines(ClassLoader loader) throws BSFException;
 42  
 
 43  
     public final void registerLanguageEngine(String languageName, String className, String[] extensions) {
 44  926
         registeredLanguages.put(languageName, className);
 45  926
         if (extensions != null) {
 46  1692
             for (int i = 0; i < extensions.length; i++) {
 47  766
                 String extensionLanguages = languagesByExtension.get(extensions[i]);
 48  766
                 extensionLanguages = extensionLanguages == null ? languageName : extensionLanguages + ',' + extensionLanguages;
 49  766
                 languagesByExtension.put(extensions[i], extensionLanguages);
 50  
             }
 51  
         }
 52  926
     }
 53  
 
 54  
     public String getLanguageFromFilename(String fileName) throws BSFException {
 55  0
         int dot = fileName.lastIndexOf(".");
 56  0
         String language = dot != -1 ? getLanguageFromExtensionInternal(fileName.substring(dot + 1)) : null;
 57  0
         if (language != null) return language;
 58  0
         throw new BSFException(BSFException.REASON_OTHER_ERROR,
 59  
                            "file extension missing: "
 60  
                            + "unable to determine language for '"
 61  
                            + fileName
 62  
                            + "'");
 63  
     }
 64  
 
 65  
     public String getLanguageFromExtension(String extension) throws BSFException {
 66  0
         String language = getLanguageFromExtensionInternal(extension);
 67  0
         if (language != null) return language;
 68  0
         throw new BSFException(BSFException.REASON_OTHER_ERROR,
 69  
                                "file extension unknown: "
 70  
                                + "unable to determine language for '"
 71  
                                + extension
 72  
                                + "'");
 73  
     }
 74  
 
 75  
     protected String getLanguageFromExtensionInternal(String extension) throws BSFException {
 76  0
         String langval = languagesByExtension.get(extension), lang = null;
 77  0
         if (langval == null) return null;
 78  0
         StringTokenizer st = new StringTokenizer(langval, ",");
 79  0
         while (st.hasMoreTokens()) {
 80  0
             String language = st.nextToken();
 81  
             try {
 82  0
                 Class.forName(registeredLanguages.get(language));
 83  0
                 return lang;
 84  0
             } catch (ClassNotFoundException cnfe) {
 85  
             }
 86  0
         }
 87  0
         return null;
 88  
     }
 89  
 
 90  
     protected void initializeLanguageEngine(final LanguageEngine engine, final String language) throws BSFException {
 91  
         try {
 92  
             try {
 93  67
                 AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
 94  
                     public Object run() throws Exception {
 95  67
                         engine.initialize(AbstractManager.this, language, declaredBeans);
 96  67
                         return null;
 97  
                     }
 98  
                 });
 99  0
             } catch (PrivilegedActionException e) {
 100  0
                 throw e.getException();
 101  67
             }
 102  0
         } catch (BSFException e) {
 103  0
             throw e;
 104  0
         } catch (RuntimeException e) {
 105  0
             throw e;
 106  0
         } catch (Error e) {
 107  0
             throw e;
 108  0
         } catch (Throwable t) {
 109  0
             throw (BSFException) new BSFException(BSFException.REASON_OTHER_ERROR, "unable to initialize engine for language: " + language).initCause(t);
 110  67
         }
 111  67
     }
 112  
 
 113  
     protected abstract LanguageEngine getLanguageEngineConvertor(String language, BSFEngine engine) throws BSFException;
 114  
 
 115  
     public LanguageEngine loadLanguageEngine(String language) throws BSFException {
 116  
         try {
 117  
             do {
 118  1467
                 LanguageEngine engine = loadedLanguages.get(language);
 119  1469
                 if (engine != null) return engine;
 120  67
                 String className = registeredLanguages.get(language);
 121  67
                 if (className == null) {
 122  0
                     BSFEngine bsfEngine = super.loadScriptingEngine(language);
 123  0
                     if (bsfEngine instanceof LanguageEngine) {
 124  0
                         engine = (LanguageEngine) bsfEngine;
 125  
                     } else {
 126  0
                         engine = getLanguageEngineConvertor(language, bsfEngine);
 127  0
                         initializeLanguageEngine(engine, language);
 128  0
                         pcs.addPropertyChangeListener(engine);
 129  
                     }
 130  0
                 } else {
 131  67
                     ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
 132  67
                     if (classLoader == null) classLoader = getClass().getClassLoader();
 133  67
                     synchronized (this) {
 134  67
                         engine = (LanguageEngine) Class.forName(className, true, classLoader).newInstance();
 135  67
                         initializeLanguageEngine(engine, language);
 136  67
                         pcs.addPropertyChangeListener(engine);
 137  67
                     }
 138  
                 }
 139  67
                 LanguageEngine oldEngine = loadedLanguages.putIfAbsent(language, engine);
 140  67
                 if (oldEngine == null) return engine;
 141  0
                 pcs.removePropertyChangeListener(engine);
 142  0
                 return oldEngine;
 143  
             } while (true);
 144  0
         } catch (BSFException e) {
 145  0
             throw e;
 146  0
         } catch (ClassNotFoundException e) {
 147  0
             throw (BSFException) new BSFException(BSFException.REASON_OTHER_ERROR, "unable to load language: " + language).initCause(e);
 148  0
         } catch (IllegalAccessException e) {
 149  0
             throw (BSFException) new BSFException(BSFException.REASON_OTHER_ERROR, "unable to load language: " + language).initCause(e);
 150  0
         } catch (InstantiationException e) {
 151  0
             throw (BSFException) new BSFException(BSFException.REASON_OTHER_ERROR, "unable to load language: " + language).initCause(e);
 152  
         }
 153  
     }
 154  
 
 155  
     public BSFEngine loadScriptingEngine(String language) throws BSFException {
 156  1469
         return loadLanguageEngine(language);
 157  
     }
 158  
 
 159  
     public void setDebug(String language, boolean debugging) throws BSFException {
 160  0
         ((LanguageEngine) loadScriptingEngine(language)).setDebug(debugging);
 161  0
     }
 162  
 
 163  
     public VFSDelegate<?, Object, ?> getVFSDelegate() {
 164  3050
         return vfsDelegate;
 165  
     }
 166  
 
 167  
     public Object apply(String lang, final String source, final int lineNo, final int columnNo, final Object funcBody, final String[] paramNames, final Object[] arguments) throws BSFException {
 168  0
         final LanguageEngine engine = (LanguageEngine) loadScriptingEngine(lang);
 169  
         try {
 170  0
             return AccessController.doPrivileged(
 171  0
                 new PrivilegedExceptionAction<Object>() {
 172  
                     public Object run() throws Exception {
 173  0
                         return engine.apply(source, lineNo, columnNo, funcBody, paramNames, arguments);
 174  
                     }
 175  
                 }
 176  
             );
 177  0
         } catch (PrivilegedActionException e) {
 178  0
             throw (BSFException) e.getException();
 179  
         }
 180  
     }
 181  
 
 182  
     public Object apply(String lang, final String source, final int lineNo, final int columnNo, final Object funcBody, final String[] paramNames, final Object[] arguments, final Class[] types) throws BSFException {
 183  1467
         final LanguageEngine engine = (LanguageEngine) loadScriptingEngine(lang);
 184  
         try {
 185  1467
             return AccessController.doPrivileged(
 186  1466
                 new PrivilegedExceptionAction<Object>() {
 187  
                     public Object run() throws Exception {
 188  1472
                         return engine.apply(source, lineNo, columnNo, funcBody, paramNames, arguments, types);
 189  
                     }
 190  
                 }
 191  
             );
 192  0
         } catch (PrivilegedActionException e) {
 193  0
             throw (BSFException) e.getException();
 194  
         }
 195  
     }
 196  
 }