/*********************************************************************************** * * Copyright (c) 2015 Kamil Baczkowicz * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v1.0 which accompany this distribution. * * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * * The Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * * Kamil Baczkowicz - initial API and implementation and/or initial documentation * */ package pl.baczkowicz.spy.formatting; import java.util.HashMap; import java.util.Map; import javax.script.ScriptException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import pl.baczkowicz.spy.common.generated.FormatterDetails; import pl.baczkowicz.spy.messages.FormattedMessage; import pl.baczkowicz.spy.scripts.BaseScriptManager; import pl.baczkowicz.spy.scripts.Script; import pl.baczkowicz.spy.utils.ConversionUtils; import pl.baczkowicz.spy.utils.TimeUtils; public class ScriptBasedFormatter { public static final String FORMAT_FUNCTION_NAME = "format"; public static final String PRETTY_FUNCTION_NAME = "pretty"; final static Logger logger = LoggerFactory.getLogger(ScriptBasedFormatter.class); private BaseScriptManager scriptManager; private Map<FormatterDetails, Script> formattingScripts = new HashMap<>(); private Map<FormatterDetails, Boolean> prettyFormattingAvailable = new HashMap<>(); public ScriptBasedFormatter(final BaseScriptManager scriptManager) { this.scriptManager = scriptManager; } public Script getScript(final FormatterDetails formatter) throws ScriptException { Script script = formattingScripts.get(formatter); if (script == null) { addFormatter(formatter); script = formattingScripts.get(formatter); } return script; } public void evaluate(final Script script) { // Evaluate it scriptManager.runScript(script, false); // Run before / setup try { scriptManager.invokeFunction(script, BaseScriptManager.BEFORE_METHOD); } catch (NoSuchMethodException | ScriptException e) { logger.info("No setup method present"); } } public void addFormatter(final FormatterDetails formatter) throws ScriptException { final long start = TimeUtils.getMonotonicTime(); if (FormattingUtils.isScriptBased(formatter)) { final Script script = scriptManager.addInlineScript(formatter.getID(), ConversionUtils.base64ToString(formatter.getFunction().get(0).getScriptExecution().getInlineScript())); // Store it for future formattingScripts.put(formatter, script); evaluate(script); } final long end = TimeUtils.getMonotonicTime(); logger.debug("Adding formatter {} took {} ms", formatter.getName(), (end - start)); } public String formatMessage(final FormatterDetails formatter, final FormattedMessage message) { try { Script script = formattingScripts.get(formatter); if (script == null) { addFormatter(formatter); script = formattingScripts.get(formatter); } scriptManager.setVariable(script, BaseScriptManager.RECEIVED_MESSAGE_PARAMETER, message); final String functionName = FORMAT_FUNCTION_NAME; return (String) scriptManager.invokeFunction(script, functionName); } catch (NoSuchMethodException | ScriptException e) { logger.trace("Cannot parse the message", e); return message.getPayload(); } } public String formatMessage(final FormatterDetails formatter, final FormattedMessage message, final boolean pretty) { if (pretty && !Boolean.FALSE.equals(prettyFormattingAvailable.get(formatter))) { try { Script script = formattingScripts.get(formatter); if (script == null) { addFormatter(formatter); script = formattingScripts.get(formatter); } scriptManager.setVariable(script, BaseScriptManager.RECEIVED_MESSAGE_PARAMETER, message); final String functionName = PRETTY_FUNCTION_NAME; return (String) scriptManager.invokeFunction(script, functionName); } catch (NoSuchMethodException e) { prettyFormattingAvailable.put(formatter, Boolean.FALSE); return formatMessage(formatter, message); } catch (ScriptException e) { logger.trace("Cannot parse the message", e); return message.getPayload(); } } else { return formatMessage(formatter, message); } } }