/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.scripting.internal; import com.liferay.portal.kernel.io.unsync.UnsyncStringReader; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.scripting.Scripting; import com.liferay.portal.kernel.scripting.ScriptingException; import com.liferay.portal.kernel.scripting.ScriptingExecutor; import com.liferay.portal.kernel.scripting.UnsupportedLanguageException; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import java.io.IOException; import java.io.LineNumberReader; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang.time.StopWatch; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import org.osgi.service.component.annotations.ReferenceCardinality; import org.osgi.service.component.annotations.ReferencePolicy; import org.osgi.service.component.annotations.ReferencePolicyOption; /** * @author Alberto Montero * @author Brian Wing Shun Chan * @author Shuyang Zhou */ @Component(immediate = true, service = Scripting.class) public class ScriptingImpl implements Scripting { @Override public void clearCache(String language) throws ScriptingException { ScriptingExecutor scriptingExecutor = _scriptingExecutors.get(language); if (scriptingExecutor == null) { throw new UnsupportedLanguageException(language); } scriptingExecutor.clearCache(); } @Override public ScriptingExecutor createScriptingExecutor( String language, boolean executeInSeparateThread) { ScriptingExecutor scriptingExecutor = _scriptingExecutors.get(language); return scriptingExecutor.newInstance(executeInSeparateThread); } @Override public Map<String, Object> eval( Set<String> allowedClasses, Map<String, Object> inputObjects, Set<String> outputNames, String language, String script) throws ScriptingException { ScriptingExecutor scriptingExecutor = _scriptingExecutors.get(language); if (scriptingExecutor == null) { throw new UnsupportedLanguageException(language); } StopWatch stopWatch = new StopWatch(); stopWatch.start(); try { return scriptingExecutor.eval( allowedClasses, inputObjects, outputNames, script); } catch (Exception e) { throw new ScriptingException(getErrorMessage(script, e), e); } finally { if (_log.isDebugEnabled()) { _log.debug( "Evaluated script in " + stopWatch.getTime() + " ms"); } } } /** * @deprecated As of 1.0.0, replaced by {@link #eval(Set, Map, Set, String, * String)} */ @Deprecated public Map<String, Object> eval( Set<String> allowedClasses, Map<String, Object> inputObjects, Set<String> outputNames, String language, String script, String... servletContextNames) throws ScriptingException { return eval( allowedClasses, inputObjects, outputNames, language, script); } @Override public void exec( Set<String> allowedClasses, Map<String, Object> inputObjects, String language, String script) throws ScriptingException { eval(allowedClasses, inputObjects, null, language, script); } /** * @deprecated As of 1.0.0, replaced by {@link #exec(Set, Map, String, * String)} */ @Deprecated @Override public void exec( Set<String> allowedClasses, Map<String, Object> inputObjects, String language, String script, String... servletContextNames) throws ScriptingException { eval(allowedClasses, inputObjects, null, language, script); } @Override public Set<String> getSupportedLanguages() { return _scriptingExecutors.keySet(); } protected String getErrorMessage(String script, Exception e) { StringBundler sb = new StringBundler(); sb.append(e.getMessage()); sb.append(StringPool.NEW_LINE); try { LineNumberReader lineNumberReader = new LineNumberReader( new UnsyncStringReader(script)); while (true) { String line = lineNumberReader.readLine(); if (line == null) { break; } sb.append("Line "); sb.append(lineNumberReader.getLineNumber()); sb.append(": "); sb.append(line); sb.append(StringPool.NEW_LINE); } } catch (IOException ioe) { sb.setIndex(0); sb.append(e.getMessage()); sb.append(StringPool.NEW_LINE); sb.append(script); } return sb.toString(); } @Reference( cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY ) protected void setScriptingExecutors(ScriptingExecutor scriptingExecutor) { _scriptingExecutors.put( scriptingExecutor.getLanguage(), scriptingExecutor); } protected void unsetScriptingExecutors( ScriptingExecutor scriptingExecutor) { _scriptingExecutors.remove(scriptingExecutor.getLanguage()); } private static final Log _log = LogFactoryUtil.getLog(ScriptingImpl.class); private final Map<String, ScriptingExecutor> _scriptingExecutors = new ConcurrentHashMap<>(); }