package org.aperteworkflow.plugin.ext.log; import com.vaadin.ui.TextArea; import pl.net.bluesoft.rnd.processtool.model.BpmStep; import pl.net.bluesoft.rnd.processtool.model.ProcessInstance; import pl.net.bluesoft.rnd.processtool.model.ProcessInstanceAttribute; import pl.net.bluesoft.rnd.processtool.steps.ProcessToolProcessStep; import pl.net.bluesoft.rnd.processtool.ui.widgets.annotations.AliasName; import pl.net.bluesoft.rnd.processtool.ui.widgets.annotations.AperteDoc; import pl.net.bluesoft.rnd.processtool.ui.widgets.annotations.AutoWiredProperty; import pl.net.bluesoft.rnd.processtool.ui.widgets.annotations.AutoWiredPropertyConfigurator; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @AliasName(name = "LogStep") public class LogStep implements ProcessToolProcessStep { /** * Default logger */ private static final Logger DEFAULT_LOGGER = Logger.getLogger(LogStep.class.getName()); /** * Pattern used to extract the process attribute names from the log message */ private static final Pattern PROCESS_ATTRIBUTE_PATTERN = Pattern.compile("\\$\\{([a-zA-z0-9._-]+)\\}"); @AperteDoc( humanNameKey = "log-step.attribute.message", descriptionKey = "log-step.attribute.message.description" ) @AutoWiredProperty(required = true) @AutoWiredPropertyConfigurator(fieldClass = TextArea.class) private String message; @AperteDoc( humanNameKey = "log-step.attribute.loggerName", descriptionKey = "log-step.attribute.loggerName.description" ) @AutoWiredProperty private String loggerName; @AperteDoc( humanNameKey = "log-step.attribute.loggerLevel", descriptionKey = "log-step.attribute.loggerLevel.description" ) @AutoWiredProperty private String loggerLevel; @Override public String invoke(BpmStep step, Map params) throws Exception { Logger usedLogger = DEFAULT_LOGGER; if (loggerName != null) { usedLogger = Logger.getLogger(loggerName); } Level usedLevel = Level.INFO; if (loggerLevel != null) { try { Level.parse(loggerLevel); } catch (IllegalArgumentException e) { DEFAULT_LOGGER.log(Level.SEVERE, "Logger level " + loggerLevel + " is invalid, using INFO", e); } } String parsedMessage = parseLogMessage(message, step.getProcessInstance()); usedLogger.log(usedLevel, parsedMessage); return parsedMessage; } /** * Parse log message evaluating possible references to process attributes * * @param message Content of the message * @param processInstance Content of the process * @return Parsed message */ private String parseLogMessage(String message, ProcessInstance processInstance) { StringBuilder builder = new StringBuilder(); Matcher matcher = PROCESS_ATTRIBUTE_PATTERN.matcher(message); int pos = 0; while (matcher.find()) { String processAttributeKey = matcher.group(1); ProcessInstanceAttribute attribute = processInstance.findAttributeByKey(processAttributeKey); if (attribute != null) { int start = matcher.start(0); if (pos < start) { builder.append(message.substring(pos, start)); } builder.append(attribute.toString()); pos = matcher.end(0); } } if (pos < message.length()) { builder.append(message.substring(pos)); } return builder.toString(); } @SuppressWarnings("unused") public String getMessage() { return message; } @SuppressWarnings("unused") public void setMessage(String message) { this.message = message; } @SuppressWarnings("unused") public String getLoggerName() { return loggerName; } @SuppressWarnings("unused") public void setLoggerName(String loggerName) { this.loggerName = loggerName; } @SuppressWarnings("unused") public String getLoggerLevel() { return loggerLevel; } @SuppressWarnings("unused") public void setLoggerLevel(String loggerLevel) { this.loggerLevel = loggerLevel; } }