PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/projects/weka-3-6-9/weka-src/src/main/java/weka/gui/beans/FlowRunner.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 489 lines | 320 code | 50 blank | 119 comment | 81 complexity | 583054a40e5bdc8da0dd85d9659a6934 MD5 | raw file
  1. /*
  2. * This program is free software; you can redistribute it and/or modify
  3. * it under the terms of the GNU General Public License as published by
  4. * the Free Software Foundation; either version 2 of the License, or
  5. * (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program; if not, write to the Free Software
  14. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. /*
  17. * FlowRunner.java
  18. * Copyright (C) 2008 University of Waikato, Hamilton, New Zealand
  19. *
  20. */
  21. package weka.gui.beans;
  22. import java.text.SimpleDateFormat;
  23. import java.util.ArrayList;
  24. import java.util.Date;
  25. import java.util.Set;
  26. import java.util.TreeMap;
  27. import java.util.Vector;
  28. import java.io.File;
  29. import java.io.FileInputStream;
  30. import java.io.FileOutputStream;
  31. import java.io.IOException;
  32. import java.io.InputStream;
  33. import java.io.InputStreamReader;
  34. import java.io.ObjectInputStream;
  35. import java.io.ObjectOutputStream;
  36. import java.io.OutputStream;
  37. import weka.core.Environment;
  38. import weka.core.EnvironmentHandler;
  39. import weka.core.RevisionHandler;
  40. import weka.core.RevisionUtils;
  41. import weka.gui.Logger;
  42. import weka.gui.beans.xml.*;
  43. /**
  44. * Small utility class for executing KnowledgeFlow
  45. * flows outside of the KnowledgeFlow application
  46. *
  47. * @author Mark Hall (mhall{[at]}pentaho{[dot]}org)
  48. * @version $Revision: 7059 $
  49. */
  50. public class FlowRunner implements RevisionHandler {
  51. /** The potential flow(s) to execute */
  52. protected Vector m_beans;
  53. protected int m_runningCount = 0;
  54. protected transient Logger m_log = null;
  55. protected transient Environment m_env;
  56. /** run each Startable bean sequentially? (default in parallel) */
  57. protected boolean m_startSequentially = false;
  58. public static class SimpleLogger implements weka.gui.Logger {
  59. SimpleDateFormat m_DateFormat =
  60. new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  61. public void logMessage(String lm) {
  62. System.out.println(m_DateFormat.format(new Date()) + ": " + lm);
  63. }
  64. public void statusMessage(String lm) {
  65. System.out.println(m_DateFormat.format(new Date()) + ": " + lm);
  66. }
  67. }
  68. /**
  69. * Constructor
  70. */
  71. public FlowRunner() {
  72. // make sure that properties and plugins are loaded
  73. KnowledgeFlowApp.loadProperties();
  74. }
  75. public void setLog(Logger log) {
  76. m_log = log;
  77. }
  78. protected void runSequentially(TreeMap<Integer, Startable> startables) {
  79. Set<Integer> s = startables.keySet();
  80. for (Integer i : s) {
  81. try {
  82. Startable startPoint = startables.get(i);
  83. startPoint.start();
  84. Thread.sleep(200);
  85. waitUntilFinished();
  86. } catch (Exception ex) {
  87. ex.printStackTrace();
  88. if (m_log != null) {
  89. m_log.logMessage(ex.getMessage());
  90. m_log.logMessage(Messages.getInstance().getString("FlowRunner_RunSequentially_LogMessage_Text_First"));
  91. } else {
  92. System.err.println(ex.getMessage());
  93. System.err.println(Messages.getInstance().getString("FlowRunner_RunSequentially_LogMessage_Text_Second"));
  94. }
  95. break;
  96. }
  97. }
  98. }
  99. protected synchronized void launchThread(final Startable s, final int flowNum) {
  100. Thread t = new Thread() {
  101. private int m_num = flowNum;
  102. public void run() {
  103. try {
  104. s.start();
  105. } catch (Exception ex) {
  106. ex.printStackTrace();
  107. if (m_log != null) {
  108. m_log.logMessage(ex.getMessage());
  109. } else {
  110. System.err.println(ex.getMessage());
  111. }
  112. } finally {
  113. /*
  114. if (m_log != null) {
  115. m_log.logMessage("[FlowRunner] flow " + m_num + " finished.");
  116. } else {
  117. System.out.println("[FlowRunner] Flow " + m_num + " finished.");
  118. }
  119. */
  120. decreaseCount();
  121. }
  122. }
  123. };
  124. m_runningCount++;
  125. t.setPriority(Thread.MIN_PRIORITY);
  126. t.start();
  127. }
  128. protected synchronized void decreaseCount() {
  129. m_runningCount--;
  130. }
  131. public synchronized void stopAllFlows() {
  132. for (int i = 0; i < m_beans.size(); i++) {
  133. BeanInstance temp = (BeanInstance)m_beans.elementAt(i);
  134. if (temp.getBean() instanceof BeanCommon) {
  135. // try to stop any execution
  136. ((BeanCommon)temp.getBean()).stop();
  137. }
  138. }
  139. }
  140. /**
  141. * Waits until all flows have finished executing before returning
  142. *
  143. */
  144. public void waitUntilFinished() {
  145. try {
  146. while (m_runningCount > 0) {
  147. Thread.sleep(200);
  148. }
  149. // now poll beans to see if there are any that are still busy
  150. // (i.e. any multi-threaded ones that queue data instead of blocking)
  151. while (true) {
  152. boolean busy = false;
  153. for (int i = 0; i < m_beans.size(); i++) {
  154. BeanInstance temp = (BeanInstance)m_beans.elementAt(i);
  155. if (temp.getBean() instanceof BeanCommon) {
  156. if (((BeanCommon)temp.getBean()).isBusy()) {
  157. busy = true;
  158. break; // for
  159. }
  160. }
  161. }
  162. if (busy) {
  163. Thread.sleep(3000);
  164. } else {
  165. break; // while
  166. }
  167. }
  168. } catch (Exception ex) {
  169. if (m_log != null) {
  170. m_log.logMessage(Messages.getInstance().getString("FlowRunner_WaitUntilFinished_LogMessage_Text"));
  171. } else {
  172. System.err.println(Messages.getInstance().getString("FlowRunner_WaitUntilFinished_Error_Text"));
  173. }
  174. stopAllFlows();
  175. // ex.printStackTrace();
  176. }
  177. }
  178. /**
  179. * Load a serialized KnowledgeFlow (either binary or xml)
  180. *
  181. * @param fileName the name of the file to load from
  182. * @throws Exception if something goes wrong
  183. */
  184. public void load(String fileName) throws Exception {
  185. if (!fileName.endsWith(".kf") && !fileName.endsWith(".kfml")) {
  186. throw new Exception(Messages.getInstance().getString("FlowRunner_Load_Exception_Text"));
  187. }
  188. if (fileName.endsWith(".kf")) {
  189. loadBinary(fileName);
  190. } else if (fileName.endsWith(".kfml")) {
  191. loadXML(fileName);
  192. }
  193. }
  194. /**
  195. * Load a binary serialized KnowledgeFlow
  196. *
  197. * @param fileName the name of the file to load from
  198. * @throws Exception if something goes wrong
  199. */
  200. public void loadBinary(String fileName) throws Exception {
  201. if (!fileName.endsWith(".kf")) {
  202. throw new Exception(Messages.getInstance().getString("FlowRunner_LoadBinary_Exception_Text_First"));
  203. }
  204. InputStream is = new FileInputStream(fileName);
  205. ObjectInputStream ois = new ObjectInputStream(is);
  206. m_beans = (Vector)ois.readObject();
  207. // don't need the graphical connections
  208. ois.close();
  209. if (m_env != null) {
  210. String parentDir = (new File(fileName)).getParent();
  211. if (parentDir == null) {
  212. parentDir = "./";
  213. }
  214. m_env.addVariable("Internal.knowledgeflow.directory",
  215. parentDir);
  216. }
  217. }
  218. /**
  219. * Load an XML serialized KnowledgeFlow
  220. *
  221. * @param fileName the name of the file to load from
  222. * @throws Exception if something goes wrong
  223. */
  224. public void loadXML(String fileName) throws Exception {
  225. if (!fileName.endsWith(".kfml")) {
  226. throw new Exception(Messages.getInstance().getString("FlowRunner_LoadXML_Exception_Text"));
  227. }
  228. XMLBeans xml = new XMLBeans(null, null);
  229. Vector v = (Vector) xml.read(new File(fileName));
  230. m_beans = (Vector) v.get(XMLBeans.INDEX_BEANINSTANCES);
  231. if (m_env != null) {
  232. String parentDir = (new File(fileName)).getParent();
  233. if (parentDir == null) {
  234. parentDir = "./";
  235. }
  236. m_env.addVariable("Internal.knowledgeflow.directory",
  237. parentDir);
  238. } else {
  239. System.err.println(Messages.getInstance().getString("FlowRunner_LoadXML_Error_Text"));
  240. }
  241. }
  242. /**
  243. * Get the vector holding the flow(s)
  244. *
  245. * @return the Vector holding the flow(s)
  246. */
  247. public Vector getFlows() {
  248. return m_beans;
  249. }
  250. /**
  251. * Set the vector holding the flows(s) to run
  252. *
  253. * @param beans the Vector holding the flows to run
  254. */
  255. public void setFlows(Vector beans) {
  256. m_beans = beans;
  257. }
  258. /**
  259. * Set the environment variables to use. NOTE: this needs
  260. * to be called BEFORE a load method is invoked to ensure
  261. * that the ${Internal.knowledgeflow.directory} variable get
  262. * set in the supplied Environment object.
  263. *
  264. * @param env the environment variables to use.
  265. */
  266. public void setEnvironment(Environment env) {
  267. m_env = env;
  268. }
  269. /**
  270. * Get the environment variables that are in use.
  271. *
  272. * @return the environment variables that are in ues.
  273. */
  274. public Environment getEnvironment() {
  275. return m_env;
  276. }
  277. /**
  278. * Set whether to launch Startable beans one after the other
  279. * or all in parallel.
  280. *
  281. * @param s true if Startable beans are to be launched sequentially
  282. */
  283. public void setStartSequentially(boolean s) {
  284. m_startSequentially = s;
  285. }
  286. /**
  287. * Gets whether Startable beans will be launched sequentially
  288. * or all in parallel.
  289. *
  290. * @return true if Startable beans will be launched sequentially
  291. */
  292. public boolean getStartSequentially() {
  293. return m_startSequentially;
  294. }
  295. /**
  296. * Launch all loaded KnowledgeFlow
  297. *
  298. * @throws Exception if something goes wrong during execution
  299. */
  300. public void run() throws Exception {
  301. if (m_beans == null) {
  302. throw new Exception(Messages.getInstance().getString("FlowRunner_Run_Exception_Text"));
  303. }
  304. // register the log (if set) with the beans
  305. for (int i = 0; i < m_beans.size(); i++) {
  306. BeanInstance tempB = (BeanInstance)m_beans.elementAt(i);
  307. if (m_log != null) {
  308. if (tempB.getBean() instanceof BeanCommon) {
  309. ((BeanCommon)tempB.getBean()).setLog(m_log);
  310. }
  311. }
  312. if (tempB.getBean() instanceof EnvironmentHandler) {
  313. ((EnvironmentHandler)tempB.getBean()).setEnvironment(m_env);
  314. }
  315. }
  316. int numFlows = 1;
  317. if (m_log != null) {
  318. if (m_startSequentially) {
  319. m_log.logMessage(Messages.getInstance().getString("FlowRunner_Run_LogMessage_Text_First"));
  320. } else {
  321. m_log.logMessage(Messages.getInstance().getString("FlowRunner_Run_LogMessage_Text_Second"));
  322. }
  323. }
  324. TreeMap<Integer, Startable> startables = new TreeMap<Integer, Startable>();
  325. // look for a Startable bean...
  326. for (int i = 0; i < m_beans.size(); i++) {
  327. BeanInstance tempB = (BeanInstance)m_beans.elementAt(i);
  328. if (tempB.getBean() instanceof Startable) {
  329. Startable s = (Startable)tempB.getBean();
  330. // start that sucker (if it's happy to be started)...
  331. if (!m_startSequentially) {
  332. if (s.getStartMessage().charAt(0) != '$') {
  333. if (m_log != null) {
  334. m_log.logMessage(Messages.getInstance().getString("FlowRunner_Run_LogMessage_Text_Third") + numFlows + Messages.getInstance().getString("FlowRunner_Run_LogMessage_Text_Fourth"));
  335. } else {
  336. System.out.println(Messages.getInstance().getString("FlowRunner_Run_Text_First") + numFlows + Messages.getInstance().getString("FlowRunner_Run_Text_Second"));
  337. }
  338. launchThread(s, numFlows);
  339. numFlows++;
  340. } else {
  341. String beanName = s.getClass().getName();
  342. if (s instanceof BeanCommon) {
  343. String customName = ((BeanCommon)s).getCustomName();
  344. beanName = customName;
  345. }
  346. if (m_log != null) {
  347. m_log.logMessage(Messages.getInstance().getString("FlowRunner_Run_LogMessage_Text_Fifth") + beanName + Messages.getInstance().getString("FlowRunner_Run_LogMessage_Text_Sixth"));
  348. } else {
  349. System.out.println(Messages.getInstance().getString("FlowRunner_Run_Text_Third") + beanName + Messages.getInstance().getString("FlowRunner_Run_Text_Fourth"));
  350. }
  351. }
  352. } else {
  353. boolean ok = false;
  354. Integer position = null;
  355. String beanName = s.getClass().getName();
  356. if (s instanceof BeanCommon) {
  357. String customName = ((BeanCommon)s).getCustomName();
  358. beanName = customName;
  359. // see if we have a parseable integer at the start of the name
  360. if (customName.indexOf(':') > 0) {
  361. String startPos = customName.substring(0, customName.indexOf(':'));
  362. try {
  363. position = new Integer(startPos);
  364. ok = true;
  365. } catch (NumberFormatException n) {
  366. }
  367. }
  368. }
  369. if (!ok) {
  370. if (startables.size() == 0) {
  371. position = new Integer(0);
  372. } else {
  373. int newPos = startables.lastKey().intValue();
  374. newPos++;
  375. position = new Integer(newPos);
  376. }
  377. }
  378. if (s.getStartMessage().charAt(0) != '$') {
  379. if (m_log != null) {
  380. m_log.logMessage(Messages.getInstance().getString("FlowRunner_Run_LogMessage_Text_Seventh") + beanName
  381. + Messages.getInstance().getString("FlowRunner_Run_LogMessage_Text_Eighth") + position
  382. + Messages.getInstance().getString("FlowRunner_Run_LogMessage_Text_Nineth"));
  383. } else {
  384. System.out.println(Messages.getInstance().getString("FlowRunner_Run_Text_Fifth") + beanName
  385. + Messages.getInstance().getString("FlowRunner_Run_Text_Sixth") + position + Messages.getInstance().getString("FlowRunner_Run_Text_Seventh"));
  386. }
  387. startables.put(position, s);
  388. } else {
  389. if (m_log != null) {
  390. m_log.logMessage(Messages.getInstance().getString("FlowRunner_Run_LogMessage_Text_Tenth") + beanName + Messages.getInstance().getString("FlowRunner_Run_LogMessage_Text_Eleventh"));
  391. } else {
  392. System.out.println(Messages.getInstance().getString("FlowRunner_Run_Text_Eighth") + beanName + Messages.getInstance().getString("FlowRunner_Run_Text_Nineth"));
  393. }
  394. }
  395. }
  396. }
  397. }
  398. if (m_startSequentially) {
  399. runSequentially(startables);
  400. }
  401. }
  402. /**
  403. * Main method for testing this class. <p>
  404. * <br>Usage:<br><br>
  405. * <pre>Usage:\n\nFlowRunner <serialized kf file></pre>
  406. *
  407. * @param args command line arguments
  408. */
  409. public static void main(String[] args) {
  410. weka.core.logging.Logger.log(weka.core.logging.Logger.Level.INFO, Messages.getInstance().getString("FlowRunner_Main_Logger_Text"));
  411. if (args.length < 1) {
  412. System.err.println(Messages.getInstance().getString("FlowRunner_Main_Error_Text"));
  413. } else {
  414. try {
  415. FlowRunner fr = new FlowRunner();
  416. FlowRunner.SimpleLogger sl = new FlowRunner.SimpleLogger();
  417. String fileName = args[0];
  418. if (args.length == 2 && args[1].equals("-s")) {
  419. fr.setStartSequentially(true);
  420. }
  421. // start with the system-wide vars
  422. Environment env = Environment.getSystemWide();
  423. fr.setLog(sl);
  424. fr.setEnvironment(env);
  425. fr.load(fileName);
  426. fr.run();
  427. fr.waitUntilFinished();
  428. System.out.println(Messages.getInstance().getString("FlowRunner_Main_Text"));
  429. System.exit(1);
  430. } catch (Exception ex) {
  431. ex.printStackTrace();
  432. System.err.println(ex.getMessage());
  433. }
  434. }
  435. }
  436. public String getRevision() {
  437. return "$Revision: 7059 $";
  438. }
  439. }