001/*
002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Stephane Lacoin <slacoin@nuxeo.com>
018 *     Vladimir Pasquier <vpasquier@nuxeo.com>
019 */
020package org.nuxeo.automation.scripting.internals;
021
022import javax.script.ScriptEngineFactory;
023import javax.script.ScriptEngineManager;
024
025import org.apache.commons.logging.Log;
026import org.apache.commons.logging.LogFactory;
027import org.nuxeo.automation.scripting.api.AutomationScriptingConstants;
028import org.nuxeo.runtime.api.Framework;
029
030/**
031 * This factory configures the Nashorn engine and register it following the JVM version.
032 *
033 * @since 7.3
034 */
035public class ScriptingFactory {
036
037    private static final Log log = LogFactory.getLog(ScriptingFactory.class);
038
039    protected ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
040
041    protected void install() {
042        scriptEngineManager.registerEngineName(AutomationScriptingConstants.NX_NASHORN, newFactory());
043    }
044
045    protected ScriptEngineFactory newFactory() {
046        String version = Framework.getProperty("java.version", "1.8");
047        // Check if jdk8
048        if (version.contains(AutomationScriptingConstants.NASHORN_JAVA_VERSION)) {
049            // Check if version < jdk8u25 -> no cache.
050            if (version.compareTo(AutomationScriptingConstants.COMPLIANT_JAVA_VERSION_CACHE) < 0) {
051                log.warn(AutomationScriptingConstants.NASHORN_WARN_CACHE);
052                return new ScriptingCache(false);
053                // Check if jdk8u25 <= version < jdk8u40 -> only cache.
054            } else if (version.compareTo(AutomationScriptingConstants.COMPLIANT_JAVA_VERSION_CACHE) >= 0
055                    && version.compareTo(AutomationScriptingConstants.COMPLIANT_JAVA_VERSION_CLASS_FILTER) < 0) {
056                if (Boolean.valueOf(Framework.getProperty(AutomationScriptingConstants.AUTOMATION_SCRIPTING_PRECOMPILE,
057                        AutomationScriptingConstants.DEFAULT_PRECOMPILE_STATUS))) {
058                    log.warn(AutomationScriptingConstants.NASHORN_WARN_CLASS_FILTER);
059                    return new ScriptingCache(true);
060                } else {
061                    log.warn(AutomationScriptingConstants.NASHORN_WARN_CLASS_FILTER);
062                    return new ScriptingCache(false);
063                }
064                // Check if version >= jdk8u40 -> cache + class filter
065            } else if (version.compareTo(AutomationScriptingConstants.COMPLIANT_JAVA_VERSION_CLASS_FILTER) >= 0) {
066                try {
067                    if (Boolean.valueOf(Framework.getProperty(
068                            AutomationScriptingConstants.AUTOMATION_SCRIPTING_PRECOMPILE,
069                            AutomationScriptingConstants.DEFAULT_PRECOMPILE_STATUS))) {
070                        return new ScriptingCacheClassFilter(true);
071                    } else {
072                        return new ScriptingCacheClassFilter(false);
073                    }
074                } catch (NoClassDefFoundError cause) {
075                    log.warn(AutomationScriptingConstants.NASHORN_WARN_CLASS_FILTER);
076                    return new ScriptingCache(true);
077                }
078            }
079        }
080        log.warn(AutomationScriptingConstants.NASHORN_WARN_VERSION);
081        throw new UnsupportedOperationException();
082    }
083}