001/*
002 * Copyright (c) 2002-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: welker $'
006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 
007 * '$Revision: 24234 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.geon;
031
032import java.io.BufferedReader;
033import java.io.File;
034import java.io.FileWriter;
035import java.io.InputStreamReader;
036import java.io.Writer;
037import java.net.HttpURLConnection;
038import java.net.URL;
039import java.util.Vector;
040
041import org.kepler.configuration.ConfigurationManager;
042import org.kepler.configuration.ConfigurationProperty;
043
044import ptolemy.actor.TypedAtomicActor;
045import ptolemy.actor.TypedIOPort;
046import ptolemy.actor.gui.BrowserLauncher;
047import ptolemy.data.ArrayToken;
048import ptolemy.data.StringToken;
049import ptolemy.data.Token;
050import ptolemy.data.type.ArrayType;
051import ptolemy.data.type.BaseType;
052import ptolemy.gui.GraphicalMessageHandler;
053import ptolemy.kernel.CompositeEntity;
054import ptolemy.kernel.util.IllegalActionException;
055import ptolemy.kernel.util.NameDuplicationException;
056import util.UUIDGen;
057
058//////////////////////////////////////////////////////////////////////////
059//// FilterUI
060/**
061 * This actor displays its input on a browser window and allows the user to
062 * select and forward the desired selections to the output The input is accepted
063 * as an array of strings. The selected outputs are returned as an array of
064 * strings.
065 * 
066 * @author Efrat Jaeger
067 * @version $Id: FilterUI.java 24234 2010-05-06 05:21:26Z welker $
068 * @since Ptolemy II 4.0.1
069 */
070public class FilterUI extends TypedAtomicActor {
071
072        /**
073         * Construct an actor with the given container and name.
074         * 
075         * @param container
076         *            The container.
077         * @param name
078         *            The name of this actor.
079         * @exception IllegalActionException
080         *                If the actor cannot be contained by the proposed
081         *                container.
082         * @exception NameDuplicationException
083         *                If the container already has an actor with this name.
084         */
085        public FilterUI(CompositeEntity container, String name)
086                        throws IllegalActionException, NameDuplicationException {
087                super(container, name);
088
089                input = new TypedIOPort(this, "input", true, false);
090                input.setTypeEquals(new ArrayType(BaseType.STRING));
091
092                output = new TypedIOPort(this, "output", false, true);
093                output.setTypeEquals(new ArrayType(BaseType.STRING));
094
095        }
096
097        // /////////////////////////////////////////////////////////////////
098        // // ports and parameters ////
099
100        /**
101         * The input to be displayed for selection.
102         */
103        public TypedIOPort input;
104
105        /**
106         * The selected items.
107         */
108        public TypedIOPort output;
109
110        // /////////////////////////////////////////////////////////////////
111        // // public methods ////
112
113        /**
114         * Output the selected input data.
115         * 
116         * @exception IllegalActionException
117         *                If there's no director.
118         */
119
120        public void fire() throws IllegalActionException {
121
122                html = "";
123    ConfigurationManager confMan = ConfigurationManager.getInstance();
124    ConfigurationProperty commonProperty = confMan.getProperty(ConfigurationManager.getModule("common"));
125    ConfigurationProperty serversProperty = commonProperty.getProperty("servers.server");
126    ConfigurationProperty geonProperty = serversProperty.findProperties("name", "geon").get(0);
127    serverPath = geonProperty.getProperty("url").getValue();
128    
129    
130                Token[] inputTokens = ((ArrayToken) input.get(0)).arrayValue();
131                _createHTMLHeader();
132                _createHTMLBody(inputTokens);
133
134                String fileToShow = "";
135                File filterDisplay = null;
136                // write html str to tmpFile.
137                try {
138                        UUIDGen uuidgen = new UUIDGen();
139                        String fileName = uuidgen.generateUUID();
140                        filterDisplay = new File(fileName + ".html");
141
142                        Writer writer = new FileWriter(filterDisplay);
143                        writer.write(html);
144                        writer.close();
145
146                        fileToShow = filterDisplay.getAbsolutePath();
147                        BrowserLauncher.openURL(fileToShow);
148                } catch (Exception ex) {
149                        if (filterDisplay.exists()) {
150                                filterDisplay.delete();
151                        }
152                        GraphicalMessageHandler.error("Failed to display files to filter",
153                                        ex);
154                }
155
156                String fetchURL = serverPath + "pt2/jsp/ptf.jsp?ptid=" + procID;
157                System.out.println("fetchURL:  " + fetchURL + "\n");
158                try {
159                        URL url = new URL(fetchURL);
160                        while (true) {
161                                HttpURLConnection urlconn = (HttpURLConnection) url
162                                                .openConnection();
163                                urlconn.connect();
164                                Thread.sleep(5000);
165                                BufferedReader br = new BufferedReader(new InputStreamReader(
166                                                urlconn.getInputStream()));
167                                String line = br.readLine();
168                                String resp = "";
169                                while (line != null) {
170                                        System.out.println(line); // REMOVE!!!
171                                        resp += line + "\n";
172                                        line = br.readLine();
173                                }
174                                br.close();
175                                urlconn.disconnect();
176                                Vector outputVec = new Vector();
177                                if (resp.trim().toLowerCase().indexOf("<xmp>") != -1) {
178                                        while (!resp.trim().equals("</xmp>")) {
179                                                int indStart = resp.toLowerCase().indexOf("<name>");
180                                                int indEnd = resp.toLowerCase().indexOf("</name>");
181                                                String respLine = resp.substring(indStart + 6, indEnd);
182                                                String currentParamName = respLine;
183                                                String respRest = resp.substring(indEnd + 7);
184                                                resp = respRest;
185                                                indStart = resp.toLowerCase().indexOf("<value>");
186                                                indEnd = resp.toLowerCase().indexOf("</value>");
187                                                respLine = resp.substring(indStart + 7, indEnd);
188                                                String currentParamValue = respLine;
189                                                outputVec.add(new StringToken(currentParamValue));
190                                                respRest = resp.substring(indEnd + 8);
191                                                resp = respRest;
192                                        }
193                                        Token[] outputTokens = new Token[outputVec.size()];
194                                        outputVec.toArray(outputTokens);
195                                        output.broadcast(new ArrayToken(outputTokens));
196                                        break;
197                                }
198                        }
199                } catch (Exception e) {
200                        if (filterDisplay.exists()) {
201                                filterDisplay.delete();
202                        }
203                        GraphicalMessageHandler.error("url connection error. ", e);
204                }
205                filterDisplay.delete();
206        }
207
208        /**
209         * Post fire the actor. Return false to indicate that the process has
210         * finished. If it returns true, the process will continue indefinitely.
211         */
212        public boolean postfire() {
213                return true;
214        }
215
216        // /////////////////////////////////////////////////////////////////
217        // // private methods ////
218
219        /**
220         * Creates the html header and selection scripts.
221         */
222        private void _createHTMLBody(Token[] tokens) {
223
224                html += "<body>\n<form action=\"" + serverPath + "pt2/jsp/pts.jsp\"";
225                html += "method=\"post\" name=\"dataList\">\n<table border=\"1\">\n";
226                html += "<tr bgcolor=\"#9acd32\"> <th/><th align=\"center\">Data to filter</th></tr> \n";
227                for (int i = 0; i < tokens.length; i++) {
228                        String data = ((StringToken) tokens[i]).stringValue();
229                        html += "<tr><td><input onclick=\"Toggle(this)\" value=\"" + data;
230                        html += "\" name=\"" + i + "\" type=\"checkbox\"/></td>\n";
231                        html += "<td align=\"left\">" + data + "</td></tr>\n";
232                }
233                html += "</table>\n\n  <input value=\"filter\" type=\"submit\"/> \n";
234
235                // generate a process id.
236                UUIDGen uuidgen = new UUIDGen();
237                procID = uuidgen.generateUUID();
238
239                html += "<input type=\"hidden\" name=\"ptid\" value=\"" + procID
240                                + "\"/>\n";
241                html += "</form>\n</body>\n</html>";
242
243        }
244
245        /**
246         * Creates the html header and selection scripts.
247         */
248        private void _createHTMLHeader() {
249
250                html += "<html><head><title>Select data</title>\n";
251                html += "<script type=\"text/javascript\">\n\n";
252                html += "function Toggle(e) { \n  if (e.checked) { \n";
253                html += "document.dataList.toggleAll.checked = AllChecked(); \n  } \n";
254                html += "else { document.dataList.toggleAll.checked = false; } \n  } \n\n";
255                html += "function ToggleAll(e) { \n  if (e.checked) { \n  CheckAll(); \n  } \n";
256                html += "else { ClearAll(); } \n  } \n\n";
257                html += "function Check(e) { \n  e.checked = true; \n  } \n\n";
258                html += "function Clear(e) { \n  e.checked = false; \n  } \n\n";
259                html += "function CheckAll() { \n  var ml = document.dataList; \n";
260                html += "var len = ml.elements.length; \n  for (var i = 0; i &lt; len; i++) { \n";
261                html += "var e = ml.elements[i]; \n  Check(e); \n  } \n ";
262                html += "ml.toggleAll.checked = true; \n  } \n\n";
263                html += "function ClearAll() { \n  var ml = document.dataList; \n";
264                html += "var len = ml.elements.length; \n  for (var i = 0; i &lt; len; i++) { \n";
265                html += "var e = ml.elements[i]; \n  Clear(e); \n  } \n";
266                html += "ml.toggleAll.checked = false; \n  } \n\n";
267                html += "function AllChecked() { \n  var ml = document.dataList; \n";
268                html += "var len = ml.elements.length; \n  for(var i = 0 ; i &lt; len ; i++) { \n";
269                html += "if (ml.elements[i].name == \"data\" &amp;&amp; !ml.elements[i].checked) { \n";
270                html += "return false; \n  } \n  } \n  return true; \n  } \n\n";
271                html += "</script></head>\n\n";
272
273        }
274
275        // /////////////////////////////////////////////////////////////////
276        // // private members ////
277
278        /**
279         * holds the html content.
280         */
281        private String html = "";
282
283        private String procID;
284
285        /**
286         * Path to the geon server url in the config file.
287         */
288        private static final String SERVERPATH = "//servers/server[@name=\"geon\"]/url";
289
290        /**
291         * URL to backend server
292         */
293        private String serverPath = "";
294
295}