001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.j2me.cdc.project.nokiaS80;
043:
044: // IMPORTANT! You need to compile this class against ant.jar. So add the
045: // JAR ide5/ant/lib/ant.jar from your IDE installation directory (or any
046: // other version of Ant you wish to use) to your classpath. Or if
047: // writing your own build target, use e.g.:
048: // <classpath>
049: // <pathelement location="${ant.home}/lib/ant.jar"/>
050: // </classpath>
051:
052: import java.io.BufferedReader;
053: import java.io.File;
054: import java.io.IOException;
055: import java.io.InputStream;
056: import java.io.InputStreamReader;
057: import java.io.PrintWriter;
058: import java.net.Socket;
059: import java.util.ArrayList;
060: import java.util.Iterator;
061: import java.util.LinkedList;
062: import java.util.List;
063: import java.util.StringTokenizer;
064: import org.apache.tools.ant.*;
065: import org.apache.tools.ant.types.*;
066:
067: /**
068: * @author suchys
069: */
070: public class NokiaEmulatorExecTask extends Task {
071:
072: private List filesets = new LinkedList(); // List<FileSet>
073: private File home;
074: private String mainclass;
075: private String args;
076: private String jvmargs;
077: private String device;
078: private boolean xlet;
079: private boolean applet;
080: //for debugger
081: private String debuggerAddressProperty;
082: private boolean debug;
083: //out stream
084: protected PrintWriter fos = null;
085:
086: public void addFileset(FileSet fs) {
087: filesets.add(fs);
088: }
089:
090: public void execute() throws BuildException {
091: //TODO Nokia does not support Xlet and applet
092: if (xlet)
093: throw new BuildException(
094: "Xlet execution is not supported for Nokia target.");
095: if (applet)
096: throw new BuildException(
097: "Applet execution is not supported for Nokia target.");
098:
099: List arguments = new ArrayList();
100: arguments.add(home + File.separator + "bin" + File.separator
101: + "emulator.exe");
102: arguments.add("-classpath");
103: arguments.add(createPath());
104: arguments.add("-Xdevice:" + device);
105: StringTokenizer st = new StringTokenizer(jvmargs, " ");
106: while (st.hasMoreTokens())
107: arguments.add(st.nextToken());
108: if (debug) {
109: String debugAddress = null;
110: try {
111: debugAddress = Integer.toString(this
112: .determineFreePort());
113: } catch (IOException e) {
114: throw new BuildException(e);
115: }
116: arguments.add("-Xrunjdwp:server=y,suspend=y,address="
117: + debugAddress);
118: if (debuggerAddressProperty != null) {
119: this .getProject().setProperty(debuggerAddressProperty,
120: debugAddress);
121: }
122: }
123: if (!xlet && !applet) {
124: arguments.add(mainclass);
125: appendArguments(arguments);
126: }
127: if (xlet && !applet) {
128: arguments.add("com.ibm.oti.xlet.XletApplicationManager");
129: StringTokenizer xlets = new StringTokenizer(mainclass, ";");
130: while (xlets.hasMoreElements()) {
131: arguments.add("-name:" + xlets.nextElement());
132: arguments.add("-path:" + createPath());
133: if (args != null && args.length() != 0) {
134: arguments.add("-args:" + args);
135: }
136: }
137: }
138: String[] arg = (String[]) arguments.toArray(new String[0]);
139: getProject().log("Application arguments:", Project.MSG_VERBOSE);
140: for (int i = 0; i < arg.length; i++)
141: getProject().log("'" + arg[i] + "'", Project.MSG_VERBOSE);
142: Process p = null;
143: try {
144: p = Runtime.getRuntime().exec(arg);
145: StreamReader inputReader = new StreamReader(p
146: .getInputStream(), Project.MSG_INFO);
147: StreamReader errorReader = new StreamReader(p
148: .getErrorStream(), Project.MSG_WARN);
149:
150: // starts pumping away the generated output/error
151: inputReader.start();
152: errorReader.start();
153:
154: // Wait for everything to finish
155: p.waitFor();
156: inputReader.join();
157: errorReader.join();
158: p.destroy();
159:
160: // close the output file if required
161: logFlush();
162:
163: if (p.exitValue() != 0)
164: throw new BuildException("Emulator execution failed!");
165: } catch (IOException ex) {
166: throw new BuildException("Emulator execution failed!");
167: } catch (InterruptedException ex) {
168: throw new BuildException("Emulator execution failed!");
169: }
170: }
171:
172: private String createPath() {
173: Iterator it = filesets.iterator();
174: StringBuffer sb = new StringBuffer();
175: while (it.hasNext()) {
176: FileSet fs = (FileSet) it.next();
177: DirectoryScanner ds = fs.getDirectoryScanner(project);
178: File basedir = ds.getBasedir();
179: String[] files = ds.getIncludedFiles();
180: for (int i = 0; i < files.length; i++) {
181: sb.append("\"" + basedir.getAbsolutePath()
182: + File.separatorChar + files[i] + "\"");
183: if (i + 1 < files.length) {
184: sb.append(";");
185: }
186: }
187: }
188: return sb.toString();
189: }
190:
191: private void appendArguments(List args) {
192: if (this .args == null || this .args.length() == 0)
193: return;
194: StringTokenizer st = new StringTokenizer(this .args, " ");
195: while (st.hasMoreTokens()) {
196: //args.add("-D" + st.nextToken());
197: args.add(st.nextToken());
198: }
199: }
200:
201: /**
202: * Finds a free port to be used for listening for debugger connection.
203: * @return free port number
204: * @throws IOException
205: */
206: private int determineFreePort() throws IOException {
207: Socket sock = new Socket();
208: sock.bind(null);
209: int port = sock.getLocalPort();
210: sock.close();
211: return port;
212: }
213:
214: private void outputLog(String line, int messageLevel) {
215: if (fos == null) {
216: log(line, messageLevel);
217: } else {
218: fos.println(line);
219: }
220: }
221:
222: private void logFlush() {
223: if (fos != null) {
224: fos.close();
225: }
226: }
227:
228: public File getHome() {
229: return home;
230: }
231:
232: public void setHome(File home) {
233: this .home = home;
234: }
235:
236: public String getMainclass() {
237: return mainclass;
238: }
239:
240: public void setMainclass(String mainclass) {
241: this .mainclass = mainclass;
242: }
243:
244: public String getArgs() {
245: return args;
246: }
247:
248: public void setArgs(String args) {
249: this .args = args;
250: }
251:
252: public String getJvmargs() {
253: return jvmargs;
254: }
255:
256: public void setJvmargs(String jvmargs) {
257: this .jvmargs = jvmargs;
258: }
259:
260: public String getDevice() {
261: return device;
262: }
263:
264: public void setDevice(String device) {
265: this .device = device;
266: }
267:
268: public boolean isXlet() {
269: return xlet;
270: }
271:
272: public void setXlet(boolean xlet) {
273: this .xlet = xlet;
274: }
275:
276: public boolean isApplet() {
277: return applet;
278: }
279:
280: public void setApplet(boolean applet) {
281: this .applet = applet;
282: }
283:
284: public String getDebuggerAddressProperty() {
285: return debuggerAddressProperty;
286: }
287:
288: public void setDebuggerAddressProperty(
289: String debuggerAddressProperty) {
290: this .debuggerAddressProperty = debuggerAddressProperty;
291: }
292:
293: public boolean isDebug() {
294: return debug;
295: }
296:
297: public void setDebug(boolean debug) {
298: this .debug = debug;
299: }
300:
301: class StreamReader extends Thread {
302: private BufferedReader din;
303: private int messageLevel;
304: private boolean endOfStream = false;
305: private int SLEEP_TIME = 5;
306:
307: public StreamReader(InputStream is, int messageLevel) {
308: this .din = new BufferedReader(new InputStreamReader(is));
309: this .messageLevel = messageLevel;
310: }
311:
312: public void pumpStream() throws IOException {
313: if (!endOfStream) {
314: String line = din.readLine();
315:
316: if (line != null) {
317: outputLog(line, messageLevel);
318: } else {
319: endOfStream = true;
320: }
321: }
322: }
323:
324: public void run() {
325: try {
326: try {
327: while (!endOfStream) {
328: pumpStream();
329: sleep(SLEEP_TIME);
330: }
331: } catch (InterruptedException ie) {
332: }
333: din.close();
334: } catch (IOException ioe) {
335: }
336: }
337: }
338: }
|