PageRenderTime 75ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/netbeans-7.3/web.monitor/src/org/netbeans/modules/web/monitor/client/Controller.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 1643 lines | 1201 code | 228 blank | 214 comment | 260 complexity | c9f6c2c08cab1453bce10e9751e1b363 MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * Contributor(s):
  28. *
  29. * The Original Software is NetBeans. The Initial Developer of the Original
  30. * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
  31. * Microsystems, Inc. All Rights Reserved.
  32. *
  33. * If you wish your version of this file to be governed by only the CDDL
  34. * or only the GPL Version 2, indicate your decision by adding
  35. * "[Contributor] elects to include this software in this distribution
  36. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  37. * single choice of license, a recipient has the option to distribute
  38. * your version of this file under either the CDDL, the GPL Version 2 or
  39. * to extend the choice of license to its licensees as provided above.
  40. * However, if you add GPL Version 2 code and therefore, elected the GPL
  41. * Version 2 license, then the option applies only if the new code is
  42. * made subject to such option by the copyright holder.
  43. */
  44. /**
  45. * @author Ana von Klopp
  46. */
  47. package org.netbeans.modules.web.monitor.client;
  48. import java.util.ArrayList;
  49. import java.util.Comparator;
  50. import java.util.Date;
  51. import java.util.Enumeration;
  52. import java.util.Hashtable;
  53. import java.util.List;
  54. import java.util.Vector;
  55. import java.util.Iterator;
  56. import java.io.File;
  57. import java.io.FileNotFoundException;
  58. import java.io.InputStreamReader;
  59. import java.io.IOException;
  60. import java.io.OutputStream;
  61. import java.io.PrintWriter;
  62. import java.net.InetAddress;
  63. import java.net.MalformedURLException;
  64. import java.net.Socket;
  65. import java.net.UnknownHostException;
  66. import java.net.URL;
  67. import java.util.logging.Level;
  68. import java.util.logging.Logger;
  69. import javax.swing.SwingUtilities;
  70. import org.openide.DialogDisplayer;
  71. import org.openide.NotifyDescriptor;
  72. import org.openide.awt.HtmlBrowser;
  73. import org.openide.filesystems.FileAlreadyLockedException;
  74. import org.openide.filesystems.FileObject;
  75. import org.openide.filesystems.FileLock;
  76. import org.openide.filesystems.FileUtil;
  77. import org.openide.filesystems.URLMapper;
  78. import org.openide.nodes.Node;
  79. import org.openide.nodes.AbstractNode;
  80. import org.openide.nodes.Children;
  81. import org.openide.util.NbBundle;
  82. import org.openide.util.RequestProcessor;
  83. import org.netbeans.modules.web.monitor.data.*;
  84. class Controller {
  85. // REPLAY strings - must be coordinated with server.MonitorFilter
  86. final static String REPLAY="netbeans.replay"; //NOI18N
  87. final static String PORT="netbeans.replay.port"; //NOI18N
  88. final static String REPLAYSTATUS="netbeans.replay.status"; //NOI18N
  89. final static String REPLAYSESSION="netbeans.replay.session"; //NOI18N
  90. static final boolean debug = false;
  91. //private transient static boolean starting = true;
  92. // Test server location and port
  93. // Should use InetAddress.getLocalhost() instead
  94. private transient static String server = "localhost"; //NOI18N
  95. private transient static int port = 8080;
  96. // Location of the files
  97. private static FileObject monDir = null;
  98. private static FileObject currDir = null;
  99. private static FileObject saveDir = null;
  100. private static FileObject replayDir = null;
  101. final static String monDirStr = "HTTPMonitor"; // NOI18N
  102. final static String currDirStr = "current"; // NOI18N
  103. final static String saveDirStr = "save"; // NOI18N
  104. final static String replayDirStr = "replay"; // NOI18N
  105. // Constant nodes etc we need to know about
  106. private transient NavigateNode root = null;
  107. private Children.SortedArray currTrans = null;
  108. private Children.SortedArray savedTrans = null;
  109. // These are the ones that should go.
  110. private Hashtable currBeans = null;
  111. private Hashtable saveBeans = null;
  112. private transient Comparator comp = null;
  113. private boolean useBrowserCookie = true;
  114. private static Controller instance = null;
  115. private Date startDate;
  116. private Controller() {
  117. // TODO: setting the startup date to 30s earlier from now to prevent deletion of the
  118. // first request (#56880), the ideal fix should be to use the IDE startup time
  119. startDate = new Date(System.currentTimeMillis() - 30000);
  120. currBeans = new Hashtable();
  121. saveBeans = new Hashtable();
  122. createNodeStructure();
  123. /*
  124. registerBrowserListener();
  125. */
  126. }
  127. static Controller getInstance() {
  128. if(instance == null)
  129. instance = new Controller();
  130. return instance;
  131. }
  132. /**
  133. * Invoked at startup, creates the root folder and the folder for
  134. * current and saved transactions (and their children arrays).
  135. */
  136. private void createNodeStructure() {
  137. comp = new CompTime(true);
  138. currTrans = new Children.SortedArray();
  139. currTrans.setComparator(comp);
  140. savedTrans = new Children.SortedArray();
  141. savedTrans.setComparator(comp);
  142. CurrNode currNode = new CurrNode(currTrans);
  143. SavedNode savedNode = new SavedNode(savedTrans);
  144. Node[] kids = new Node[2];
  145. kids[0] = currNode;
  146. kids[1] = savedNode;
  147. Children children = new Children.Array();
  148. children.add(kids);
  149. root = new NavigateNode(children);
  150. }
  151. /**
  152. * Adds a transaction to the list of current transactions.
  153. */
  154. void addTransaction(String id) {
  155. if(debug) log("Creating node for " + id);
  156. TransactionNode[] nodes = new TransactionNode[1];
  157. MonitorData md = retrieveMonitorData(id, currDirStr);
  158. try {
  159. nodes[0] = createTransactionNode(md, true);
  160. currTrans.add(nodes);
  161. }
  162. catch(Exception ex) {
  163. // If there is some kind of parsing exception, do nothing
  164. }
  165. }
  166. /**
  167. * Adds a transaction to the list of current transactions.
  168. */
  169. protected NavigateNode getRoot() {
  170. return root;
  171. }
  172. protected static FileObject getMonDir() throws FileNotFoundException {
  173. if(monDir == null || !monDir.isFolder()) {
  174. try {
  175. createDirectories();
  176. }
  177. catch(FileNotFoundException ex) {
  178. throw ex;
  179. }
  180. }
  181. return monDir;
  182. }
  183. protected static FileObject getCurrDir() throws FileNotFoundException {
  184. if(currDir == null || !currDir.isFolder()) {
  185. try{
  186. createDirectories();
  187. }
  188. catch(FileNotFoundException ex) {
  189. throw ex;
  190. }
  191. }
  192. return currDir;
  193. }
  194. protected static FileObject getReplayDir() throws FileNotFoundException {
  195. if(replayDir == null || !replayDir.isFolder()) {
  196. try{
  197. createDirectories();
  198. }
  199. catch(FileNotFoundException ex) {
  200. throw ex;
  201. }
  202. }
  203. return replayDir;
  204. }
  205. protected static FileObject getSaveDir() throws FileNotFoundException {
  206. if(saveDir == null || !saveDir.isFolder()) {
  207. try{
  208. createDirectories();
  209. }
  210. catch(FileNotFoundException ex) {
  211. throw ex;
  212. }
  213. }
  214. return saveDir;
  215. }
  216. boolean haveDirectories() {
  217. if(currDir == null) {
  218. try {
  219. currDir = getCurrDir();
  220. }
  221. catch(Exception ex) {
  222. return false;
  223. }
  224. }
  225. if(saveDir == null) {
  226. try {
  227. saveDir = getSaveDir();
  228. }
  229. catch(Exception ex) {
  230. return false;
  231. }
  232. }
  233. return true;
  234. }
  235. private static void createDirectories() throws FileNotFoundException {
  236. if(debug) log("Now in createDirectories()"); // NOI18N
  237. FileObject rootdir =
  238. FileUtil.getConfigRoot();
  239. if(debug) {
  240. log("Root directory is " + rootdir.getName()); // NOI18N
  241. File rootF = FileUtil.toFile(rootdir);
  242. log("Root directory abs path " + // NOI18N
  243. rootF.getAbsolutePath());
  244. }
  245. FileLock lock = null;
  246. if(monDir == null || !monDir.isFolder()) {
  247. try {
  248. monDir = rootdir.getFileObject(monDirStr);
  249. }
  250. catch(Exception ex) {
  251. }
  252. if(monDir == null || !monDir.isFolder()) {
  253. if(monDir != null) {
  254. try {
  255. lock = monDir.lock();
  256. monDir.delete(lock);
  257. }
  258. catch(FileAlreadyLockedException falex) {
  259. throw new FileNotFoundException();
  260. }
  261. catch(IOException ex) {
  262. throw new FileNotFoundException();
  263. }
  264. finally {
  265. if(lock != null) lock.releaseLock();
  266. }
  267. }
  268. try {
  269. monDir = rootdir.createFolder(monDirStr);
  270. }
  271. catch(IOException ioex) {
  272. if(debug) ioex.printStackTrace();
  273. }
  274. }
  275. if(monDir == null || !monDir.isFolder())
  276. throw new FileNotFoundException();
  277. }
  278. if(debug)
  279. log("monitor directory is " + monDir.getName());// NOI18N
  280. // Current directory
  281. if(currDir == null || !currDir.isFolder()) {
  282. try {
  283. currDir = monDir.getFileObject(currDirStr);
  284. }
  285. catch(Exception ex) { }
  286. if(currDir == null || !currDir.isFolder()) {
  287. lock = null;
  288. if(currDir != null) {
  289. try {
  290. lock = currDir.lock();
  291. currDir.delete(lock);
  292. }
  293. catch(FileAlreadyLockedException falex) {
  294. throw new FileNotFoundException();
  295. }
  296. catch(IOException ex) {
  297. throw new FileNotFoundException();
  298. }
  299. finally {
  300. if(lock != null) lock.releaseLock();
  301. }
  302. }
  303. try {
  304. currDir = monDir.createFolder(currDirStr);
  305. }
  306. catch(IOException ex) {
  307. if(debug) ex.printStackTrace();
  308. }
  309. }
  310. if(currDir == null || !currDir.isFolder())
  311. throw new FileNotFoundException();
  312. }
  313. if(debug) log("curr directory is " + currDir.getName()); // NOI18N
  314. // Save Directory
  315. if(saveDir == null || !saveDir.isFolder()) {
  316. try {
  317. saveDir = monDir.getFileObject(saveDirStr);
  318. }
  319. catch(Exception ex) { }
  320. if(saveDir == null || !saveDir.isFolder()) {
  321. if(saveDir != null) {
  322. lock = null;
  323. try {
  324. lock = saveDir.lock();
  325. saveDir.delete(lock);
  326. }
  327. catch(FileAlreadyLockedException falex) {
  328. throw new FileNotFoundException();
  329. }
  330. catch(IOException ex) {
  331. throw new FileNotFoundException();
  332. }
  333. finally {
  334. if(lock != null) lock.releaseLock();
  335. }
  336. }
  337. try {
  338. saveDir = monDir.createFolder(saveDirStr);
  339. }
  340. catch(IOException ex) {
  341. if(debug) ex.printStackTrace();
  342. }
  343. }
  344. if(saveDir == null || !saveDir.isFolder())
  345. throw new FileNotFoundException();
  346. if(debug)
  347. log("save directory is " + saveDir.getName()); // NOI18N
  348. }
  349. // Replay Directory
  350. if(replayDir == null || !replayDir.isFolder()) {
  351. try {
  352. replayDir = monDir.getFileObject(replayDirStr);
  353. }
  354. catch(Exception ex) { }
  355. if(replayDir == null || !replayDir.isFolder()) {
  356. if(replayDir != null) {
  357. lock = null;
  358. try {
  359. lock = replayDir.lock();
  360. replayDir.delete(lock);
  361. }
  362. catch(FileAlreadyLockedException falex) {
  363. throw new FileNotFoundException();
  364. }
  365. catch(IOException ex) {
  366. throw new FileNotFoundException();
  367. }
  368. finally {
  369. if(lock != null) lock.releaseLock();
  370. }
  371. }
  372. try {
  373. replayDir = monDir.createFolder(replayDirStr);
  374. }
  375. catch(Exception ex) {
  376. if(debug) ex.printStackTrace();
  377. }
  378. }
  379. if(replayDir == null || !replayDir.isFolder())
  380. throw new FileNotFoundException();
  381. if(debug)
  382. log("replay directory is " + replayDir.getName());// NOI18N
  383. }
  384. }
  385. /**
  386. * Invoked by ReplayAction. Replays the transaction corresponding to
  387. * the selected node.
  388. *
  389. * PENDING - it would be better if the nodes know which server
  390. * they were processed on. This would be the case if we listed the
  391. * nodes separately depending on the server that collected the
  392. * data.
  393. *
  394. */
  395. void replayTransaction(Node node) {
  396. if(debug)
  397. log("replayTransaction(Node node) from node " +
  398. node.getName()); // NOI18N
  399. if(!checkServer(true)) return;
  400. TransactionNode tn = null;
  401. try {
  402. tn = (TransactionNode)node;
  403. }
  404. catch(ClassCastException cce) {
  405. if(debug)
  406. log("Selected node was not a transaction node");//NOI18N
  407. return;
  408. }
  409. MonitorData md = getMonitorData(tn, false, false);
  410. if (md == null) {
  411. String msg = NbBundle.getMessage(Controller.class, "MSG_NoMonitorData");
  412. Logger.getLogger("global").log(Level.INFO, msg);
  413. return;
  414. }
  415. if(!useBrowserCookie)
  416. md.getRequestData().setReplaceSessionCookie(true);
  417. if(debug) {
  418. log("Replace is " + // NOI18N
  419. String.valueOf(md.getRequestData().getReplaceSessionCookie()));
  420. String fname = md.createTempFile("control-replay.xml"); // NOI18N
  421. log("Wrote replay data to " + fname);// NOI18N
  422. }
  423. String status;
  424. if(tn.isCurrent()) status = currDirStr;
  425. else status = saveDirStr;
  426. try {
  427. replayTransaction(md, status);
  428. }
  429. catch(UnknownHostException uhe) {
  430. // Notify the user that there is no host
  431. Object[] options = {
  432. NbBundle.getBundle(Controller.class).getString("MON_OK"),
  433. };
  434. NotifyDescriptor noServerDialog =
  435. new NotifyDescriptor(NbBundle.getMessage(Controller.class, "MON_Exec_server_no_host", md.getServerName()),
  436. NbBundle.getBundle(Controller.class).getString("MON_Exec_server"),
  437. NotifyDescriptor.DEFAULT_OPTION,
  438. NotifyDescriptor.INFORMATION_MESSAGE,
  439. options,
  440. options[0]);
  441. DialogDisplayer.getDefault().notify(noServerDialog);
  442. }
  443. catch(IOException ioe) {
  444. if(debug) {
  445. log(ioe.getMessage());
  446. ioe.printStackTrace();
  447. }
  448. // Notify the user that the server is not running
  449. Object[] options = {
  450. NbBundle.getBundle(Controller.class).getString("MON_OK"),
  451. };
  452. NotifyDescriptor noServerDialog =
  453. new NotifyDescriptor(NbBundle.getMessage(Controller.class, "MON_Exec_server_start", md.getServerAndPort()),
  454. NbBundle.getBundle(Controller.class).getString("MON_Exec_server"),
  455. NotifyDescriptor.DEFAULT_OPTION,
  456. NotifyDescriptor.INFORMATION_MESSAGE,
  457. options,
  458. options[0]);
  459. DialogDisplayer.getDefault().notify(noServerDialog);
  460. }
  461. }
  462. /**
  463. * Invoked by EditPanel. Replays the transaction corresponding to
  464. * the selected node.
  465. */
  466. void replayTransaction(MonitorData md)
  467. throws UnknownHostException, IOException {
  468. // PENDING - can't make UI changes right now for Sierra
  469. // any exception thrown in this method indicates that we
  470. // couldn't even get to the monitor data, and we should add an
  471. // additional panel to that effect. Also, unreadable monitor
  472. // data should cause the transaction to be removed from the
  473. // pane.
  474. if(debug) log("replayTransaction(MonitorData md)"); //NOI18N
  475. FileObject fo;
  476. FileLock lock = null;
  477. OutputStream out = null;
  478. PrintWriter pw = null;
  479. if(debug) log("Creating record for replay"); //NOI18N
  480. String id = md.getAttributeValue("id"); // NOI18N
  481. try {
  482. // This will fail if the file already exists. This can
  483. // happen if the replay previously failed because the
  484. // server was not running. This is dealt with in the
  485. // catch clause below.
  486. fo = getReplayDir().createData(id, "xml"); //NOI18N
  487. if(debug) log(" Created file for replay data");
  488. }
  489. catch(IOException ioex) {
  490. try {
  491. fo = getReplayDir().getFileObject(id, "xml");
  492. }
  493. catch(IllegalArgumentException iaex) {
  494. // This is only thrown if getReplayDir() is not a
  495. // folder. This should not happen.
  496. throw new IOException("No replay dir");
  497. }
  498. if(!fo.isData()) {
  499. throw new IOException("Can't create file, giving up");
  500. }
  501. try {
  502. lock = fo.lock();
  503. }
  504. catch(FileAlreadyLockedException falex) {
  505. throw new IOException("Old file exist, islocked");
  506. }
  507. try {
  508. fo.delete(lock);
  509. }
  510. catch(IOException ioex2) {
  511. throw new IOException("Couldn't delete old file");
  512. }
  513. finally {
  514. if(lock != null) lock.releaseLock();
  515. }
  516. try {
  517. fo = getReplayDir().createData(id, "xml"); //NOI18N
  518. }
  519. catch(IOException ioex2) {
  520. if(debug) log(" Couldn't create file for replay data");
  521. throw ioex2;
  522. }
  523. }
  524. try {
  525. lock = fo.lock();
  526. }
  527. catch(FileAlreadyLockedException fale) {
  528. if(debug) log("Can't get a file lock for the replay file");
  529. throw new IOException();
  530. }
  531. try {
  532. out = fo.getOutputStream(lock);
  533. pw = new PrintWriter(out);
  534. md.write(pw);
  535. if(debug) log("...record complete"); //NOI18N
  536. if(debug) {
  537. String fname =
  538. md.createTempFile("control-record.xml"); // NOI18N
  539. log("Wrote replay data to " + fname); // NOI18N
  540. }
  541. }
  542. catch(IOException ioex) {
  543. throw ioex;
  544. }
  545. finally {
  546. if(lock != null) lock.releaseLock();
  547. try {
  548. pw.close();
  549. }
  550. catch(Throwable t) {
  551. }
  552. try {
  553. out.close();
  554. }
  555. catch(Throwable t) {
  556. }
  557. }
  558. try {
  559. replayTransaction(md, replayDirStr);
  560. }
  561. catch(UnknownHostException uhe) {
  562. throw uhe;
  563. }
  564. catch(IOException ioe) {
  565. throw ioe;
  566. }
  567. }
  568. /**
  569. *
  570. */
  571. void replayTransaction(MonitorData md, String status)
  572. throws UnknownHostException, IOException {
  573. if(debug) log("replayTransaction(MonitorData md, String status )"); //NOI18N
  574. URL url = null;
  575. try {
  576. String name = md.getServerName();
  577. int port = md.getServerPort();
  578. StringBuffer uriBuf = new StringBuffer(128);
  579. uriBuf.append(md.getRequestData().getAttributeValue("uri")); //NOI18N
  580. uriBuf.append("?"); //NOI18N
  581. uriBuf.append(REPLAY);
  582. uriBuf.append("="); //NOI18N
  583. uriBuf.append(md.getAttributeValue("id")); //NOI18N
  584. uriBuf.append("&"); //NOI18N
  585. uriBuf.append(REPLAYSTATUS);
  586. uriBuf.append("="); //NOI18N
  587. uriBuf.append(status);
  588. String portS = null;
  589. try {
  590. URL u = getSampleHTTPServerURL();
  591. portS =
  592. String.valueOf(u.getPort()/*HttpServer.getRepositoryRoot().getPort()*/);
  593. }
  594. catch(Exception ex) {
  595. // No internal HTTP server, do nothing
  596. }
  597. if(portS != null) {
  598. uriBuf.append("&"); //NOI18N
  599. uriBuf.append(PORT);
  600. uriBuf.append("="); //NOI18N
  601. uriBuf.append(portS);
  602. }
  603. if(md.getRequestData().getReplaceSessionCookie()) {
  604. uriBuf.append("&"); //NOI18N
  605. uriBuf.append(REPLAYSESSION);
  606. uriBuf.append("="); //NOI18N
  607. uriBuf.append(md.getRequestData().getSessionID());
  608. }
  609. url = new URL("http", name, port, uriBuf.toString()); //NOI18N
  610. }
  611. catch(MalformedURLException me) {
  612. if(debug) log(me.getMessage());
  613. }
  614. catch(NumberFormatException ne) {
  615. if(debug) log(ne.getMessage());
  616. }
  617. // Send the url to the browser.
  618. try {
  619. showReplay(url);
  620. }
  621. catch(UnknownHostException uhe) {
  622. throw uhe;
  623. }
  624. catch(IOException ioe) {
  625. throw ioe;
  626. }
  627. }
  628. void saveTransaction(Node[] nodes) {
  629. if(!haveDirectories()) {
  630. // PENDING - report the error properly
  631. // This should not happen
  632. log("Couldn't get the directory"); //NOI18N
  633. return;
  634. }
  635. Node[] newNodes = new Node[nodes.length];
  636. TransactionNode mvNode;
  637. String id;
  638. boolean error = false;
  639. for(int i=0; i < nodes.length; ++i) {
  640. mvNode = (TransactionNode)nodes[i];
  641. id = mvNode.getID();
  642. if(debug) log(" Saving " + id); //NOI18N
  643. if(currBeans.containsKey(id))
  644. saveBeans.put(id, currBeans.remove(id));
  645. // Note I didn't load the bean here yet. Will only do that
  646. // if the data is displayed.
  647. FileLock lock = null;
  648. try {
  649. FileObject fold =
  650. currDir.getFileObject(id, "xml"); //NOI18N
  651. lock = fold.lock();
  652. fold.copy(saveDir, id, "xml"); //NOI18N
  653. if(debug) log(fold.getName());
  654. fold.delete(lock);
  655. mvNode.setCurrent(false);
  656. newNodes[i] = mvNode;
  657. }
  658. catch(FileAlreadyLockedException falex) {
  659. error = true;
  660. // PENDING report properly
  661. }
  662. catch(IOException ioex) {
  663. error = true;
  664. // PENDING report properly
  665. }
  666. catch(Exception ex) {
  667. error = true;
  668. // PENDING report properly
  669. }
  670. finally {
  671. if(lock != null) lock.releaseLock();
  672. }
  673. }
  674. if(!error) currTrans.remove(nodes);
  675. savedTrans.add(newNodes);
  676. }
  677. /**
  678. * Invoked by DeleteAction. Deletes a saved transaction
  679. */
  680. void deleteTransaction(final Node[] nodes) {
  681. if(!haveDirectories()) {
  682. // PENDING - report the error property
  683. // This should not happen
  684. log("Couldn't get the directory"); //NOI18N
  685. return;
  686. }
  687. // PENDING
  688. if((nodes == null) || (nodes.length == 0)) return;
  689. final ProgressMonitor progressMonitor = new ProgressMonitor();
  690. RequestProcessor.getDefault().post(new Runnable () {
  691. public void run() {
  692. // give awt thread chance to draw the progress monitor
  693. Thread.yield();
  694. // remove nodes
  695. currTrans.remove(nodes);
  696. savedTrans.remove(nodes);
  697. int oldValue = 0;
  698. for(int i=0; i < nodes.length; i++) {
  699. TransactionNode node = (TransactionNode)nodes[i];
  700. FileObject fileObject = null;
  701. if (node.isCurrent()) {
  702. String id = node.getID();
  703. fileObject = currDir.getFileObject(id, "xml");
  704. currBeans.remove(id);
  705. } else {
  706. String id = node.getID();
  707. fileObject = saveDir.getFileObject(id, "xml");
  708. saveBeans.remove(id);
  709. }
  710. if (fileObject != null) {
  711. // delete the file
  712. FileLock lock = null;
  713. try {
  714. lock = fileObject.lock();
  715. fileObject.delete(lock);
  716. } catch(FileAlreadyLockedException falex) {
  717. Logger.getLogger("global").log(Level.INFO, null, falex);
  718. } catch(IOException exception) {
  719. Logger.getLogger("global").log(Level.INFO, null, exception);
  720. } finally {
  721. if(lock != null) {
  722. lock.releaseLock();
  723. }
  724. }
  725. }
  726. // update the progress monitor if needed
  727. final int newValue = 100*(i+1)/nodes.length;
  728. if (newValue > oldValue) {
  729. oldValue = newValue;
  730. SwingUtilities.invokeLater(new Runnable () {
  731. public void run (){
  732. progressMonitor.setValue(newValue);
  733. }
  734. });
  735. }
  736. }
  737. SwingUtilities.invokeLater(new Runnable () {
  738. public void run (){
  739. progressMonitor.close();
  740. }
  741. });
  742. }
  743. });
  744. progressMonitor.setVisible(true);
  745. }
  746. void deleteDirectory(String dir) {
  747. if(!haveDirectories()) {
  748. // PENDING - report the error property
  749. // This should not happen
  750. log("Couldn't get the directory"); //NOI18N
  751. return;
  752. }
  753. final FileObject directory;
  754. if(dir.equals(saveDirStr)) {
  755. directory = saveDir;
  756. savedTrans.remove(savedTrans.getNodes());
  757. saveBeans.clear();
  758. }
  759. else {
  760. directory = currDir;
  761. currTrans.remove(currTrans.getNodes());
  762. currBeans.clear();
  763. }
  764. if (directory.getChildren().length == 0) {
  765. return;
  766. }
  767. final ProgressMonitor progressMonitor = new ProgressMonitor();
  768. RequestProcessor.getDefault().post(new Runnable () {
  769. public void run() {
  770. Thread.yield();
  771. int number = directory.getChildren().length;
  772. int oldValue = -1;
  773. int i = 0;
  774. for(Enumeration e = directory.getData(false); e.hasMoreElements(); ++i) {
  775. FileObject fo = (FileObject) e.nextElement();
  776. FileLock lock = null;
  777. try {
  778. lock = fo.lock();
  779. fo.delete(lock);
  780. } catch(FileAlreadyLockedException falex) {
  781. Logger.getLogger("global").log(Level.INFO, null, falex);
  782. } catch(IOException exception) {
  783. Logger.getLogger("global").log(Level.INFO, null, exception);
  784. } finally {
  785. if(lock != null) {
  786. lock.releaseLock();
  787. }
  788. }
  789. // update the progress monitor if needed
  790. final int newValue = 100 * i/number;
  791. if (newValue > oldValue) {
  792. oldValue = newValue;
  793. SwingUtilities.invokeLater(new Runnable() {
  794. public void run() {
  795. progressMonitor.setValue(newValue);
  796. }
  797. });
  798. }
  799. }
  800. SwingUtilities.invokeLater(new Runnable() {
  801. public void run() {
  802. progressMonitor.close();
  803. }
  804. });
  805. }
  806. });
  807. progressMonitor.setVisible(true);
  808. }
  809. void deleteTransactions() {
  810. deleteDirectory(Constants.Files.save);
  811. deleteDirectory(Constants.Files.current);
  812. savedTrans.remove(savedTrans.getNodes());
  813. currTrans.remove(currTrans.getNodes());
  814. }
  815. void getTransactions() {
  816. if(debug) log("getTransactions"); //NOI18N
  817. if(!haveDirectories()) {
  818. // PENDING - report the error property
  819. // This should not happen
  820. log("Couldn't get the directory"); //NOI18N
  821. return;
  822. }
  823. Enumeration e = null;
  824. Vector nodes = new Vector();
  825. int numtns = 0;
  826. TransactionNode[] tns = null;
  827. FileObject fo = null;
  828. String id = null;
  829. MonitorData md = null;
  830. currTrans.remove(currTrans.getNodes());
  831. if(debug) log("getTransactions removed old nodes"); //NOI18N
  832. e = currDir.getData(false);
  833. final List fileObjectsToDelete = new ArrayList();
  834. while(e.hasMoreElements()) {
  835. fo = (FileObject)e.nextElement();
  836. // #43213 - avoiding ModuleInstall class, delaying deletion of old records until now
  837. if (fo.lastModified().after(startDate)) {
  838. id = fo.getName();
  839. if(debug)
  840. log("getting current transaction: " + id); //NOI18N
  841. // Retrieve the monitordata
  842. md = retrieveMonitorData(id, currDir);
  843. if (md != null) {
  844. nodes.add(createTransactionNode(md, true));
  845. }
  846. } else {
  847. fileObjectsToDelete.add(fo);
  848. }
  849. }
  850. RequestProcessor.getDefault().post(new Runnable () {
  851. public void run() {
  852. for (Iterator it = fileObjectsToDelete.iterator(); it.hasNext(); ) {
  853. try {
  854. ((FileObject) it.next()).delete();
  855. } catch (IOException e) {
  856. Logger.getLogger("global").log(Level.INFO, null, e);
  857. }
  858. }
  859. }
  860. });
  861. numtns = nodes.size();
  862. tns = new TransactionNode[numtns];
  863. for(int i=0;i<numtns;++i)
  864. tns[i] = (TransactionNode)nodes.elementAt(i);
  865. currTrans.add(tns);
  866. savedTrans.remove(savedTrans.getNodes());
  867. nodes = new Vector();
  868. e = saveDir.getData(false);
  869. while(e.hasMoreElements()) {
  870. fo = (FileObject)e.nextElement();
  871. id = fo.getName();
  872. if(debug)
  873. log("getting current transaction: " + id); //NOI18N
  874. // Retrieve the monitordata
  875. md = retrieveMonitorData(id, saveDir);
  876. if (md != null) {
  877. nodes.add(createTransactionNode(md, false));
  878. }
  879. }
  880. numtns = nodes.size();
  881. tns = new TransactionNode[numtns];
  882. for(int i=0;i<numtns;++i) {
  883. tns[i] = (TransactionNode)nodes.elementAt(i);
  884. if(debug)
  885. log("Adding saved node" + tns[i].toString()); //NOI18N
  886. }
  887. savedTrans.add(tns);
  888. }
  889. private int parseStatusCode(String statusCode) {
  890. if (statusCode == null) {
  891. return -1;
  892. }
  893. // The statusCode is expected to look like e.g. "404: Not Found", if not
  894. // the status code was not resolved, which mostly means there was no error => 200
  895. int statusCodeNum = 200;
  896. try {
  897. int idx = statusCode.indexOf(':');
  898. if (idx != -1) {
  899. statusCode = statusCode.substring(0, idx);
  900. statusCodeNum = Integer.valueOf(statusCode).intValue();
  901. }
  902. } catch(NumberFormatException nfe) {
  903. // ignore
  904. }
  905. return statusCodeNum;
  906. }
  907. private TransactionNode createTransactionNode(MonitorData md, boolean current) {
  908. if(debug) log("createTransactionNode(MonitorData)"); //NOI18N
  909. Dispatches dis = null;
  910. RequestData rd = md.getRequestData();
  911. try {
  912. dis = md.getDispatches();
  913. }
  914. catch(Exception ex) {
  915. // Any parsing exception at this point, just ignore this
  916. // part of the request
  917. }
  918. TransactionNode node = null;
  919. // No dispatched requests, we add a regular transaction node
  920. if(dis == null || dis.sizeDispatchData() == 0 ) {
  921. if(debug) log("No dispatched requests"); //NOI18N
  922. node = new TransactionNode(md.getAttributeValue("id"), // NOI18N
  923. md.getAttributeValue("method"), // NOI18N
  924. md.getAttributeValue("resource"), //NOI18N
  925. current,
  926. parseStatusCode((rd == null) ? null : rd.getAttributeValue("status"))); // NOI18N
  927. }
  928. else {
  929. int numChildren = dis.sizeDispatchData();
  930. if(debug) log("We had some dispatched requests: " + //NOI18N
  931. String.valueOf(numChildren));
  932. if(debug) log("\t for id " + //NOI18N
  933. md.getAttributeValue("resource")); //NOI18N
  934. // Create all the children. 1
  935. Children.Array nested = new Children.Array();
  936. // First we create an array of children that has the same
  937. // size as the set of nodes.
  938. NestedNode[] nds = new NestedNode[numChildren];
  939. for(int i=0; i<numChildren; ++i) {
  940. if(debug) {
  941. log("Getting a new monitor data object"); //NOI18N
  942. log(dis.getDispatchData(i).getAttributeValue("resource")); //NOI18N
  943. }
  944. nds[i] = createNestedNode(dis.getDispatchData(i),
  945. md.getAttributeValue("method"), // NOI18N
  946. null, i);
  947. }
  948. nested.add(nds);
  949. node = new TransactionNode(md.getAttributeValue("id"), // NOI18N
  950. md.getAttributeValue("method"), // NOI18N
  951. md.getAttributeValue("resource"), //NOI18N
  952. nested,
  953. current,
  954. parseStatusCode((rd == null) ? null: rd.getAttributeValue("status"))); // NOI18N
  955. }
  956. return node;
  957. }
  958. private NestedNode createNestedNode(DispatchData dd,
  959. String method,
  960. int[] locator,
  961. int index) {
  962. Dispatches dis = dd.getDispatches();
  963. NestedNode node = null;
  964. int[] newloc = null;
  965. if(locator != null) {
  966. newloc = new int[locator.length + 1];
  967. int j=0;
  968. while(j<locator.length) {
  969. newloc[j] = locator[j];
  970. ++j;
  971. }
  972. newloc[j]=index;
  973. }
  974. else {
  975. newloc = new int[1];
  976. newloc[0] = index;
  977. }
  978. // No dispatched requests, we add a regular transaction node
  979. if(dis == null || dis.sizeDispatchData() == 0 ) {
  980. RequestData rd = dd.getRequestData();
  981. node = new NestedNode(dd.getAttributeValue("resource"),// NOI18N
  982. method,
  983. newloc,
  984. parseStatusCode((rd == null) ? null : rd.getAttributeValue("status"))); // NOI18N
  985. }
  986. else {
  987. int numChildren = dis.sizeDispatchData();
  988. Children.Array nested = new Children.Array();
  989. NestedNode[] nds = new NestedNode[numChildren];
  990. for(int i=0; i<numChildren; ++i) {
  991. nds[i] = createNestedNode(dis.getDispatchData(i),
  992. method, newloc, i);
  993. }
  994. nested.add(nds);
  995. node = new NestedNode(dd.getAttributeValue("resource"), // NOI18N
  996. method,
  997. nested,
  998. newloc,
  999. parseStatusCode(dd.getRequestData().getAttributeValue("status"))); // NOI18N
  1000. }
  1001. return node;
  1002. }
  1003. /**
  1004. * Sets the machine name and port of the web server. Not used in
  1005. * this version, we do not support remote debugging.
  1006. */
  1007. static void setServer(String loc, int p) {
  1008. port = p;
  1009. server = loc;
  1010. return;
  1011. }
  1012. void setComparator(Comparator comp) {
  1013. currTrans.setComparator(comp);
  1014. savedTrans.setComparator(comp);
  1015. }
  1016. /** This method toggles whether the request uses the browser's
  1017. * cookie or a cookie specified by the user. In 3.6, it is not
  1018. * possible to configure the monitor to use user-specified
  1019. * cookies, but I leave the method, in case it becomes possible in
  1020. * the future. Basically, we can no longer set the cookie on the
  1021. * server side (the Servlet APIs does not provide any method for
  1022. * doing this) but we could technically tell the browser that
  1023. * issues the replay request to send another cookie (the APIs for
  1024. * that are not there now). If so, the feature can be
  1025. * reintroduced.
  1026. */
  1027. void setUseBrowserCookie(boolean value) {
  1028. useBrowserCookie = value;
  1029. if(debug)
  1030. log("Setting useBrowserCookie to " + //NOI18N
  1031. String.valueOf(useBrowserCookie));
  1032. }
  1033. boolean getUseBrowserCookie() {
  1034. return useBrowserCookie;
  1035. }
  1036. /**
  1037. * @param node A node on the Monitor GUI
  1038. * @return a data record
  1039. * Convenience method - this gets the DataRecord corresponding to
  1040. * a node on the TransactionView panel from the cache if it is
  1041. * present. This is used to display the data from the node.
  1042. */
  1043. DataRecord getDataRecord(AbstractNode node) {
  1044. return getDataRecord(node, true);
  1045. }
  1046. /**
  1047. * @param node A node on the Monitor GUI
  1048. * @param fromCache true if it is OK to get the data record from
  1049. * the cache
  1050. * @return a data record
  1051. */
  1052. DataRecord getDataRecord(AbstractNode anode, boolean fromCache) {
  1053. if(debug) log("Entered getDataRecord()"); //NOI18N
  1054. if(anode instanceof TransactionNode) {
  1055. if(debug) log("TransactionNode"); //NOI18N
  1056. // Since this method is used to retrieve data records for
  1057. // the purposes of displaying the transaction, we cache
  1058. // the result
  1059. MonitorData md = getMonitorData((TransactionNode)anode,
  1060. fromCache, true);
  1061. if (md == null) {
  1062. String msg = NbBundle.getMessage(Controller.class, "MSG_NoMonitorData");
  1063. Logger.getLogger("global").log(Level.INFO, msg);
  1064. return null;
  1065. }
  1066. return (DataRecord)md;
  1067. }
  1068. else if(anode instanceof NestedNode) {
  1069. NestedNode node = (NestedNode)anode;
  1070. if(debug) log(node.toString());
  1071. int index[] = node.getIndex();
  1072. AbstractNode parent = (AbstractNode)node.getParentNode();
  1073. if(parent == null) {
  1074. if(debug) log("null parent, something went wrong!"); //NOI18N
  1075. return null;
  1076. }
  1077. while(parent != null && !(parent instanceof TransactionNode)) {
  1078. if(debug) log("Parent is not transaction node"); //NOI18N
  1079. if(debug) log(parent.toString());
  1080. parent = (AbstractNode)(parent.getParentNode());
  1081. }
  1082. if(debug) log("We got the transaction node"); //NOI18N
  1083. // We get the data record, from cache if it is present,
  1084. // and cache the node also
  1085. MonitorData md = getMonitorData((TransactionNode)parent,
  1086. true, true);
  1087. if (md == null) {
  1088. String msg = NbBundle.getMessage(Controller.class, "MSG_NoMonitorData");
  1089. Logger.getLogger("global").log(Level.INFO, msg);
  1090. return null;
  1091. }
  1092. DataRecord dr = (DataRecord)md;
  1093. int[] nodeindex = node.getIndex();
  1094. int c = 0;
  1095. while(c<nodeindex.length) {
  1096. if(debug) log("Doing the data record cycle"); //NOI18N
  1097. if(debug) log(String.valueOf(c) + ":" + //NOI18N
  1098. String.valueOf(nodeindex[c]));
  1099. Dispatches dis = dr.getDispatches();
  1100. dr = (DataRecord)dis.getDispatchData(nodeindex[c]);
  1101. ++c;
  1102. }
  1103. return dr;
  1104. }
  1105. return null;
  1106. }
  1107. /**
  1108. * @param node A node on the Monitor GUI
  1109. * @param fromCache true if it is OK to get the data record from
  1110. * the cache
  1111. * @param cacheIt true if it is OK to cache the data that we
  1112. * retrieve
  1113. * @return a data record, <code>null</code> if monitor date could not be got
  1114. */
  1115. MonitorData getMonitorData(TransactionNode node,
  1116. boolean fromCache,
  1117. boolean cacheIt) {
  1118. String id = node.getID();
  1119. Hashtable ht = null;
  1120. FileObject dir = null;
  1121. if(node.isCurrent()) {
  1122. ht = currBeans;
  1123. dir = currDir;
  1124. if(debug) log("node is current"); //NOI18N
  1125. }
  1126. else {
  1127. ht = saveBeans;
  1128. dir = saveDir;
  1129. }
  1130. if(debug) {
  1131. log("node id is " + node.getID()); //NOI18N
  1132. log("using directory " + dir.getName()); //NOI18N
  1133. }
  1134. if(fromCache && ht.containsKey(id))
  1135. return (MonitorData)(ht.get(id));
  1136. MonitorData md = retrieveMonitorData(id, dir);
  1137. if(cacheIt && md != null) ht.put(id, md);
  1138. return md;
  1139. }
  1140. /**
  1141. * @param id The ID of the record
  1142. * @param dirS The name of the directory in which the transaction
  1143. * resides
  1144. **/
  1145. MonitorData retrieveMonitorData(String id, String dirS) {
  1146. if(debug)
  1147. log("retrieveMonitorData(String, String)"); //NOI18N
  1148. if(!haveDirectories()) {
  1149. // PENDING - report the error property
  1150. log("Couldn't get the directory"); //NOI18N
  1151. return null;
  1152. }
  1153. FileObject dir = null;
  1154. if (dirS.equalsIgnoreCase(currDirStr)) dir = currDir;
  1155. else if (dirS.equalsIgnoreCase(saveDirStr)) dir = saveDir;
  1156. else if (dirS.equalsIgnoreCase(replayDirStr)) dir = replayDir;
  1157. if(debug) log("Directory = " + dir.getName()); //NOI18N
  1158. return retrieveMonitorData(id, dir);
  1159. }
  1160. /**
  1161. * @param id The ID of the record.
  1162. * @param dir The directory in which the transaction resides.
  1163. * @return monitor date, <code>null</code> if monitor date could not be retrieved.
  1164. */
  1165. MonitorData retrieveMonitorData(String id, FileObject dir) {
  1166. // PENDING - this method needs an error reporting mechanism in
  1167. // case the monitor data cannot be retrieved. Now it will just
  1168. // return null.
  1169. if(debug)
  1170. log("retrieveMonitorData(String, FileObject)"); //NOI18N
  1171. if(!haveDirectories()) {
  1172. // PENDING - report the error property
  1173. log("Couldn't get the directory"); //NOI18N
  1174. return null;
  1175. }
  1176. MonitorData md = null;
  1177. FileObject fo = null;
  1178. FileLock lock = null;
  1179. InputStreamReader in = null;
  1180. try {
  1181. fo = dir.getFileObject(id, "xml"); // NOI18N
  1182. if(debug) log("From file: " + //NOI18N
  1183. FileUtil.toFile(fo).getAbsolutePath());
  1184. if(debug) log("Locking it..."); //NOI18N
  1185. lock = fo.lock();
  1186. if(debug) log("Getting InputStreamReader"); //NOI18N
  1187. in = new InputStreamReader(fo.getInputStream());
  1188. if(debug) log("Creating monitor data"); //NOI18N
  1189. md = MonitorData.createGraph(in);
  1190. try {
  1191. if(dir == replayDir) fo.delete(lock);
  1192. }
  1193. catch(IOException ioex2) {}
  1194. }
  1195. catch(FileAlreadyLockedException falex) {
  1196. Logger.getLogger("global").log(Level.INFO, null, falex);
  1197. if(debug) {
  1198. log("File is locked: " + fo.getNameExt()); //NOI18N
  1199. falex.printStackTrace();
  1200. }
  1201. }
  1202. catch(IOException ioex) {
  1203. Logger.getLogger("global").log(Level.INFO, null, ioex);
  1204. if(debug) {
  1205. log("Couldn't read data file: " + fo.getNameExt()); //NOI18N
  1206. ioex.printStackTrace();
  1207. }
  1208. }
  1209. catch(Exception ex) {
  1210. Logger.getLogger("global").log(Level.INFO, null, ex);
  1211. if(debug) {
  1212. log("Something went wrong when retrieving record"); //NOI18N
  1213. ex.printStackTrace();
  1214. }
  1215. }
  1216. finally {
  1217. try { in.close(); }
  1218. catch(Throwable t) {}
  1219. if(lock != null) lock.releaseLock();
  1220. }
  1221. if(debug) log("We're done!"); //NOI18N
  1222. return md;
  1223. }
  1224. private void showReplay(final URL url) throws UnknownHostException,
  1225. IOException {
  1226. if(debug)
  1227. log("showReplay(URL url) url is " + url.toString()); // NOI18N
  1228. // First we check that we can find a host of the name that's
  1229. // specified
  1230. ServerCheck sc = new ServerCheck(url.getHost());
  1231. if(debug) log("host is " + url.getHost()); //NOI18N
  1232. Thread t = new Thread(sc);
  1233. t.start();
  1234. try {
  1235. t.join(2000);
  1236. }
  1237. catch(InterruptedException ie) {
  1238. }
  1239. t = null;
  1240. if(!sc.isServerGood()) {
  1241. if(debug)
  1242. log("showReplay(): No host"); // NOI18N
  1243. throw new UnknownHostException();
  1244. }
  1245. if(debug) log("performed server check"); // NOI18N
  1246. // Next we see if we can connect to the server
  1247. try {
  1248. Socket server = new Socket(url.getHost(), url.getPort());
  1249. server.close();
  1250. server = null;
  1251. }
  1252. catch(UnknownHostException uhe) {
  1253. if(debug) log("showReplay(): uhe2"); // NOI18N
  1254. throw uhe;
  1255. }
  1256. catch(IOException ioe) {
  1257. if(debug)
  1258. log("showReplay(): No service"); // NOI18N
  1259. throw ioe;
  1260. }
  1261. if(debug) log("showReplay(): reaching the end..."); // NOI18N
  1262. // window system code must be run in AWT thread
  1263. SwingUtilities.invokeLater(new Runnable() {
  1264. public void run () {
  1265. HtmlBrowser.URLDisplayer.getDefault().showURL(url);
  1266. }});
  1267. }
  1268. // PENDING - use the logger instead
  1269. private static void log(final String s) {
  1270. System.out.println("Controller::" + s); //NOI18N
  1271. }
  1272. private static URL getSampleHTTPServerURL() {
  1273. FileObject fo = FileUtil.getConfigFile("HTTPServer_DUMMY");
  1274. if (fo == null) {
  1275. return null;
  1276. }
  1277. URL u = URLMapper.findURL(fo, URLMapper.NETWORK);
  1278. return u;
  1279. }
  1280. boolean checkServer(boolean replay) {
  1281. try {
  1282. URL u = getSampleHTTPServerURL();
  1283. if(debug) log("Getting HTTP server - url " + u);
  1284. if (u.getProtocol().equals("http")) {
  1285. //HttpServer.getRepositoryRoot();
  1286. if(debug) log("Got the HTTP server");
  1287. return true;
  1288. }
  1289. }
  1290. catch(Throwable t) {
  1291. if(debug) {
  1292. log("Exception: " + t.getMessage());
  1293. t.printStackTrace();
  1294. }
  1295. Object[] options = {
  1296. NbBundle.getBundle(Controller.class).getString("MON_OK"),
  1297. };
  1298. String msg = null;
  1299. if(replay)
  1300. msg = NbBundle.getBundle(Controller.class).getString("MON_CantReplay");
  1301. else
  1302. msg = NbBundle.getBundle(Controller.class).getString("MON_NoServer");
  1303. NotifyDescriptor noServerDialog =
  1304. new NotifyDescriptor(msg,
  1305. NbBundle.getBundle(Controller.class).getString("MON_NoServerTitle"),
  1306. NotifyDescriptor.DEFAULT_OPTION,
  1307. NotifyDescriptor.INFORMATION_MESSAGE,
  1308. options,
  1309. options[0]);
  1310. DialogDisplayer.getDefault().notify(noServerDialog);
  1311. }
  1312. return false;
  1313. }
  1314. /**
  1315. * Does the server we try to replay on exist?
  1316. */
  1317. class ServerCheck implements Runnable {
  1318. boolean serverGood = false;
  1319. String serverName = null;
  1320. ServerCheck(String name) {
  1321. serverName = name;
  1322. }
  1323. public void run() {
  1324. try {
  1325. InetAddress.getByName(serverName);
  1326. serverGood = true;
  1327. }
  1328. catch (UnknownHostException e) {
  1329. serverGood = false;
  1330. }
  1331. }
  1332. boolean isServerGood() {
  1333. return serverGood;
  1334. }
  1335. }
  1336. /**
  1337. * Sort by time
  1338. */
  1339. class CompTime implements Comparator {
  1340. boolean descend = true;
  1341. CompTime(boolean descend) {
  1342. this.descend = descend;
  1343. }
  1344. public int compare(Object o1, Object o2) {
  1345. if(debug) {
  1346. log("In compareTime"); //NOI18N
  1347. log("Comparing " + String.valueOf(o1) + //NOI18N
  1348. " and " + String.valueOf(o2)); //NOI18N
  1349. log("Cast the nodes"); //NOI18N
  1350. }
  1351. TransactionNode n1 = (TransactionNode)o1;
  1352. TransactionNode n2 = (TransactionNode)o2;
  1353. if(debug) {
  1354. try {
  1355. log(n1.getID());
  1356. log(n2.getID());
  1357. }
  1358. catch(Exception ex) {};
  1359. }
  1360. int result;
  1361. if(descend)
  1362. result = n1.getID().compareTo(n2.getID());
  1363. else result = n2.getID().compareTo(n1.getID());
  1364. if(debug) log("End of compareTime"); //NOI18N
  1365. return result;
  1366. }
  1367. }
  1368. // PENDING
  1369. // Really dumb way of forcing this, but I couldn't get the tree to
  1370. // repaint... Will remove this method when that works.
  1371. void updateNodeNames() {
  1372. TransactionNode tn;
  1373. Node[] nodes = currTrans.getNodes();
  1374. int size = nodes.length;
  1375. for(int i=0; i<size; ++i) {
  1376. tn = (TransactionNode)nodes[i];
  1377. tn.setNameString();
  1378. }
  1379. nodes = savedTrans.getNodes();
  1380. size = nodes.length;
  1381. for(int i=0; i<size; ++i) {
  1382. tn = (TransactionNode)nodes[i];
  1383. tn.setNameString();
  1384. }
  1385. }
  1386. /**
  1387. * Sort alphabetically
  1388. */
  1389. class CompAlpha implements Comparator {
  1390. public int compare(Object o1, Object o2) {
  1391. if(debug) log("In compareAlpha"); //NOI18N
  1392. TransactionNode n1 = (TransactionNode)o1;
  1393. TransactionNode n2 = (TransactionNode)o2;
  1394. if(debug) log("cast the nodes"); //NOI18N
  1395. if(debug) {
  1396. log("Comparing " + String.valueOf(o1) + //NOI18N
  1397. " and " + String.valueOf(o2)); //NOI18N
  1398. try {
  1399. log("names"); //NOI18N
  1400. log(n1.getName());
  1401. log(n2.getName());
  1402. log("IDs"); //NOI18N
  1403. log(n1.getID());
  1404. log(n2.getID());
  1405. }
  1406. catch(Exception ex) {};
  1407. }
  1408. int diff = n1.getName().compareTo(n2.getName());
  1409. if(diff == 0)
  1410. return n1.getID().compareTo(n2.getID());
  1411. else
  1412. return diff;
  1413. }
  1414. }
  1415. } // Controller