Author: pmouawad
Date: Sat Jan 19 21:35:26 2019
New Revision: 1851688

URL: http://svn.apache.org/viewvc?rev=1851688&view=rev
Log:
Bug 63093 - Add "Compile JSR223 Test Elements" menu item

Contributed by UbikLoadPack
Bugzilla Id: 63093

Added:
    
jmeter/trunk/src/core/org/apache/jmeter/gui/action/CompileJSR223TestElements.java
   (with props)
Modified:
    jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java
    jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
    jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
    jmeter/trunk/src/core/org/apache/jmeter/util/JSR223TestElement.java
    jmeter/trunk/xdocs/changes.xml

Modified: jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java
URL: 
http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java?rev=1851688&r1=1851687&r2=1851688&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java 
(original)
+++ jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java Sat Jan 
19 21:35:26 2019
@@ -45,6 +45,7 @@ public final class ActionNames {
     public static final String CLEAR_ALL        = "action.clear_all"; // 
$NON-NLS-1$
     public static final String CLOSE            = "close"; // $NON-NLS-1$
     public static final String COLLAPSE_ALL     = "collapse all"; // 
$NON-NLS-1$
+    public static final String COMPILE_JSR223   = "compile_jsr223"; // 
$NON-NLS-1$
     public static final String COPY             = "Copy"; // $NON-NLS-1$
     public static final String CUT              = "Cut"; // $NON-NLS-1$
     public static final String DEBUG_ON         = "debug_on"; // $NON-NLS-1$

Added: 
jmeter/trunk/src/core/org/apache/jmeter/gui/action/CompileJSR223TestElements.java
URL: 
http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/action/CompileJSR223TestElements.java?rev=1851688&view=auto
==============================================================================
--- 
jmeter/trunk/src/core/org/apache/jmeter/gui/action/CompileJSR223TestElements.java
 (added)
+++ 
jmeter/trunk/src/core/org/apache/jmeter/gui/action/CompileJSR223TestElements.java
 Sat Jan 19 21:35:26 2019
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.jmeter.gui.action;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.text.MessageFormat;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.MenuElement;
+
+import org.apache.jmeter.gui.GuiPackage;
+import org.apache.jmeter.gui.plugin.MenuCreator;
+import org.apache.jmeter.gui.tree.JMeterTreeNode;
+import org.apache.jmeter.testbeans.TestBeanHelper;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jmeter.util.JSR223TestElement;
+import org.apache.jorphan.collections.HashTree;
+import org.apache.jorphan.collections.HashTreeTraverser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Compile JSR223 Test Element that use Compilable script language
+ * @since 5.1
+ */
+public class CompileJSR223TestElements extends AbstractAction implements 
MenuCreator {
+    private static final Logger log = 
LoggerFactory.getLogger(CompileJSR223TestElements.class);
+    
+    private static final MessageFormat MESSAGE_FORMAT = 
+            new MessageFormat(JMeterUtils.getResString("compilation_errors")); 
// //$NON-NLS-1$
+    /**
+     * 
+     */
+    private static class JSR223TestElementCompilerVisitor implements 
HashTreeTraverser {
+        private int elementsWithCompilationErrors = 0;
+        public JSR223TestElementCompilerVisitor() {
+            super();
+        }
+        @Override
+        public void addNode(Object object, HashTree subTree) {
+            JMeterTreeNode treeNode = (JMeterTreeNode) object;
+            Object userObject = treeNode.getUserObject();
+            treeNode.setMarkedBySearch(false);
+            if (treeNode.isEnabled() && (userObject instanceof 
JSR223TestElement)) {
+                JSR223TestElement element = (JSR223TestElement) userObject;
+                TestBeanHelper.prepare(element);
+                try {
+                    log.info("Compiling {}", element.getName());
+                    if(!element.compile()) {
+                        elementsWithCompilationErrors++;
+                        treeNode.setMarkedBySearch(true);
+                    } else {
+                        log.info("Compilation succeeded for {}", 
element.getName());
+                    }
+                } catch (Exception e) {
+                    treeNode.setMarkedBySearch(true);
+                    log.error("Error compiling test element {}", 
element.getName(), e);
+                }
+            }
+        }
+
+        @Override
+        public void subtractNode() {
+            // NOOP
+        }
+        @Override
+        public void processPath() {
+            // NOOP
+        }
+        /**
+         * @return the elementsWithCompilationErrors
+         */
+        public int getElementsWithCompilationErrors() {
+            return elementsWithCompilationErrors;
+        }
+    }
+    
+    private static final Set<String> commands = new HashSet<>();
+
+    static {
+        commands.add(ActionNames.COMPILE_JSR223);
+    }
+
+    public CompileJSR223TestElements() {
+        super();
+    }
+
+    /**
+     * @see Command#doAction(ActionEvent)
+     */
+    @Override
+    public void doAction(ActionEvent e) {
+        HashTree wholeTree = 
GuiPackage.getInstance().getTreeModel().getTestPlan();
+        JSR223TestElementCompilerVisitor visitor = new 
JSR223TestElementCompilerVisitor();
+        wholeTree.traverse(visitor);
+        GuiPackage.getInstance().getMainFrame().repaint();
+        if (visitor.getElementsWithCompilationErrors()>0) {
+            JMeterUtils.reportErrorToUser(MESSAGE_FORMAT.format(new 
Object[]{Integer.valueOf(visitor.getElementsWithCompilationErrors())}));
+        }
+    }
+
+
+    /**
+     * @see Command#getActionNames()
+     */
+    @Override
+    public Set<String> getActionNames() {
+        return commands;
+    }
+
+    @Override
+    public JMenuItem[] getMenuItemsAtLocation(MENU_LOCATION location) {
+        if(location == MENU_LOCATION.HELP) {
+            
+            JMenuItem menuItemIC = new JMenuItem(
+                    JMeterUtils.getResString("compile_menu"), 
KeyEvent.VK_UNDEFINED);
+            menuItemIC.setName(ActionNames.COMPILE_JSR223);
+            menuItemIC.setActionCommand(ActionNames.COMPILE_JSR223);
+            menuItemIC.setAccelerator(null);
+            menuItemIC.addActionListener(ActionRouter.getInstance());
+
+            return new JMenuItem[]{menuItemIC};
+        }
+        return new JMenuItem[0];
+    }
+
+    @Override
+    public JMenu[] getTopLevelMenus() {
+        return new JMenu[0];
+    }
+
+    @Override
+    public boolean localeChanged(MenuElement menu) {
+        return false;
+    }
+
+    @Override
+    public void localeChanged() {
+        // NOOP
+    }
+}

Propchange: 
jmeter/trunk/src/core/org/apache/jmeter/gui/action/CompileJSR223TestElements.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jmeter/trunk/src/core/org/apache/jmeter/gui/action/CompileJSR223TestElements.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
URL: 
http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1851688&r1=1851687&r2=1851688&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties 
(original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Sat 
Jan 19 21:35:26 2019
@@ -211,6 +211,8 @@ comparison_regex_substitution=Substituti
 comparison_response_time=Response Time: 
 comparison_unit=\ ms
 comparison_visualizer_title=Comparison Assertion Visualizer
+compile_menu=Compile JSR223 Test Elements
+compilation_errors={0} element(s) with compilation errors have been marked in 
red. Check jmeter.log.
 concat_result=Append to existing file
 config_element=Config Element
 config_save_settings=Configure

Modified: 
jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
URL: 
http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1851688&r1=1851687&r2=1851688&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties 
(original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties 
Sat Jan 19 21:35:26 2019
@@ -206,6 +206,8 @@ comparison_regex_substitution=Substituti
 comparison_response_time=Temps de réponse \: 
 comparison_unit=ms
 comparison_visualizer_title=Récepteur d'assertions de comparaison
+compile_menu=Compiler les éléments de test JSR223
+compilation_errors={0} élément(s) JSR223 présentant des erreurs de 
compilation sont marqués en rouge. Vérifiez jmeter.log.
 concat_result=Ajouter les résultats au fichier existant
 config_element=Elément de configuration
 config_save_settings=Configurer

Modified: jmeter/trunk/src/core/org/apache/jmeter/util/JSR223TestElement.java
URL: 
http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/util/JSR223TestElement.java?rev=1851688&r1=1851687&r2=1851688&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/util/JSR223TestElement.java 
(original)
+++ jmeter/trunk/src/core/org/apache/jmeter/util/JSR223TestElement.java Sat Jan 
19 21:35:26 2019
@@ -55,6 +55,7 @@ public abstract class JSR223TestElement
 {
     private static final long serialVersionUID = 232L;
        
+    private static final Logger logger = 
LoggerFactory.getLogger(JSR223TestElement.class);
     /**
      * Cache of compiled scripts
      */
@@ -124,8 +125,8 @@ public abstract class JSR223TestElement
         final String fileName = getFilename();
         final String scriptParameters = getParameters();
         // Use actual class name for log
-        final Logger logger = LoggerFactory.getLogger(getClass());
-        bindings.put("log", logger); // $NON-NLS-1$ (this name is fixed)
+        final Logger elementLogger = 
LoggerFactory.getLogger(getClass().getName()+"."+getName());
+        bindings.put("log", elementLogger); // $NON-NLS-1$ (this name is fixed)
         bindings.put("Label", label); // $NON-NLS-1$ (this name is fixed)
         bindings.put("FileName", fileName); // $NON-NLS-1$ (this name is fixed)
         bindings.put("Parameters", scriptParameters); // $NON-NLS-1$ (this 
name is fixed)
@@ -154,13 +155,14 @@ public abstract class JSR223TestElement
      * - If ScriptEngine implements Compilable script will be compiled and 
cached
      * - If not if will be run
      * @param scriptEngine ScriptEngine
-     * @param bindings {@link Bindings} might be null
+     * @param pBindings {@link Bindings} might be null
      * @return Object returned by script
      * @throws IOException when reading the script fails
      * @throws ScriptException when compiling or evaluation of the script fails
      */
-    protected Object processFileOrScript(ScriptEngine scriptEngine, Bindings 
bindings)
+    protected Object processFileOrScript(ScriptEngine scriptEngine, final 
Bindings pBindings)
             throws IOException, ScriptException {
+        Bindings bindings = pBindings; 
         if (bindings == null) {
             bindings = scriptEngine.createBindings();
         }
@@ -174,19 +176,19 @@ public abstract class JSR223TestElement
             if (!StringUtils.isEmpty(getFilename())) {
                 if (scriptFile.exists() && scriptFile.canRead()) {
                     if (supportsCompilable) {
-                        String cacheKey = getScriptLanguage() + "#" + // 
$NON-NLS-1$
+                        String newCacheKey = getScriptLanguage() + "#" + // 
$NON-NLS-1$
                                 scriptFile.getAbsolutePath() + "#" + // 
$NON-NLS-1$
                                 scriptFile.lastModified();
-                        CompiledScript compiledScript = 
compiledScriptsCache.get(cacheKey);
+                        CompiledScript compiledScript = 
compiledScriptsCache.get(newCacheKey);
                         if (compiledScript == null) {
                             synchronized (compiledScriptsCache) {
-                                compiledScript = 
compiledScriptsCache.get(cacheKey);
+                                compiledScript = 
compiledScriptsCache.get(newCacheKey);
                                 if (compiledScript == null) {
                                     // TODO Charset ?
                                     try (BufferedReader fileReader = new 
BufferedReader(new FileReader(scriptFile),
                                             (int) scriptFile.length())) {
                                         compiledScript = ((Compilable) 
scriptEngine).compile(fileReader);
-                                        compiledScriptsCache.put(cacheKey, 
compiledScript);
+                                        compiledScriptsCache.put(newCacheKey, 
compiledScript);
                                     }
                                 }
                             }
@@ -236,6 +238,43 @@ public abstract class JSR223TestElement
     }
     
     /**
+     * @return boolean true if element is not compilable or if compilation 
succeeds
+     * @throws IOException if script is missing
+     * @throws ScriptException if compilation fails
+     */
+    public boolean compile() 
+        throws ScriptException, IOException {
+        String lang = getScriptLanguageWithDefault();
+        ScriptEngine scriptEngine = getInstance().getEngineByName(lang);
+        boolean supportsCompilable = scriptEngine instanceof Compilable
+                && 
!("bsh.engine.BshScriptEngine".equals(scriptEngine.getClass().getName())); // 
NOSONAR // $NON-NLS-1$
+        if(!supportsCompilable) {
+            return true;
+        }
+        if (!StringUtils.isEmpty(getScript())) {
+            try {
+                ((Compilable) scriptEngine).compile(getScript());
+                return true;
+            } catch (ScriptException e) {
+                logger.error("Error compiling script for test element {}, 
error:{}", getName(), e.getMessage());
+                return false;
+            }
+        } else {
+            File scriptFile = new File(getFilename());
+            try (BufferedReader fileReader = new BufferedReader(new 
FileReader(scriptFile),
+                    (int) scriptFile.length())) {
+                try {
+                    ((Compilable) scriptEngine).compile(fileReader);
+                    return true;
+                } catch (ScriptException e) {
+                    logger.error("Error compiling script for test element {}, 
error:{}", getName(), e.getMessage());
+                    return false;
+                }
+            }
+        }
+    }
+
+    /**
      * compute MD5 if it is null
      */
     private void computeScriptMD5() {

Modified: jmeter/trunk/xdocs/changes.xml
URL: 
http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1851688&r1=1851687&r2=1851688&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml [utf-8] (original)
+++ jmeter/trunk/xdocs/changes.xml [utf-8] Sat Jan 19 21:35:26 2019
@@ -135,6 +135,7 @@ of previous time slot as a base. Startin
     <li><bug>62829</bug>Allow specifying Proxy server scheme for HTTP request 
sampler, Advanced tab and command line option. Contributed by Hitesh Patel 
(hitesh.h.patel at gmail.com)</li>
     <li><bug>59633</bug>Menus <code>Save Test Plan as</code>, <code>Save as 
Test Fragment</code> and <code>Save Selection as ...</code> should use a new 
file name in File Dialog</li>
     <li><bug>61486</bug>Make jmeter-server and non GUI mode run headless</li>
+    <li><bug>63093</bug>Add <code>Compile JSR223 Test Elements</code> menu 
item. Contributed by Ubik Load Pack (support at ubikloadpack.com)</li>
 </ul>
 
 <ch_section>Non-functional changes</ch_section>


Reply via email to