1 19 20 package org.apache.jmeter.module.integration; 21 22 import java.awt.Component ; 23 import java.awt.Container ; 24 import java.awt.Image ; 25 import java.awt.event.ActionEvent ; 26 import java.awt.event.ActionListener ; 27 import java.beans.PropertyChangeListener ; 28 import java.beans.PropertyChangeSupport ; 29 import java.io.OutputStreamWriter ; 30 import java.util.Enumeration ; 31 import java.util.Iterator ; 32 import java.util.LinkedList ; 33 import java.util.Properties ; 34 import java.util.concurrent.Semaphore ; 35 36 import javax.swing.ImageIcon ; 37 import javax.swing.JPopupMenu ; 38 import javax.swing.JTextPane ; 39 import javax.swing.SwingUtilities ; 40 import javax.swing.event.TreeModelEvent ; 41 import javax.swing.event.TreeModelListener ; 42 import javax.swing.event.TreeSelectionEvent ; 43 import javax.swing.tree.TreePath ; 44 45 import org.apache.jmeter.config.gui.AbstractConfigGui; 46 import org.apache.jmeter.control.gui.AbstractControllerGui; 47 import org.apache.jmeter.control.gui.TestPlanGui; 48 import org.apache.jmeter.control.gui.WorkBenchGui; 49 import org.apache.jmeter.gui.GUIFactory; 50 import org.apache.jmeter.gui.GuiPackage; 51 import org.apache.jmeter.gui.JMeterGUIComponent; 52 import org.apache.jmeter.gui.MainFrame; 53 import org.apache.jmeter.gui.action.ActionNames; 54 import org.apache.jmeter.gui.action.ActionRouter; 55 import org.apache.jmeter.gui.action.Load; 56 import org.apache.jmeter.gui.tree.JMeterTreeListener; 57 import org.apache.jmeter.gui.tree.JMeterTreeModel; 58 import org.apache.jmeter.gui.tree.JMeterTreeNode; 59 import org.apache.jmeter.plugin.JMeterPlugin; 60 import org.apache.jmeter.plugin.PluginManager; 61 import org.apache.jmeter.samplers.gui.AbstractSamplerGui; 62 import org.apache.jmeter.save.SaveService; 63 import org.apache.jmeter.testelement.TestElement; 64 import org.apache.jmeter.threads.gui.ThreadGroupGui; 65 import org.apache.jmeter.timers.gui.AbstractTimerGui; 66 import org.apache.jmeter.util.JMeterUtils; 67 import org.apache.jmeter.visualizers.gui.AbstractVisualizer; 68 import org.apache.jorphan.collections.HashTree; 69 import org.apache.jorphan.util.JOrphanUtils; 70 import org.openide.filesystems.FileLock; 71 import org.openide.filesystems.FileObject; 72 import org.openide.filesystems.FileUtil; 73 74 78 public class JMeterGUISupport implements JMeterPlugin { 79 public static final String DIRTY = "dirty"; 80 81 private static Semaphore initLock = new Semaphore (1); 82 private static JMeterGUISupport instance = null; 83 private static ThreadLocal currentNodeHolder = new ThreadLocal (); 84 85 private JMeterTreeModel treeModel = new JMeterTreeModel(); 86 87 private static TestElement lastSelectedElementCopy = null, lastSelectedElement = null; 88 89 private static boolean modified = false; 90 private static boolean editing = false; 91 private static boolean loading = false; 92 93 private PropertyChangeSupport pcs = new PropertyChangeSupport (this); 94 95 private final JMeterTreeListener modifiedListener = new JMeterTreeListener() { 96 public void valueChanged(final TreeSelectionEvent e) { 97 super.valueChanged(e); 98 SwingUtilities.invokeLater(new Runnable () { 99 public void run() { 100 TreePath path = e.getPath(); 101 JMeterTreeNode node = (JMeterTreeNode)path.getPathComponent(path.getPathCount() - 1); 102 TestElement element = (TestElement)node.getUserObject(); 103 104 if (lastSelectedElement != null) { 105 if (lastSelectedElementCopy != null) { 106 if (!lastSelectedElement.equals(lastSelectedElementCopy)) { 107 setDirty(true); 108 } 109 } else { 110 setDirty(true); 111 } 112 } 113 114 lastSelectedElement = element; 115 lastSelectedElementCopy = (TestElement)element.clone(); 116 } 117 }); 118 } 119 120 }; 121 private final JMeterTreeListener normalListener = new JMeterTreeListener(); 122 123 private GuiPackage jmeterGui = null; 124 private MainFrame frame = null; 125 126 127 private JMeterGUISupport() { 128 final String editorClassBackup = JTextPane.getEditorKitClassNameForContentType("text/html"); 130 JTextPane.registerEditorKitForContentType("text/html", "org.apache.jmeter.module.integration.HTMLEditorKit"); 131 133 PluginManager.install(this, true); 134 135 modifiedListener.setActionHandler(ActionRouter.getInstance()); 136 normalListener.setActionHandler(ActionRouter.getInstance()); 137 138 jmeterGui = GuiPackage.getInstance(modifiedListener, treeModel); 139 frame = new MainFrame(ActionRouter.getInstance(), treeModel, modifiedListener); 140 jmeterGui.setMainFrame(frame); 141 ActionRouter.getInstance().addPostActionListener(Object .class, new ActionListener () { 142 public void actionPerformed(ActionEvent e) { 143 } 145 }); 146 JTextPane.registerEditorKitForContentType("text/html", editorClassBackup); 148 150 treeModel.addTreeModelListener(new TreeModelListener () { 151 public void treeNodesChanged(TreeModelEvent e) { 152 } 154 public void treeNodesInserted(TreeModelEvent e) { 155 if (!loading) { 156 setDirty(true); 158 } 159 } 160 public void treeNodesRemoved(TreeModelEvent e) { 161 setDirty(true); 162 } 163 public void treeStructureChanged(TreeModelEvent e) { 164 } 166 }); 167 } 168 169 public final static JMeterGUISupport getDefault() { 170 if (instance == null) { 171 try { 172 initLock.acquire(); 173 if (instance == null) { 174 instance = new JMeterGUISupport(); 175 } 176 initLock.release(); 177 } catch (InterruptedException e) {} 178 } 179 return instance; 180 } 181 182 private static final String [][] DEFAULT_ICONS = { 184 { TestPlanGui.class.getName(), "org/apache/jmeter/images/beaker.gif" }, { AbstractTimerGui.class.getName(), "org/apache/jmeter/images/timer.gif" }, { ThreadGroupGui.class.getName(), "org/apache/jmeter/images/thread.gif" }, { AbstractVisualizer.class.getName(), "org/apache/jmeter/images/meter.png" }, { AbstractConfigGui.class.getName(), "org/apache/jmeter/images/testtubes.png" }, { AbstractControllerGui.class.getName(), "org/apache/jmeter/images/knob.gif" }, { WorkBenchGui.class.getName(), "org/apache/jmeter/images/clipboard.gif" }, { AbstractSamplerGui.class.getName(), "org/apache/jmeter/images/pipet.png" } }; 203 204 public String [][] getIconMappings() { 205 String iconProp = JMeterUtils.getPropDefault("jmeter.icons", "org/apache/jmeter/images/icon.properties"); Properties p = JMeterUtils.loadProperties(iconProp); 208 if (p == null) { 209 return DEFAULT_ICONS; 210 } 211 String [][] iconlist = new String [p.size()][3]; 212 Enumeration pe = p.keys(); 213 int i = 0; 214 while (pe.hasMoreElements()) { 215 String key = (String ) pe.nextElement(); 216 String icons[] = JOrphanUtils.split(p.getProperty(key), " "); iconlist[i][0] = key; 218 iconlist[i][1] = icons[0]; 219 if (icons.length > 1) 220 iconlist[i][2] = icons[1]; 221 i++; 222 } 223 return iconlist; 224 } 225 226 public String [][] getResourceBundles() { 227 return new String [0][]; 228 } 229 231 public void addPropertyChangeListener(final PropertyChangeListener pcl) { 233 pcs.addPropertyChangeListener(pcl); 234 } 235 236 public void addPropertyChangeListener(final String propertyName, final PropertyChangeListener pcl) { 237 pcs.addPropertyChangeListener(propertyName, pcl); 238 } 239 240 public void removePropertyChangeListener(final PropertyChangeListener pcl) { 241 pcs.removePropertyChangeListener(pcl); 242 } 243 244 public void removePropertyChangeListener(final String propertyName, final PropertyChangeListener pcl) { 245 pcs.removePropertyChangeListener(propertyName, pcl); 246 } 247 249 public Component getGui(final TestElement element) { 250 JMeterGUIComponent gui = jmeterGui.getGui(element); 251 gui.configure(element); 252 return (Component )gui; 253 } 254 255 public JPopupMenu getPopup(final TestElement element) { 256 currentNodeHolder.set(element); 257 return jmeterGui.getGui(element).createPopupMenu(); 258 } 259 260 public Image getIcon(final TestElement element) { 261 Object gui = jmeterGui.getGui(element); 262 ImageIcon icon = GUIFactory.getIcon(gui.getClass(), element.isEnabled()); 263 return icon != null ? icon.getImage() : null; 264 } 265 266 public void loadScript(final FileObject script) { 267 try { 268 loading = true; 269 if (isDirty()) { 270 ActionRouter.getInstance().doActionNow(new ActionEvent (this, 1, ActionNames.CLOSE)); 271 } 272 HashTree tree = SaveService.loadTree(script.getInputStream()); 273 GuiPackage.getInstance().setTestPlanFile(FileUtil.toFile(script).getAbsolutePath()); 274 275 276 new Load().insertLoadedTree(1, tree); 277 editing = true; 278 } catch (Exception e) { 279 e.printStackTrace(); 280 } finally { 281 loading = false; 282 } 283 } 284 285 public void unloadScript() { 286 GuiPackage.getInstance().getTreeModel().clearTestPlan(); 287 GuiPackage.getInstance().getTreeListener().getJTree().setSelectionRow(1); 288 289 GuiPackage.getInstance().setTestPlanFile(null); 291 292 ActionRouter.getInstance().actionPerformed(new ActionEvent (this, 1, ActionNames.ADD_ALL)); 293 294 editing = false; 295 setDirty(false); 296 } 297 298 public void saveScript(final FileObject script) throws Exception { 299 FileLock aLock = script.lock(); 300 try { 301 OutputStreamWriter osw = new OutputStreamWriter (script.getOutputStream(aLock)); 302 HashTree plan = treeModel.getTestPlan(); 303 convertSubTree(plan); 304 SaveService.saveTree(plan, osw); 305 ActionRouter.getInstance().doActionNow(new ActionEvent (this, 1, ActionNames.SUB_TREE_SAVED)); 306 } finally { 307 aLock.releaseLock(); 308 } 309 } 310 311 public Container getEditor() { 312 return frame != null ? frame.getContentPane() : null; 313 } 314 315 public void setDirty(final boolean value) { 316 if (value != modified) { 317 pcs.firePropertyChange(DIRTY, modified, value); 318 } 319 modified = value; 320 } 321 322 public boolean isDirty() { 323 return modified; 324 } 325 326 private void convertSubTree(HashTree tree) { 327 Iterator iter = new LinkedList (tree.list()).iterator(); 328 while (iter.hasNext()) { 329 JMeterTreeNode item = (JMeterTreeNode) iter.next(); 330 convertSubTree(tree.getTree(item)); 331 TestElement testElement = item.getTestElement(); 332 tree.replace(item, testElement); 333 } 334 } 335 } | Popular Tags |