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 static org.nuxeo.automation.scripting.api.AutomationScriptingConstants.AUTOMATION_SCRIPTING_PRECOMPILE;
023import static org.nuxeo.automation.scripting.api.AutomationScriptingConstants.COMPLIANT_JAVA_VERSION_CACHE;
024import static org.nuxeo.automation.scripting.api.AutomationScriptingConstants.COMPLIANT_JAVA_VERSION_CLASS_FILTER;
025import static org.nuxeo.automation.scripting.api.AutomationScriptingConstants.DEFAULT_PRECOMPILE_STATUS;
026import static org.nuxeo.automation.scripting.api.AutomationScriptingConstants.NASHORN_JAVA_VERSION;
027import static org.nuxeo.automation.scripting.api.AutomationScriptingConstants.NASHORN_WARN_CACHE;
028import static org.nuxeo.automation.scripting.api.AutomationScriptingConstants.NASHORN_WARN_CLASS_FILTER;
029import static org.nuxeo.automation.scripting.api.AutomationScriptingConstants.NASHORN_WARN_VERSION;
030import static org.nuxeo.launcher.config.ConfigurationGenerator.checkJavaVersion;
031
032import javax.script.ScriptEngineFactory;
033import javax.script.ScriptEngineManager;
034
035import org.apache.commons.logging.Log;
036import org.apache.commons.logging.LogFactory;
037import org.nuxeo.automation.scripting.api.AutomationScriptingConstants;
038import org.nuxeo.runtime.api.Framework;
039
040/**
041 * This factory configures the Nashorn engine and register it following the JVM version.
042 *
043 * @since 7.3
044 */
045public class ScriptingFactory {
046
047    private static final Log log = LogFactory.getLog(ScriptingFactory.class);
048
049    protected ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
050
051    protected void install() {
052        scriptEngineManager.registerEngineName(AutomationScriptingConstants.NX_NASHORN, newFactory());
053    }
054
055    protected ScriptEngineFactory newFactory() {
056        String version = Framework.getProperty("java.version");
057        // Check if jdk8
058        if (!checkJavaVersion(version, NASHORN_JAVA_VERSION)) {
059            log.warn(NASHORN_WARN_VERSION);
060            throw new UnsupportedOperationException();
061        }
062        // Check if version < jdk8u25 -> no cache.
063        if (!checkJavaVersion(version, COMPLIANT_JAVA_VERSION_CACHE)) {
064            log.warn(NASHORN_WARN_CACHE);
065            return new ScriptingCache(false);
066        }
067        // Check if jdk8u25 <= version < jdk8u40 -> only cache.
068        if (!checkJavaVersion(version, COMPLIANT_JAVA_VERSION_CLASS_FILTER)) {
069            if (Boolean.parseBoolean(
070                    Framework.getProperty(AUTOMATION_SCRIPTING_PRECOMPILE, DEFAULT_PRECOMPILE_STATUS))) {
071                log.warn(NASHORN_WARN_CLASS_FILTER);
072                return new ScriptingCache(true);
073            } else {
074                log.warn(NASHORN_WARN_CLASS_FILTER);
075                return new ScriptingCache(false);
076            }
077        }
078        // Else if version >= jdk8u40 -> cache + class filter
079        try {
080            if (Boolean.parseBoolean(
081                    Framework.getProperty(AUTOMATION_SCRIPTING_PRECOMPILE, DEFAULT_PRECOMPILE_STATUS))) {
082                return new ScriptingCacheClassFilter(true);
083            } else {
084                return new ScriptingCacheClassFilter(false);
085            }
086        } catch (NoClassDefFoundError cause) {
087            log.warn(NASHORN_WARN_CLASS_FILTER);
088            return new ScriptingCache(true);
089        }
090    }
091
092}