Author: sebb
Date: Tue Feb 23 23:24:29 2010
New Revision: 915587

URL: http://svn.apache.org/viewvc?rev=915587&view=rev
Log:
Bug 48749 - Allowing custom Thread Groups

Added:
    
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/AbstractThreadGroup.java
   (with props)
    
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java
   (with props)
Modified:
    
jakarta/jmeter/trunk/src/components/org/apache/jmeter/control/gui/ModuleControllerGui.java
    
jakarta/jmeter/trunk/src/components/org/apache/jmeter/timers/ConstantThroughputTimer.java
    jakarta/jmeter/trunk/src/core/org/apache/jmeter/control/gui/TestPlanGui.java
    jakarta/jmeter/trunk/src/core/org/apache/jmeter/engine/ConvertListeners.java
    
jakarta/jmeter/trunk/src/core/org/apache/jmeter/engine/StandardJMeterEngine.java
    jakarta/jmeter/trunk/src/core/org/apache/jmeter/gui/util/MenuFactory.java
    
jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
    jakarta/jmeter/trunk/src/core/org/apache/jmeter/testelement/TestPlan.java
    jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterContext.java
    jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
    jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/ThreadGroup.java
    
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/gui/ThreadGroupGui.java
    
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/proxy/ProxyControl.java
    
jakarta/jmeter/trunk/src/reports/org/apache/jmeter/testelement/ReportPlan.java
    jakarta/jmeter/trunk/xdocs/changes.xml

Modified: 
jakarta/jmeter/trunk/src/components/org/apache/jmeter/control/gui/ModuleControllerGui.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/components/org/apache/jmeter/control/gui/ModuleControllerGui.java?rev=915587&r1=915586&r2=915587&view=diff
==============================================================================
--- 
jakarta/jmeter/trunk/src/components/org/apache/jmeter/control/gui/ModuleControllerGui.java
 (original)
+++ 
jakarta/jmeter/trunk/src/components/org/apache/jmeter/control/gui/ModuleControllerGui.java
 Tue Feb 23 23:24:29 2010
@@ -38,7 +38,7 @@
 import org.apache.jmeter.testelement.TestElement;
 import org.apache.jmeter.testelement.TestPlan;
 import org.apache.jmeter.testelement.WorkBench;
-import org.apache.jmeter.threads.ThreadGroup;
+import org.apache.jmeter.threads.AbstractThreadGroup;
 import org.apache.jmeter.util.JMeterUtils;
 import org.apache.jorphan.gui.layout.VerticalLayout;
 
@@ -205,7 +205,7 @@
                 StringBuilder name = new StringBuilder();
                 JMeterTreeNode cur = (JMeterTreeNode) node.getChildAt(i);
                 TestElement te = cur.getTestElement();
-                if (te instanceof ThreadGroup) {
+                if (te instanceof AbstractThreadGroup) {
                     name.append(parent_name);
                     name.append(cur.getName());
                     name.append(seperator);

Modified: 
jakarta/jmeter/trunk/src/components/org/apache/jmeter/timers/ConstantThroughputTimer.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/components/org/apache/jmeter/timers/ConstantThroughputTimer.java?rev=915587&r1=915586&r2=915587&view=diff
==============================================================================
--- 
jakarta/jmeter/trunk/src/components/org/apache/jmeter/timers/ConstantThroughputTimer.java
 (original)
+++ 
jakarta/jmeter/trunk/src/components/org/apache/jmeter/timers/ConstantThroughputTimer.java
 Tue Feb 23 23:24:29 2010
@@ -26,7 +26,7 @@
 import org.apache.jmeter.testelement.AbstractTestElement;
 import org.apache.jmeter.testelement.TestListener;
 import org.apache.jmeter.threads.JMeterContextService;
-import org.apache.jmeter.threads.ThreadGroup;
+import org.apache.jmeter.threads.AbstractThreadGroup;
 import org.apache.jmeter.util.JMeterUtils;
 import org.apache.jorphan.logging.LoggingManager;
 import org.apache.log.Logger;
@@ -70,9 +70,9 @@
     //For calculating throughput across all threads
     private final static ThroughputInfo allThreadsInfo = new ThroughputInfo();
 
-    //For holding the ThrougputInfo objects for all ThreadGroups. Keyed by 
ThreadGroup objects
-    private final static Map<ThreadGroup, ThroughputInfo> threadGroupsInfoMap =
-        new ConcurrentHashMap<ThreadGroup, ThroughputInfo>();
+    //For holding the ThrougputInfo objects for all ThreadGroups. Keyed by 
AbstractThreadGroup objects
+    private final static Map<AbstractThreadGroup, ThroughputInfo> 
threadGroupsInfoMap =
+        new ConcurrentHashMap<AbstractThreadGroup, ThroughputInfo>();
 
 
     /**
@@ -165,7 +165,7 @@
             break;
 
         case 4: //All threads in this group - alternate calculation
-            final org.apache.jmeter.threads.ThreadGroup group =
+            final org.apache.jmeter.threads.AbstractThreadGroup group =
                 JMeterContextService.getContext().getThreadGroup();
             ThroughputInfo groupInfo;
             synchronized (threadGroupsInfoMap) {

Modified: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/control/gui/TestPlanGui.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/control/gui/TestPlanGui.java?rev=915587&r1=915586&r2=915587&view=diff
==============================================================================
--- 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/control/gui/TestPlanGui.java 
(original)
+++ 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/control/gui/TestPlanGui.java 
Tue Feb 23 23:24:29 2010
@@ -36,7 +36,6 @@
 import org.apache.jmeter.testelement.TestElement;
 import org.apache.jmeter.testelement.TestPlan;
 import org.apache.jmeter.testelement.property.JMeterProperty;
-import org.apache.jmeter.threads.gui.ThreadGroupGui;
 import org.apache.jmeter.util.JMeterUtils;
 
 /**
@@ -87,8 +86,7 @@
     public JPopupMenu createPopupMenu() {
         JPopupMenu pop = new JPopupMenu();
         JMenu addMenu = new JMenu(JMeterUtils.getResString("add")); // 
$NON-NLS-1$
-        addMenu.add(MenuFactory.makeMenuItem(new 
ThreadGroupGui().getStaticLabel(), ThreadGroupGui.class.getName(),
-                ActionNames.ADD));
+        addMenu.add(MenuFactory.makeMenu(MenuFactory.THREADS, 
ActionNames.ADD));
         addMenu.add(MenuFactory.makeMenu(MenuFactory.CONFIG_ELEMENTS, 
ActionNames.ADD));
         addMenu.add(MenuFactory.makeMenu(MenuFactory.TIMERS, ActionNames.ADD));
         addMenu.add(MenuFactory.makeMenu(MenuFactory.PRE_PROCESSORS, 
ActionNames.ADD));

Modified: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/engine/ConvertListeners.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/engine/ConvertListeners.java?rev=915587&r1=915586&r2=915587&view=diff
==============================================================================
--- 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/engine/ConvertListeners.java 
(original)
+++ 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/engine/ConvertListeners.java 
Tue Feb 23 23:24:29 2010
@@ -30,7 +30,7 @@
 import org.apache.jmeter.samplers.SampleListener;
 import org.apache.jmeter.testelement.TestListener;
 import org.apache.jmeter.testelement.ThreadListener;
-import org.apache.jmeter.threads.ThreadGroup;
+import org.apache.jmeter.threads.AbstractThreadGroup;
 import org.apache.jorphan.collections.HashTree;
 import org.apache.jorphan.collections.HashTreeTraverser;
 import org.apache.jorphan.logging.LoggingManager;
@@ -53,8 +53,8 @@
         Iterator<?> iter = subTree.list().iterator();
         while (iter.hasNext()) {
             Object item = iter.next();
-            if (item instanceof ThreadGroup) {
-                log.info("num threads = " + ((ThreadGroup) 
item).getNumThreads());
+            if (item instanceof AbstractThreadGroup) {
+                log.info("num threads = " + ((AbstractThreadGroup) 
item).getNumThreads());
             }
             if (item instanceof Remoteable) {
                 if (item instanceof ThreadListener){

Modified: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/engine/StandardJMeterEngine.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/engine/StandardJMeterEngine.java?rev=915587&r1=915586&r2=915587&view=diff
==============================================================================
--- 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/engine/StandardJMeterEngine.java
 (original)
+++ 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/engine/StandardJMeterEngine.java
 Tue Feb 23 23:24:29 2010
@@ -44,7 +44,7 @@
 import org.apache.jmeter.threads.JMeterThreadMonitor;
 import org.apache.jmeter.threads.ListenerNotifier;
 import org.apache.jmeter.threads.TestCompiler;
-import org.apache.jmeter.threads.ThreadGroup;
+import org.apache.jmeter.threads.AbstractThreadGroup;
 import org.apache.jmeter.util.JMeterUtils;
 import org.apache.jorphan.collections.HashTree;
 import org.apache.jorphan.collections.ListedHashTree;
@@ -257,7 +257,7 @@
         Iterator<?> iter = elements.iterator();
         while (iter.hasNext()) {
             Object item = iter.next();
-            if (item instanceof ThreadGroup) {
+            if (item instanceof AbstractThreadGroup) {
                 iter.remove();
             } else if (!(item instanceof TestElement)) {
                 iter.remove();
@@ -421,13 +421,13 @@
 
         List<?> testLevelElements = new 
LinkedList<Object>(test.list(test.getArray()[0]));
         removeThreadGroups(testLevelElements);
-        SearchByClass<ThreadGroup> searcher = new 
SearchByClass<ThreadGroup>(ThreadGroup.class);
+        SearchByClass<AbstractThreadGroup> searcher = new 
SearchByClass<AbstractThreadGroup>(AbstractThreadGroup.class);
         test.traverse(searcher);
         TestCompiler.initialize();
         // for each thread group, generate threads
         // hand each thread the sampler controller
         // and the listeners, and the timer
-        Iterator<ThreadGroup> iter = searcher.getSearchResults().iterator();
+        Iterator<AbstractThreadGroup> iter = 
searcher.getSearchResults().iterator();
 
         /*
          * Here's where the test really starts. Run a Full GC now: it's no harm
@@ -444,16 +444,14 @@
         startingGroups = true;
         while (running && iter.hasNext()) {// for each thread group
             groupCount++;
-            ThreadGroup group = iter.next();
+            AbstractThreadGroup group = iter.next();
             int numThreads = group.getNumThreads();
             JMeterContextService.addTotalThreads(numThreads);
             boolean onErrorStopTest = group.getOnErrorStopTest();
             boolean onErrorStopTestNow = group.getOnErrorStopTestNow();
             boolean onErrorStopThread = group.getOnErrorStopThread();
             String groupName = group.getName();
-            int rampUp = group.getRampUp();
-            float perThreadDelay = ((float) (rampUp * 1000) / (float) 
numThreads);
-            log.info("Starting " + numThreads + " threads for group " + 
groupName + ". Ramp up = " + rampUp + ".");
+            log.info("Starting " + numThreads + " threads for group " + 
groupName + ".");
 
             if (onErrorStopTest) {
                 log.info("Test will stop on error");
@@ -464,7 +462,6 @@
             } else {
                 log.info("Thread will continue on error");
             }
-
             ListedHashTree threadGroupTree = (ListedHashTree) 
searcher.getSubTree(group);
             threadGroupTree.add(group, testLevelElements);
             for (int i = 0; running && i < numThreads; i++) {
@@ -472,18 +469,15 @@
                 jmeterThread.setThreadNum(i);
                 jmeterThread.setThreadGroup(group);
                 
jmeterThread.setInitialContext(JMeterContextService.getContext());
-                jmeterThread.setInitialDelay((int) (perThreadDelay * i));
                 final String threadName = groupName + " " + (groupCount) + "-" 
+ (i + 1);
                 jmeterThread.setThreadName(threadName);
-
-                scheduleThread(jmeterThread, group);
-
-                // Set up variables for stop handling
                 jmeterThread.setEngine(this);
                 jmeterThread.setOnErrorStopTest(onErrorStopTest);
                 jmeterThread.setOnErrorStopTestNow(onErrorStopTestNow);
                 jmeterThread.setOnErrorStopThread(onErrorStopThread);
 
+                group.scheduleThread(jmeterThread);
+
                 Thread newThread = new Thread(jmeterThread);
                 newThread.setName(threadName);
                 allThreads.put(jmeterThread, newThread);
@@ -509,39 +503,6 @@
         }
     }
 
-    /**
-     * This will schedule the time for the JMeterThread.
-     *
-     * @param thread
-     * @param group
-     */
-    private void scheduleThread(JMeterThread thread, ThreadGroup group) {
-        // if true the Scheduler is enabled
-        if (group.getScheduler()) {
-            long now = System.currentTimeMillis();
-            // set the start time for the Thread
-            if (group.getDelay() > 0) {// Duration is in seconds
-                thread.setStartTime(group.getDelay() * 1000 + now);
-            } else {
-                long start = group.getStartTime();
-                if (start < now) {
-                    start = now; // Force a sensible start time
-                }
-                thread.setStartTime(start);
-            }
-
-            // set the endtime for the Thread
-            if (group.getDuration() > 0) {// Duration is in seconds
-                thread.setEndTime(group.getDuration() * 1000 + 
(thread.getStartTime()));
-            } else {
-                thread.setEndTime(group.getEndTime());
-            }
-
-            // Enables the scheduler
-            thread.setScheduled(true);
-        }
-    }
-
     private boolean verifyThreadsStopped() {
         boolean stoppedAll = true;
         List<Thread> threadsToCheck = new ArrayList<Thread>(allThreads.size());

Modified: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/gui/util/MenuFactory.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/gui/util/MenuFactory.java?rev=915587&r1=915586&r2=915587&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/gui/util/MenuFactory.java 
(original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/gui/util/MenuFactory.java 
Tue Feb 23 23:24:29 2010
@@ -64,6 +64,8 @@
      *  These are used as menu categories in the menuMap Hashmap,
      *  and also for resource lookup in messages.properties
     */
+    public static final String THREADS = "menu_threads"; //$NON-NLS-1$
+
     public static final String TIMERS = "menu_timer"; //$NON-NLS-1$
 
     public static final String CONTROLLERS = "menu_logic_controller"; 
//$NON-NLS-1$
@@ -90,6 +92,7 @@
     // MENU_ADD_xxx - controls which items are in the ADD menu
     // MENU_PARENT_xxx - controls which items are in the Insert Parent menu
     private static final String[] MENU_ADD_CONTROLLER = new String[] {
+        MenuFactory.THREADS,
         MenuFactory.CONTROLLERS,
         MenuFactory.CONFIG_ELEMENTS,
         MenuFactory.TIMERS,
@@ -115,11 +118,12 @@
     private static final String[] MENU_PARENT_SAMPLER = new String[] {
         MenuFactory.CONTROLLERS };
 
-    private static final List<MenuInfo> timers, controllers, samplers, 
configElements,
-        assertions, listeners, nonTestElements,
+    private static final List<MenuInfo> timers, controllers, samplers, threads,
+        configElements, assertions, listeners, nonTestElements,
         postProcessors, preProcessors;
 
     static {
+        threads = new LinkedList<MenuInfo>();
         timers = new LinkedList<MenuInfo>();
         controllers = new LinkedList<MenuInfo>();
         samplers = new LinkedList<MenuInfo>();
@@ -129,6 +133,7 @@
         postProcessors = new LinkedList<MenuInfo>();
         preProcessors = new LinkedList<MenuInfo>();
         nonTestElements = new LinkedList<MenuInfo>();
+        menuMap.put(THREADS, threads);
         menuMap.put(TIMERS, timers);
         menuMap.put(ASSERTIONS, assertions);
         menuMap.put(CONFIG_ELEMENTS, configElements);
@@ -455,6 +460,9 @@
                     log.debug(name + " participates in no menus.");
                     continue;
                 }
+                if (categories.contains(THREADS)) {
+                    threads.add(new MenuInfo(item, name));
+                }
                 if (categories.contains(TIMERS)) {
                     timers.add(new MenuInfo(item, name));
                 }
@@ -545,14 +553,14 @@
         if (parent instanceof TestPlan) {
             if (foundClass(nodes,
                      new Class[]{Sampler.class, Controller.class}, // Samplers 
and Controllers need not apply ...
-                     org.apache.jmeter.threads.ThreadGroup.class)  // but 
ThreadGroup (Controller) is OK
+                     org.apache.jmeter.threads.AbstractThreadGroup.class)  // 
but AbstractThreadGroup (Controller) is OK
                 ){
                 return false;
             }
             return true;
         }
-        // ThreadGroup is only allowed under a TestPlan
-        if (foundClass(nodes, new 
Class[]{org.apache.jmeter.threads.ThreadGroup.class})){
+        // AbstractThreadGroup is only allowed under a TestPlan
+        if (foundClass(nodes, new 
Class[]{org.apache.jmeter.threads.AbstractThreadGroup.class})){
             return false;
         }
         if (parent instanceof Controller) {// Includes thread group; anything 
goes

Modified: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=915587&r1=915586&r2=915587&view=diff
==============================================================================
--- 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties 
(original)
+++ 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties 
Tue Feb 23 23:24:29 2010
@@ -484,6 +484,7 @@
 menu_edit=Edit
 menu_expand_all=Expand All
 menu_generative_controller=Sampler
+menu_threads=Threads (Users)
 menu_listener=Listener
 menu_logic_controller=Logic Controller
 menu_merge=Merge

Modified: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/testelement/TestPlan.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/testelement/TestPlan.java?rev=915587&r1=915586&r2=915587&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/testelement/TestPlan.java 
(original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/testelement/TestPlan.java 
Tue Feb 23 23:24:29 2010
@@ -31,7 +31,7 @@
 import org.apache.jmeter.testelement.property.BooleanProperty;
 import org.apache.jmeter.testelement.property.JMeterProperty;
 import org.apache.jmeter.testelement.property.TestElementProperty;
-import org.apache.jmeter.threads.ThreadGroup;
+import org.apache.jmeter.threads.AbstractThreadGroup;
 import org.apache.jorphan.logging.LoggingManager;
 import org.apache.jorphan.util.JOrphanUtils;
 import org.apache.log.Logger;
@@ -55,7 +55,7 @@
 
     private final static String BASEDIR = "basedir";
 
-    private transient List<ThreadGroup> threadGroups = new 
LinkedList<ThreadGroup>();
+    private transient List<AbstractThreadGroup> threadGroups = new 
LinkedList<AbstractThreadGroup>();
 
     // Does not appear to be needed
 //  private transient List configs = new LinkedList();
@@ -71,7 +71,7 @@
 
     static {
         // WARNING! This String value must be identical to the String value
-        // returned in org.apache.jmeter.threads.ThreadGroup.getClassLabel()
+        // returned in 
org.apache.jmeter.threads.AbstractThreadGroup.getClassLabel()
         // method. If it's not you will not be able to add a Thread Group
         // element to a Test Plan.
 
@@ -96,7 +96,7 @@
 
     // create transient item
     private Object readResolve(){
-        threadGroups = new LinkedList<ThreadGroup>();
+        threadGroups = new LinkedList<AbstractThreadGroup>();
         return this;
     }
 
@@ -228,15 +228,15 @@
     @Override
     public void addTestElement(TestElement tg) {
         super.addTestElement(tg);
-        if (tg instanceof ThreadGroup && !isRunningVersion()) {
-            addThreadGroup((ThreadGroup) tg);
+        if (tg instanceof AbstractThreadGroup && !isRunningVersion()) {
+            addThreadGroup((AbstractThreadGroup) tg);
         }
     }
 
 //    // Does not appear to be needed
 //  public void addJMeterComponent(TestElement child) {
-//      if (child instanceof ThreadGroup) {
-//          addThreadGroup((ThreadGroup) child);
+//      if (child instanceof AbstractThreadGroup) {
+//          addThreadGroup((AbstractThreadGroup) child);
 //      }
 //  }
 
@@ -262,12 +262,12 @@
 //  }
 
     /**
-     * Adds a feature to the ThreadGroup attribute of the TestPlan object.
+     * Adds a feature to the AbstractThreadGroup attribute of the TestPlan 
object.
      *
      * @param group
-     *            the feature to be added to the ThreadGroup attribute
+     *            the feature to be added to the AbstractThreadGroup attribute
      */
-    public void addThreadGroup(ThreadGroup group) {
+    public void addThreadGroup(AbstractThreadGroup group) {
         threadGroups.add(group);
     }
 

Added: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/AbstractThreadGroup.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/AbstractThreadGroup.java?rev=915587&view=auto
==============================================================================
--- 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/AbstractThreadGroup.java
 (added)
+++ 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/AbstractThreadGroup.java
 Tue Feb 23 23:24:29 2010
@@ -0,0 +1,189 @@
+/*
+ * 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.threads;
+
+import java.io.Serializable;
+
+import org.apache.jmeter.control.Controller;
+import org.apache.jmeter.control.LoopController;
+import org.apache.jmeter.engine.event.LoopIterationListener;
+import org.apache.jmeter.samplers.Sampler;
+import org.apache.jmeter.testelement.AbstractTestElement;
+import org.apache.jmeter.testelement.TestElement;
+import org.apache.jmeter.testelement.property.IntegerProperty;
+import org.apache.jmeter.testelement.property.JMeterProperty;
+import org.apache.jmeter.testelement.property.TestElementProperty;
+
+/**
+ * ThreadGroup holds the settings for a JMeter thread group.
+ * 
+ * This class is intended to be ThreadSafe.
+ */
+public abstract class AbstractThreadGroup extends AbstractTestElement 
implements Serializable, Controller {
+
+    private static final long serialVersionUID = 240L;
+
+    /** Action to be taken when a Sampler error occurs */
+    public final static String ON_SAMPLE_ERROR = 
"ThreadGroup.on_sample_error"; // int
+
+    /** Continue, i.e. ignore sampler errors */
+    public final static String ON_SAMPLE_ERROR_CONTINUE = "continue";
+
+    /** Stop current thread if sampler error occurs */
+    public final static String ON_SAMPLE_ERROR_STOPTHREAD = "stopthread";
+
+    /** Stop test (all threads) if sampler error occurs */
+    public final static String ON_SAMPLE_ERROR_STOPTEST = "stoptest";
+
+    /** Stop test NOW (all threads) if sampler error occurs */
+    public final static String ON_SAMPLE_ERROR_STOPTEST_NOW = "stoptestnow";
+
+    /** Number of threads in the thread group */
+    public final static String NUM_THREADS = "ThreadGroup.num_threads";
+
+    public final static String MAIN_CONTROLLER = "ThreadGroup.main_controller";
+
+    // @GuardedBy("this")
+    private int numberOfThreads = 0; // Number of active threads in this group
+
+    /** {...@inheritdoc} */
+    public boolean isDone() {
+        return getSamplerController().isDone();
+    }
+
+    /** {...@inheritdoc} */
+    public Sampler next() {
+        return getSamplerController().next();
+    }
+
+    /**
+     * Get the sampler controller.
+     *
+     * @return the sampler controller.
+     */
+    public Controller getSamplerController() {
+        Controller c = (Controller) 
getProperty(MAIN_CONTROLLER).getObjectValue();
+        return c;
+    }
+
+    /**
+     * Set the sampler controller.
+     *
+     * @param c
+     *            the sampler controller.
+     */
+    public void setSamplerController(LoopController c) {
+        c.setContinueForever(false);
+        setProperty(new TestElementProperty(MAIN_CONTROLLER, c));
+    }
+
+    /**
+     * Add a test element.
+     *
+     * @param child
+     *            the test element to add.
+     */
+    @Override
+    public void addTestElement(TestElement child) {
+        getSamplerController().addTestElement(child);
+    }
+
+    /** {...@inheritdoc} */
+    public void addIterationListener(LoopIterationListener lis) {
+        getSamplerController().addIterationListener(lis);
+    }
+
+    /** {...@inheritdoc} */
+    public void initialize() {
+        Controller c = getSamplerController();
+        JMeterProperty property = c.getProperty(TestElement.NAME);
+        property.setObjectValue(getName()); // Copy our name into that of the 
controller
+        property.setRunningVersion(property.isRunningVersion());// otherwise 
name reverts
+        c.initialize();
+    }
+
+    /**
+     * Set the total number of threads to start
+     *
+     * @param numThreads
+     *            the number of threads.
+     */
+    public void setNumThreads(int numThreads) {
+        setProperty(new IntegerProperty(NUM_THREADS, numThreads));
+    }
+
+    /**
+     * Increment the number of active threads
+     */
+    synchronized void incrNumberOfThreads() {
+        numberOfThreads++;
+    }
+
+    /**
+     * Decrement the number of active threads
+     */
+    synchronized void decrNumberOfThreads() {
+        numberOfThreads--;
+    }
+
+    /**
+     * Get the number of active threads
+     */
+    public synchronized int getNumberOfThreads() {
+        return numberOfThreads;
+    }
+    
+    /**
+     * Get the number of threads.
+     *
+     * @return the number of threads.
+     */
+    public int getNumThreads() {
+        return this.getPropertyAsInt(AbstractThreadGroup.NUM_THREADS);
+    }
+
+    /**
+     * Check if a sampler error should cause thread to stop.
+     *
+     * @return true if thread should stop
+     */
+    public boolean getOnErrorStopThread() {
+        return 
getPropertyAsString(ThreadGroup.ON_SAMPLE_ERROR).equalsIgnoreCase(ON_SAMPLE_ERROR_STOPTHREAD);
+    }
+
+    /**
+     * Check if a sampler error should cause test to stop.
+     *
+     * @return true if test (all threads) should stop
+     */
+    public boolean getOnErrorStopTest() {
+        return 
getPropertyAsString(ThreadGroup.ON_SAMPLE_ERROR).equalsIgnoreCase(ON_SAMPLE_ERROR_STOPTEST);
+    }
+
+    /**
+     * Check if a sampler error should cause test to stop now.
+     *
+     * @return true if test (all threads) should stop immediately
+     */
+    public boolean getOnErrorStopTestNow() {
+        return 
getPropertyAsString(ThreadGroup.ON_SAMPLE_ERROR).equalsIgnoreCase(ON_SAMPLE_ERROR_STOPTEST_NOW);
+    }
+
+    public abstract void scheduleThread(JMeterThread thread);
+}

Propchange: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/AbstractThreadGroup.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/AbstractThreadGroup.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterContext.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterContext.java?rev=915587&r1=915586&r2=915587&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterContext.java 
(original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterContext.java 
Tue Feb 23 23:24:29 2010
@@ -43,7 +43,7 @@
 
     private JMeterThread thread;
 
-    private ThreadGroup threadGroup;
+    private AbstractThreadGroup threadGroup;
 
     private int threadNum;
 
@@ -145,11 +145,11 @@
         this.thread = thread;
     }
 
-    public ThreadGroup getThreadGroup() {
+    public AbstractThreadGroup getThreadGroup() {
         return this.threadGroup;
     }
 
-    public void setThreadGroup(ThreadGroup threadgrp) {
+    public void setThreadGroup(AbstractThreadGroup threadgrp) {
         this.threadGroup = threadgrp;
     }
 

Modified: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java?rev=915587&r1=915586&r2=915587&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java 
(original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java 
Tue Feb 23 23:24:29 2010
@@ -102,7 +102,7 @@
     // based on this scheduler is enabled or disabled
 
     // Gives access to parent thread threadGroup
-    private ThreadGroup threadGroup;
+    private AbstractThreadGroup threadGroup;
 
     private StandardJMeterEngine engine = null; // For access to stop methods.
 
@@ -764,7 +764,7 @@
         onErrorStopThread = b;
     }
 
-    public void setThreadGroup(ThreadGroup group) {
+    public void setThreadGroup(AbstractThreadGroup group) {
         this.threadGroup = group;
     }
 

Modified: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/ThreadGroup.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/ThreadGroup.java?rev=915587&r1=915586&r2=915587&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/ThreadGroup.java 
(original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/ThreadGroup.java 
Tue Feb 23 23:24:29 2010
@@ -18,37 +18,21 @@
 
 package org.apache.jmeter.threads;
 
-import java.io.Serializable;
-
-import org.apache.jmeter.control.Controller;
-import org.apache.jmeter.control.LoopController;
-import org.apache.jmeter.engine.event.LoopIterationListener;
-import org.apache.jmeter.samplers.Sampler;
-import org.apache.jmeter.testelement.AbstractTestElement;
-import org.apache.jmeter.testelement.TestElement;
 import org.apache.jmeter.testelement.property.BooleanProperty;
 import org.apache.jmeter.testelement.property.IntegerProperty;
-import org.apache.jmeter.testelement.property.JMeterProperty;
 import org.apache.jmeter.testelement.property.LongProperty;
-import org.apache.jmeter.testelement.property.TestElementProperty;
 
 /**
  * ThreadGroup holds the settings for a JMeter thread group.
  * 
  * This class is intended to be ThreadSafe.
  */
-public class ThreadGroup extends AbstractTestElement implements Serializable, 
Controller {
-
-    private static final long serialVersionUID = 233L;
-
-    /** Number of threads in the thread group */
-    public final static String NUM_THREADS = "ThreadGroup.num_threads";
+public class ThreadGroup extends AbstractThreadGroup {
+    private static final long serialVersionUID = 240L;
 
     /** Ramp-up time */
     public final static String RAMP_TIME = "ThreadGroup.ramp_time";
 
-    public final static String MAIN_CONTROLLER = "ThreadGroup.main_controller";
-
     /** Whether scheduler is being used */
     public final static String SCHEDULER = "ThreadGroup.scheduler";
 
@@ -64,70 +48,12 @@
     /** Scheduler start delay, overrides start time */
     public final static String DELAY = "ThreadGroup.delay";
 
-    /** Action to be taken when a Sampler error occurs */
-    public final static String ON_SAMPLE_ERROR = 
"ThreadGroup.on_sample_error"; // int
-
-    /** Continue, i.e. ignore sampler errors */
-    public final static String ON_SAMPLE_ERROR_CONTINUE = "continue";
-
-    /** Stop current thread if sampler error occurs */
-    public final static String ON_SAMPLE_ERROR_STOPTHREAD = "stopthread";
-
-    /** Stop test (all threads) if sampler error occurs */
-    public final static String ON_SAMPLE_ERROR_STOPTEST = "stoptest";
-
-    /** Stop test NOW (all threads) if sampler error occurs */
-    public final static String ON_SAMPLE_ERROR_STOPTEST_NOW = "stoptestnow";
-
-    // @GuardedBy("this")
-    private int numberOfThreads = 0; // Number of active threads in this group
-
     /**
      * No-arg constructor.
      */
     public ThreadGroup() {
     }
 
-    /**
-     * Set the total number of threads to start
-     *
-     * @param numThreads
-     *            the number of threads.
-     */
-    public void setNumThreads(int numThreads) {
-        setProperty(new IntegerProperty(NUM_THREADS, numThreads));
-    }
-
-    /**
-     * Increment the number of active threads
-     */
-    synchronized void incrNumberOfThreads() {
-        numberOfThreads++;
-    }
-
-    /**
-     * Decrement the number of active threads
-     */
-    synchronized void decrNumberOfThreads() {
-        numberOfThreads--;
-    }
-
-    /**
-     * Get the number of active threads
-     */
-    public synchronized int getNumberOfThreads() {
-        return numberOfThreads;
-    }
-
-    /** {...@inheritdoc} */
-    public boolean isDone() {
-        return getSamplerController().isDone();
-    }
-
-    /** {...@inheritdoc} */
-    public Sampler next() {
-        return getSamplerController().next();
-    }
 
     /**
      * Set whether scheduler is being used
@@ -242,86 +168,46 @@
         return getPropertyAsInt(ThreadGroup.RAMP_TIME);
     }
 
-    /**
-     * Get the sampler controller.
-     *
-     * @return the sampler controller.
-     */
-    public Controller getSamplerController() {
-        Controller c = (Controller) 
getProperty(MAIN_CONTROLLER).getObjectValue();
-        return c;
-    }
-
-    /**
-     * Set the sampler controller.
-     *
-     * @param c
-     *            the sampler controller.
-     */
-    public void setSamplerController(LoopController c) {
-        c.setContinueForever(false);
-        setProperty(new TestElementProperty(MAIN_CONTROLLER, c));
-    }
-
-    /**
-     * Get the number of threads.
-     *
-     * @return the number of threads.
-     */
-    public int getNumThreads() {
-        return this.getPropertyAsInt(ThreadGroup.NUM_THREADS);
-    }
-
-    /**
-     * Add a test element.
-     *
-     * @param child
-     *            the test element to add.
-     */
-    @Override
-    public void addTestElement(TestElement child) {
-        getSamplerController().addTestElement(child);
-    }
-
-    /** {...@inheritdoc} */
-    public void addIterationListener(LoopIterationListener lis) {
-        getSamplerController().addIterationListener(lis);
-    }
-
-    /** {...@inheritdoc} */
-    public void initialize() {
-        Controller c = getSamplerController();
-        JMeterProperty property = c.getProperty(TestElement.NAME);
-        property.setObjectValue(getName()); // Copy our name into that of the 
controller
-        property.setRunningVersion(property.isRunningVersion());// otherwise 
name reverts
-        c.initialize();
+   @Override
+   public void scheduleThread(JMeterThread thread)
+   {
+       int rampUp = getRampUp();
+       float perThreadDelay = ((float) (rampUp * 1000) / (float) 
getNumThreads());
+       thread.setInitialDelay((int) (perThreadDelay * thread.getThreadNum()));
+
+       scheduleThread(thread, this);
+   }
+
+    /**
+     * This will schedule the time for the JMeterThread.
+     *
+     * @param thread
+     * @param group
+     */
+    private void scheduleThread(JMeterThread thread, ThreadGroup group) {
+        // if true the Scheduler is enabled
+        if (group.getScheduler()) {
+            long now = System.currentTimeMillis();
+            // set the start time for the Thread
+            if (group.getDelay() > 0) {// Duration is in seconds
+                thread.setStartTime(group.getDelay() * 1000 + now);
+            } else {
+                long start = group.getStartTime();
+                if (start < now) {
+                    start = now; // Force a sensible start time
+                }
+                thread.setStartTime(start);
+            }
+
+            // set the endtime for the Thread
+            if (group.getDuration() > 0) {// Duration is in seconds
+                thread.setEndTime(group.getDuration() * 1000 + 
(thread.getStartTime()));
+            } else {
+                thread.setEndTime(group.getEndTime());
+            }
+
+            // Enables the scheduler
+            thread.setScheduled(true);
+        }
     }
-
-    /**
-     * Check if a sampler error should cause thread to stop.
-     *
-     * @return true if thread should stop
-     */
-    public boolean getOnErrorStopThread() {
-        return 
getPropertyAsString(ThreadGroup.ON_SAMPLE_ERROR).equalsIgnoreCase(ON_SAMPLE_ERROR_STOPTHREAD);
-    }
-
-    /**
-     * Check if a sampler error should cause test to stop.
-     *
-     * @return true if test (all threads) should stop
-     */
-    public boolean getOnErrorStopTest() {
-        return 
getPropertyAsString(ThreadGroup.ON_SAMPLE_ERROR).equalsIgnoreCase(ON_SAMPLE_ERROR_STOPTEST);
-    }
-
-    /**
-     * Check if a sampler error should cause test to stop now.
-     *
-     * @return true if test (all threads) should stop immediately
-     */
-    public boolean getOnErrorStopTestNow() {
-        return 
getPropertyAsString(ThreadGroup.ON_SAMPLE_ERROR).equalsIgnoreCase(ON_SAMPLE_ERROR_STOPTEST_NOW);
-    }
-
 }

Added: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java?rev=915587&view=auto
==============================================================================
--- 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java
 (added)
+++ 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java
 Tue Feb 23 23:24:29 2010
@@ -0,0 +1,172 @@
+/*
+ * 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.threads.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.ItemListener;
+import java.util.Arrays;
+import java.util.Collection;
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.ButtonGroup;
+import javax.swing.JPanel;
+
+import javax.swing.JPopupMenu;
+import javax.swing.JRadioButton;
+
+import org.apache.jmeter.gui.AbstractJMeterGuiComponent;
+import org.apache.jmeter.gui.action.ActionNames;
+import org.apache.jmeter.gui.util.MenuFactory;
+import org.apache.jmeter.testelement.TestElement;
+import org.apache.jmeter.testelement.property.StringProperty;
+import org.apache.jmeter.threads.AbstractThreadGroup;
+import org.apache.jmeter.util.JMeterUtils;
+
+public abstract class AbstractThreadGroupGui extends 
AbstractJMeterGuiComponent implements ItemListener {
+    private static final long serialVersionUID = 240L;
+
+    // Sampler error action buttons
+    private JRadioButton continueBox;
+
+    private JRadioButton stopThrdBox;
+
+    private JRadioButton stopTestBox;
+
+    private JRadioButton stopTestNowBox;
+
+    public AbstractThreadGroupGui(){
+        super();
+        init();
+        initGui();
+    }
+
+    public Collection<String> getMenuCategories() {
+        return Arrays.asList(new String[] { MenuFactory.THREADS });
+    }
+
+    public JPopupMenu createPopupMenu() {
+        JPopupMenu pop = new JPopupMenu();
+        pop.add(MenuFactory.makeMenus(new String[] {
+                MenuFactory.CONTROLLERS,
+                MenuFactory.CONFIG_ELEMENTS,
+                MenuFactory.TIMERS,
+                MenuFactory.PRE_PROCESSORS,
+                MenuFactory.SAMPLERS,
+                MenuFactory.POST_PROCESSORS,
+                MenuFactory.ASSERTIONS,
+                MenuFactory.LISTENERS,
+                },
+                JMeterUtils.getResString("add"), // $NON-NLS-1$
+                ActionNames.ADD));
+        MenuFactory.addEditMenu(pop, true);
+        MenuFactory.addFileMenu(pop);
+        return pop;
+    }
+
+    @Override
+    public Dimension getPreferredSize() {
+        return getMinimumSize();
+    }
+
+    @Override
+    public void clearGui(){
+        super.clearGui();
+        initGui();
+    }
+
+    private void init() {
+        setLayout(new BorderLayout(0, 5));
+        setBorder(makeBorder());
+
+        Box box = Box.createVerticalBox();
+        box.add(makeTitlePanel());
+        box.add(createOnErrorPanel());
+        add(box, BorderLayout.NORTH);
+    }
+    
+    private void initGui() {
+        continueBox.setSelected(true);
+    }
+
+    private JPanel createOnErrorPanel() {
+        JPanel panel = new JPanel();
+        
panel.setBorder(BorderFactory.createTitledBorder(JMeterUtils.getResString("sampler_on_error_action")));
 // $NON-NLS-1$
+
+        ButtonGroup group = new ButtonGroup();
+
+        continueBox = new 
JRadioButton(JMeterUtils.getResString("sampler_on_error_continue")); // 
$NON-NLS-1$
+        group.add(continueBox);
+        panel.add(continueBox);
+
+        stopThrdBox = new 
JRadioButton(JMeterUtils.getResString("sampler_on_error_stop_thread")); // 
$NON-NLS-1$
+        group.add(stopThrdBox);
+        panel.add(stopThrdBox);
+
+        stopTestBox = new 
JRadioButton(JMeterUtils.getResString("sampler_on_error_stop_test")); // 
$NON-NLS-1$
+        group.add(stopTestBox);
+        panel.add(stopTestBox);
+
+        stopTestNowBox = new 
JRadioButton(JMeterUtils.getResString("sampler_on_error_stop_test_now")); // 
$NON-NLS-1$
+        group.add(stopTestNowBox);
+        panel.add(stopTestNowBox);
+
+        return panel;
+    }
+
+    private void setSampleErrorBoxes(AbstractThreadGroup te) {
+        if (te.getOnErrorStopTest()) {
+            stopTestBox.setSelected(true);
+        } else if (te.getOnErrorStopTestNow()) {
+            stopTestNowBox.setSelected(true);
+        } else if (te.getOnErrorStopThread()) {
+            stopThrdBox.setSelected(true);
+        } else {
+            continueBox.setSelected(true);
+        }
+    }
+
+    private String onSampleError() {
+        if (stopTestBox.isSelected()) {
+            return AbstractThreadGroup.ON_SAMPLE_ERROR_STOPTEST;
+        }
+        if (stopTestNowBox.isSelected()) {
+            return AbstractThreadGroup.ON_SAMPLE_ERROR_STOPTEST_NOW;
+        }
+        if (stopThrdBox.isSelected()) {
+            return AbstractThreadGroup.ON_SAMPLE_ERROR_STOPTHREAD;
+        }
+
+        // Defaults to continue
+        return AbstractThreadGroup.ON_SAMPLE_ERROR_CONTINUE;
+    }
+
+   @Override
+    public void configure(TestElement tg) {
+        super.configure(tg);
+        setSampleErrorBoxes((AbstractThreadGroup) tg);
+    }
+    
+   @Override
+    protected void configureTestElement(TestElement tg) {
+        super.configureTestElement(tg);
+        tg.setProperty(new StringProperty(AbstractThreadGroup.ON_SAMPLE_ERROR, 
onSampleError()));
+    }
+
+}

Propchange: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/gui/ThreadGroupGui.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/gui/ThreadGroupGui.java?rev=915587&r1=915586&r2=915587&view=diff
==============================================================================
--- 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/gui/ThreadGroupGui.java 
(original)
+++ 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/gui/ThreadGroupGui.java 
Tue Feb 23 23:24:29 2010
@@ -19,39 +19,28 @@
 package org.apache.jmeter.threads.gui;
 
 import java.awt.BorderLayout;
-import java.awt.Dimension;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
-import java.util.Collection;
 import java.util.Date;
 
 import javax.swing.BorderFactory;
-import javax.swing.Box;
-import javax.swing.ButtonGroup;
 import javax.swing.JCheckBox;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
-import javax.swing.JPopupMenu;
-import javax.swing.JRadioButton;
 import javax.swing.JTextField;
 
 import org.apache.jmeter.control.LoopController;
 import org.apache.jmeter.control.gui.LoopControlPanel;
-import org.apache.jmeter.gui.AbstractJMeterGuiComponent;
-import org.apache.jmeter.gui.action.ActionNames;
-import org.apache.jmeter.gui.tree.JMeterTreeNode;
 import org.apache.jmeter.gui.util.FocusRequester;
 import org.apache.jmeter.gui.util.JDateField;
-import org.apache.jmeter.gui.util.MenuFactory;
 import org.apache.jmeter.gui.util.VerticalPanel;
 import org.apache.jmeter.testelement.TestElement;
 import org.apache.jmeter.testelement.property.BooleanProperty;
 import org.apache.jmeter.testelement.property.LongProperty;
-import org.apache.jmeter.testelement.property.StringProperty;
 import org.apache.jmeter.threads.ThreadGroup;
 import org.apache.jmeter.util.JMeterUtils;
 
-public class ThreadGroupGui extends AbstractJMeterGuiComponent implements 
ItemListener {
+public class ThreadGroupGui extends AbstractThreadGroupGui implements 
ItemListener {
     private static final long serialVersionUID = 240L;
 
     private LoopControlPanel loopPanel;
@@ -76,25 +65,12 @@
 
     private JTextField delay; // Relative start-up time
 
-    // Sampler error action buttons
-    private JRadioButton continueBox;
-
-    private JRadioButton stopThrdBox;
-
-    private JRadioButton stopTestBox;
-
-    private JRadioButton stopTestNowBox;
-
     public ThreadGroupGui() {
         super();
         init();
         initGui();
     }
 
-    public Collection<String> getMenuCategories() {
-        return null;
-    }
-
     public TestElement createTestElement() {
         ThreadGroup tg = new ThreadGroup();
         modifyTestElement(tg);
@@ -117,38 +93,10 @@
         tg.setProperty(new LongProperty(ThreadGroup.START_TIME, 
start.getDate().getTime()));
         tg.setProperty(new LongProperty(ThreadGroup.END_TIME, 
end.getDate().getTime()));
         tg.setProperty(new BooleanProperty(ThreadGroup.SCHEDULER, 
scheduler.isSelected()));
-        tg.setProperty(new StringProperty(ThreadGroup.ON_SAMPLE_ERROR, 
onSampleError()));
         tg.setProperty(ThreadGroup.DURATION, duration.getText());
         tg.setProperty(ThreadGroup.DELAY, delay.getText());
     }
 
-    private void setSampleErrorBoxes(ThreadGroup te) {
-        if (te.getOnErrorStopTest()) {
-            stopTestBox.setSelected(true);
-        } else if (te.getOnErrorStopTestNow()) {
-            stopTestNowBox.setSelected(true);
-        } else if (te.getOnErrorStopThread()) {
-            stopThrdBox.setSelected(true);
-        } else {
-            continueBox.setSelected(true);
-        }
-    }
-
-    private String onSampleError() {
-        if (stopTestBox.isSelected()) {
-            return ThreadGroup.ON_SAMPLE_ERROR_STOPTEST;
-        }
-        if (stopTestNowBox.isSelected()) {
-            return ThreadGroup.ON_SAMPLE_ERROR_STOPTEST_NOW;
-        }
-        if (stopThrdBox.isSelected()) {
-            return ThreadGroup.ON_SAMPLE_ERROR_STOPTHREAD;
-        }
-
-        // Defaults to continue
-        return ThreadGroup.ON_SAMPLE_ERROR_CONTINUE;
-    }
-
     @Override
     public void configure(TestElement tg) {
         super.configure(tg);
@@ -174,8 +122,6 @@
         }
         duration.setText(tg.getPropertyAsString(ThreadGroup.DURATION));
         delay.setText(tg.getPropertyAsString(ThreadGroup.DELAY));
-
-        setSampleErrorBoxes((ThreadGroup) tg);
     }
 
     public void itemStateChanged(ItemEvent ie) {
@@ -188,25 +134,6 @@
         }
     }
 
-    public JPopupMenu createPopupMenu() {
-        JPopupMenu pop = new JPopupMenu();
-        pop.add(MenuFactory.makeMenus(new String[] {
-                MenuFactory.CONTROLLERS,
-                MenuFactory.CONFIG_ELEMENTS,
-                MenuFactory.TIMERS,
-                MenuFactory.PRE_PROCESSORS,
-                MenuFactory.SAMPLERS,
-                MenuFactory.POST_PROCESSORS,
-                MenuFactory.ASSERTIONS,
-                MenuFactory.LISTENERS,
-                },
-                JMeterUtils.getResString("add"), // $NON-NLS-1$
-                ActionNames.ADD));
-        MenuFactory.addEditMenu(pop, true);
-        MenuFactory.addFileMenu(pop);
-        return pop;
-    }
-
     private JPanel createControllerPanel() {
         loopPanel = new LoopControlPanel(false);
         LoopController looper = (LoopController) loopPanel.createTestElement();
@@ -276,31 +203,6 @@
         return "threadgroup"; // $NON-NLS-1$
     }
 
-    private JPanel createOnErrorPanel() {
-        JPanel panel = new JPanel();
-        
panel.setBorder(BorderFactory.createTitledBorder(JMeterUtils.getResString("sampler_on_error_action")));
 // $NON-NLS-1$
-
-        ButtonGroup group = new ButtonGroup();
-
-        continueBox = new 
JRadioButton(JMeterUtils.getResString("sampler_on_error_continue")); // 
$NON-NLS-1$
-        group.add(continueBox);
-        panel.add(continueBox);
-
-        stopThrdBox = new 
JRadioButton(JMeterUtils.getResString("sampler_on_error_stop_thread")); // 
$NON-NLS-1$
-        group.add(stopThrdBox);
-        panel.add(stopThrdBox);
-
-        stopTestBox = new 
JRadioButton(JMeterUtils.getResString("sampler_on_error_stop_test")); // 
$NON-NLS-1$
-        group.add(stopTestBox);
-        panel.add(stopTestBox);
-
-        stopTestNowBox = new 
JRadioButton(JMeterUtils.getResString("sampler_on_error_stop_test_now")); // 
$NON-NLS-1$
-        group.add(stopTestNowBox);
-        panel.add(stopTestNowBox);
-
-        return panel;
-    }
-
     @Override
     public void clearGui(){
         super.clearGui();
@@ -311,7 +213,6 @@
     private void initGui(){
         threadInput.setText("1"); // $NON-NLS-1$
         rampInput.setText("1"); // $NON-NLS-1$
-        continueBox.setSelected(true);
         loopPanel.clearGui();
         scheduler.setSelected(false);
         Date today = new Date();
@@ -321,17 +222,7 @@
         duration.setText(""); // $NON-NLS-1$
     }
 
-    private void init() {
-        setLayout(new BorderLayout(0, 5));
-        setBorder(makeBorder());
-
-        Box box = Box.createVerticalBox();
-        box.add(makeTitlePanel());
-        box.add(createOnErrorPanel());
-        add(box, BorderLayout.NORTH);
-
-        // JPanel mainPanel = new JPanel(new BorderLayout());
-
+   private void init() {
         // THREAD PROPERTIES
         VerticalPanel threadPropsPanel = new VerticalPanel();
         
threadPropsPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
@@ -385,13 +276,4 @@
         intgrationPanel.add(mainPanel);
         add(intgrationPanel, BorderLayout.CENTER);
     }
-
-    public void setNode(JMeterTreeNode node) {
-        getNamePanel().setNode(node);
-    }
-
-    @Override
-    public Dimension getPreferredSize() {
-        return getMinimumSize();
-    }
 }

Modified: 
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/proxy/ProxyControl.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/proxy/ProxyControl.java?rev=915587&r1=915586&r2=915587&view=diff
==============================================================================
--- 
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/proxy/ProxyControl.java
 (original)
+++ 
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/proxy/ProxyControl.java
 Tue Feb 23 23:24:29 2010
@@ -59,7 +59,7 @@
 import org.apache.jmeter.testelement.property.JMeterProperty;
 import org.apache.jmeter.testelement.property.PropertyIterator;
 import org.apache.jmeter.testelement.property.StringProperty;
-import org.apache.jmeter.threads.ThreadGroup;
+import org.apache.jmeter.threads.AbstractThreadGroup;
 import org.apache.jmeter.timers.Timer;
 import org.apache.jmeter.util.JMeterUtils;
 import org.apache.jorphan.logging.LoggingManager;
@@ -638,7 +638,7 @@
      * <ul>
      * <li>The controller specified by the <code>target</code> property.
      * <li>If none was specified, the first RecordingController in the tree.
-     * <li>If none is found, the first ThreadGroup in the tree.
+     * <li>If none is found, the first AbstractThreadGroup in the tree.
      * <li>If none is found, the Workspace.
      * </ul>
      *
@@ -654,7 +654,7 @@
         if (myTarget != null) {
             return myTarget;
         }
-        myTarget = findFirstNodeOfType(ThreadGroup.class);
+        myTarget = findFirstNodeOfType(AbstractThreadGroup.class);
         if (myTarget != null) {
             return myTarget;
         }

Modified: 
jakarta/jmeter/trunk/src/reports/org/apache/jmeter/testelement/ReportPlan.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/reports/org/apache/jmeter/testelement/ReportPlan.java?rev=915587&r1=915586&r2=915587&view=diff
==============================================================================
--- 
jakarta/jmeter/trunk/src/reports/org/apache/jmeter/testelement/ReportPlan.java 
(original)
+++ 
jakarta/jmeter/trunk/src/reports/org/apache/jmeter/testelement/ReportPlan.java 
Tue Feb 23 23:24:29 2010
@@ -32,7 +32,7 @@
 import org.apache.jmeter.testelement.property.CollectionProperty;
 import org.apache.jmeter.testelement.property.StringProperty;
 import org.apache.jmeter.testelement.property.TestElementProperty;
-import org.apache.jmeter.threads.ThreadGroup;
+import org.apache.jmeter.threads.AbstractThreadGroup;
 import org.apache.jmeter.util.JMeterUtils;
 import org.apache.jorphan.logging.LoggingManager;
 import org.apache.log.Logger;
@@ -50,7 +50,7 @@
 
     public static final String BASEDIR = "ReportPlan.basedir";
 
-    private transient List<ThreadGroup> reportPages = new 
LinkedList<ThreadGroup>();
+    private transient List<AbstractThreadGroup> reportPages = new 
LinkedList<AbstractThreadGroup>();
 
     private transient List<ConfigElement> configs = new 
LinkedList<ConfigElement>();
 
@@ -128,14 +128,14 @@
     @Override
     public void addTestElement(TestElement tg) {
         super.addTestElement(tg);
-        if (tg instanceof ThreadGroup && !isRunningVersion()) {
-            addReportPage((ThreadGroup) tg);
+        if (tg instanceof AbstractThreadGroup && !isRunningVersion()) {
+            addReportPage((AbstractThreadGroup) tg);
         }
     }
 
     public void addJMeterComponent(TestElement child) {
-        if (child instanceof ThreadGroup) {
-            addReportPage((ThreadGroup) child);
+        if (child instanceof AbstractThreadGroup) {
+            addReportPage((AbstractThreadGroup) child);
         }
     }
 
@@ -144,7 +144,7 @@
      *
      * @return the ThreadGroups value
      */
-    public Collection<ThreadGroup> getReportPages() {
+    public Collection<AbstractThreadGroup> getReportPages() {
         return reportPages;
     }
 
@@ -159,12 +159,12 @@
     }
 
     /**
-     * Adds a feature to the ThreadGroup attribute of the TestPlan object.
+     * Adds a feature to the AbstractThreadGroup attribute of the TestPlan 
object.
      *
      * @param group
-     *            the feature to be added to the ThreadGroup attribute
+     *            the feature to be added to the AbstractThreadGroup attribute
      */
-    public void addReportPage(ThreadGroup group) {
+    public void addReportPage(AbstractThreadGroup group) {
         reportPages.add(group);
     }
 

Modified: jakarta/jmeter/trunk/xdocs/changes.xml
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=915587&r1=915586&r2=915587&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/changes.xml (original)
+++ jakarta/jmeter/trunk/xdocs/changes.xml Tue Feb 23 23:24:29 2010
@@ -161,6 +161,7 @@
 <ul>
 <li>Bug 47909 - TransactionController should sum the latency</li>
 <li>Bug 41418 - Exclude timer duration from Transaction Controller runtime in 
report</li>
+<li>Bug 48749 - Allowing custom Thread Groups</li>
 </ul>
 
 <h3>Listeners</h3>



---------------------------------------------------------------------
To unsubscribe, e-mail: jmeter-dev-unsubscr...@jakarta.apache.org
For additional commands, e-mail: jmeter-dev-h...@jakarta.apache.org

Reply via email to