1 package org.splat.launcher;
4 import java.awt.ComponentOrientation;
5 import java.awt.GridLayout;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8 import java.io.BufferedReader;
10 import java.io.IOException;
11 import java.io.InputStreamReader;
12 import java.io.ObjectInputStream;
13 import java.io.UnsupportedEncodingException;
14 import java.net.MalformedURLException;
16 import java.net.URLConnection;
17 import java.net.URLEncoder;
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.List;
23 * Applet providing a set of buttons. Each button is defined by three parameters:<BR>
25 * <li><i>icon<i></i></li>
26 * <li><i>tool<i></i></li>
27 * <li><i>file<i></i></li> - may be null
29 * where i is an index beginning from zero.
31 public class ToolbarApplet extends java.applet.Applet implements ActionListener {
34 * Serialization version id.
36 private static final long serialVersionUID = 3243053622061086715L;
39 * The name of the script to run Salome.
41 private static final String RUN_SALOME_SCRIPT = "run_salome_siman";
43 * Possible script extensions.
45 private static final String[] SCRIPT_EXT = { "", ".sh", ".bat", ".cmd" };
47 * The response key string: '<i>"canCheckout"</i> :'.
49 public static final String CHECKOUT_RES = "\"canCheckout\" :";
51 // ==============================================================================================================================
52 // Overridden functions
53 // ==============================================================================================================================
58 * @see java.applet.Applet#init()
62 URL appurl = getCodeBase();
63 int hgap = 6; // Gap between icons
66 int width = getSize().width;
67 int height = getSize().height;
68 for (ntools = 0; ntools < (width + hgap) / (height + hgap); ntools++) {
69 String icon = this.getParameter("icon" + ntools);
70 String tool = this.getParameter("tool" + ntools);
71 String file = this.getParameter("file" + ntools); // May be null
72 if (icon != null && tool != null) {
73 ToolButton button = new ToolButton(height, getImage(appurl,
74 "../skin/" + icon), tool, file);
75 add(button); // For displaying the button
76 button.addActionListener(this);
79 setLayout(new GridLayout(1, ntools, hgap, 0)); // 1 row, {ntools} buttons
80 setBackground(Color.decode("#D2E7FF"));
81 applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
87 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
89 public void actionPerformed(final ActionEvent event) {
90 if (event.getSource() instanceof ToolButton) {
91 ToolButton clicked = (ToolButton) event.getSource();
92 String module = clicked.getTool();
93 String target = clicked.getTarget();
94 launch(module, target);
98 // ==============================================================================================================================
99 // Public member functions
100 // ==============================================================================================================================
103 * Launch an appropriate application for the given file.
110 public void launch(final String name, final String filename) {
111 String module = name;
114 // Opening a Web page in a new tab
115 if (module.startsWith("http")) {
116 getAppletContext().showDocument(new URL(module), "_blank");
119 // Opening a Web module in a new tab
120 if (module.startsWith("../") || module.startsWith("/")) {
121 module = getCodeBase().toString() + module;
122 if (filename != null) {
123 module = module + "?open=" + filename;
125 getAppletContext().showDocument(new URL(module), "_blank");
128 // Opening an application on the local machine
130 if ("runSalome".equals(module)) {
131 salomeCheckout(filename);
134 if (module.endsWith(".exe") || module.endsWith(".EXE")) {
135 String applikey = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Applications\\"
137 String valkey = ""; // Default application and file keys
139 module = WindowsRegistry.readValue(applikey
140 + "\\shell\\open\\command", valkey);
141 if (module == null) {
142 module = WindowsRegistry.readValue(applikey
143 + "\\shell\\edit\\command", valkey);
145 // if (module == null) module = "\"C:\\Program Files (x86)\\Microsoft Office\\Office14\\WINWORD.EXE\"";
146 if (module == null) {
147 module = getCodeBase().toString()
148 + "error.jsp?message=launch&value=" + name;
149 getAppletContext().showDocument(new URL(module));
151 String[] parse = module.split("/");
152 String command = parse[0]; // Removing eventual options
153 if (filename != null) {
155 // Opening the application with a server side existing file
156 if (filename.startsWith("http")) {
157 path = " \"" + filename + "\"";
159 // Opening the application with a file previously created by the server
160 else if (filename.startsWith("/jsp")) { // Document created through a JSP
161 URL my = getDocumentBase();
162 String http = "http://" + my.getHost() + ":"
163 + my.getPort() + "/";
164 String[] jsppath = my.getPath().split("/"); // Parses "/webapp/..."
165 String location = http + jsppath[1] + filename;
167 URLConnection connection = new URL(location)
169 ObjectInputStream fromservlet = new ObjectInputStream(
170 connection.getInputStream());
171 URL docurl = (URL) fromservlet.readObject();
174 if (docurl != null) {
175 path = " " + docurl.toString();
178 command = command + path;
180 Runtime.getRuntime().exec(command);
183 } catch (Exception error) {
184 error.printStackTrace(); // RKV: NOPMD: Applet output
189 * The class that reads output of the process passed in constructor in a separate thread.
190 * (a quick fix to the problem that we need to read bash script
191 * output in order for it to proceed correctly).
193 class ScriptOutputReader implements Runnable {
196 * A quick fix to the problem that we need to read bash script output in order for it to proceed correctly.
201 * Constructor from process to take output from.
203 * the process to read from.
205 public ScriptOutputReader(final Process proc) {
211 * @see java.lang.Runnable#run()
216 BufferedReader bri = new BufferedReader(new InputStreamReader(
217 _proc.getInputStream()));
218 BufferedReader bre = new BufferedReader(new InputStreamReader(
219 _proc.getErrorStream()));
220 String line = bri.readLine();
221 while (line != null) {
222 System.out.println(line); // RKV: NOPMD: Applet output
223 line = bri.readLine();
226 line = bre.readLine();
227 while (line != null) {
228 System.err.println(line); // RKV: NOPMD: Applet output
229 line = bre.readLine();
232 } catch(Exception e) {
233 // NOPMD: empty catch block - nothing really to do here.
239 * Checkout a scenario and start Salome with it.
243 * @throws IOException
244 * if URL connection opening/reading is failed
245 * @throws ConfigurationException
246 * if SALOME_ROOT_DIR environment variable is not defined or Salome launcher script is not found
248 private void salomeCheckout(final String params)
249 throws ConfigurationException, IOException {
251 // To get the SALOME_HOME environment variable
252 String SALOME_HOME = System.getenv("SALOME_ROOT_DIR");
253 // If SALOME_ROOT_DIR does not exist the SALOME_HOME equals to null.
254 if (SALOME_HOME == null) {
255 showError("SALOME_ROOT_DIR environment variable is not defined.");
256 throw new ConfigurationException(
257 "SALOME_ROOT_DIR nevironment variable is not defined.");
258 } else if (!SALOME_HOME.endsWith(File.separator)) {
259 SALOME_HOME += File.separator;
261 String pathToScript = SALOME_HOME + File.separator + RUN_SALOME_SCRIPT;
262 File script = new File(pathToScript);
263 String extensions = "";
264 // Look for the launching script in the file system
265 for (String ext : SCRIPT_EXT) {
266 script = new File(pathToScript + ext); // RKV: NOPMD: There are not so much extensions
267 if (script.exists()) {
270 extensions += "|" + ext;
273 if (script.exists()) {
275 // Call to the Siman server to checkout the scenario
276 URL checkoutUrl = new URL(getCodeBase().toString()
278 + params.replaceAll("--siman-", "&").replaceAll("\\s", ""));
280 BufferedReader buffer = new BufferedReader(new InputStreamReader(
281 checkoutUrl.openStream()));
283 // Read the response of the Siman server
284 boolean isOk = false;
285 String response = buffer.readLine();
286 while ((response != null)) {
287 if (response.contains(CHECKOUT_RES)) {
288 isOk = response.contains(CHECKOUT_RES + " \"true\"");
291 response = buffer.readLine();
296 // Execute the runSalome script.
297 // filename here indeed a string containing parameters for runSalome.
298 List<String> cmd = new ArrayList<String>(Arrays.asList(params
300 cmd.add(0, script.getAbsolutePath());
301 Process proc = Runtime.getRuntime().exec(
302 cmd.toArray(new String[] {}), null,
303 new File(SALOME_HOME));
305 // Read script's output in separate thread.
306 ScriptOutputReader appletOutputReader = new ScriptOutputReader(proc);
307 Thread thread = new Thread(appletOutputReader);
310 // Checkout of the scenario is failed at the beginning.
311 if (response != null) {
312 response = response.substring(
313 response.indexOf(CHECKOUT_RES)
314 + CHECKOUT_RES.length()).replace('}', ' ')
320 // Refresh the current scenario view
321 getAppletContext().showDocument(
322 new URL(this.getParameter("refresh")));
324 extensions = "[" + extensions.replaceAll("\\|\\|", "") + "]";
325 showError("SALOME module is not found: " + pathToScript
327 throw new ConfigurationException("SALOME module is not found: "
328 + pathToScript + extensions);
333 * Show error message in the new window.
337 * @throws MalformedURLException
338 * if built URL is incorrect
339 * @throws UnsupportedEncodingException
340 * if UTF-8 encoding is not supported
342 private void showError(final String message) throws MalformedURLException,
343 UnsupportedEncodingException {
344 getAppletContext().showDocument(
345 new URL(getCodeBase().toString() + "../error.jsp?error="
346 + URLEncoder.encode(message, "UTF-8")), "_blank");