001: /**************************************************************************************
002: * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved. *
003: * http://aspectwerkz.codehaus.org *
004: * ---------------------------------------------------------------------------------- *
005: * The software in this package is published under the terms of the LGPL license *
006: * a copy of which has been included with this distribution in the license.txt file. *
007: **************************************************************************************/package org.codehaus.aspectwerkz.hook;
008:
009: import java.util.ArrayList;
010: import java.util.Collections;
011: import java.util.Comparator;
012: import java.util.HashMap;
013: import java.util.Iterator;
014: import java.util.List;
015: import java.util.Map;
016: import java.util.StringTokenizer;
017:
018: /**
019: * Starts a target process adding JDWP option to have a listening connector and be in suspend mode <p/>Target process is
020: * launched using <i>$JAVA_HOME/bin/java [opt] [main] </i> <br/>and [opt] is patched to use <i>-Xdebug
021: * -Xrunjdwp:transport=..,address=..,server=y,suspend=y </i> <br/>
022: *
023: * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
024: */
025: public class JDWPStarter extends AbstractStarter {
026: private String transport;
027:
028: private String address;
029:
030: public JDWPStarter(String opt, String main, String transport,
031: String address) {
032: super (opt, main);
033: Map jdwpOpt = parseJdwp();
034: if (jdwpOpt.containsKey("transport")) {
035: this .transport = (String) jdwpOpt.get("transport");
036: } else {
037: this .transport = transport;
038: jdwpOpt.put("transport", this .transport);
039: }
040: if (jdwpOpt.containsKey("address")) {
041: this .address = (String) jdwpOpt.get("address");
042: } else {
043: this .address = address;
044: jdwpOpt.put("address", this .address);
045: }
046: patchOptions(jdwpOpt);
047: }
048:
049: public String getTransport() {
050: return transport;
051: }
052:
053: public String getAddress() {
054: return address;
055: }
056:
057: /**
058: * Patch JDWP options if any to include necessary information Preserve JDWP options excepted server and suspend.
059: * <br/>If transport and address are already specified it uses them.
060: */
061: private void patchOptions(Map jdwpOpt) {
062: if (opt.indexOf("-Xdebug") < 0) {
063: opt = "-Xdebug " + opt;
064: }
065: jdwpOpt.put("server", "y");
066: jdwpOpt.put("suspend", "y");
067: StringBuffer jdwp = new StringBuffer("-Xrunjdwp:");
068: List keys = new ArrayList(jdwpOpt.keySet());
069:
070: // JDWP options should start with transport=..,address=..
071: // or it fails strangely
072: //Collections.reverse(keys);
073: keys = jdwpOptionSort(keys);
074: for (Iterator i = keys.iterator(); i.hasNext();) {
075: String key = (String) i.next();
076: jdwp.append(key).append("=").append(
077: (String) jdwpOpt.get(key));
078: if (i.hasNext()) {
079: jdwp.append(",");
080: }
081: }
082: if (opt.indexOf("-Xrunjdwp:") < 0) {
083: opt = jdwp + " " + opt;
084: } else {
085: int from = opt.indexOf("-Xrunjdwp:");
086: int to = Math.min(opt.length(), opt.indexOf(' ', from));
087: StringBuffer newOpt = new StringBuffer("");
088: if (from > 0) {
089: newOpt.append(opt.substring(0, from));
090: }
091: newOpt.append(" ").append(jdwp);
092: if (to < opt.length()) {
093: newOpt.append(" ").append(
094: opt.substring(to, opt.length()));
095: }
096: opt = newOpt.toString();
097: }
098: }
099:
100: /**
101: * return a Map(String=>String) of JDWP options
102: */
103: private Map parseJdwp() {
104: if (opt.indexOf("-Xrunjdwp:") < 0) {
105: return new HashMap();
106: }
107: String jdwp = opt.substring(opt.indexOf("-Xrunjdwp:")
108: + "-Xrunjdwp:".length(), Math.min(opt.length(), opt
109: .indexOf(' ', opt.indexOf("-Xrunjdwp:"))));
110: HashMap jdwpOpt = new HashMap();
111: StringTokenizer stz = new StringTokenizer(jdwp, ",");
112: while (stz.hasMoreTokens()) {
113: String jdwpo = stz.nextToken();
114: if (jdwpo.indexOf('=') < 0) {
115: System.err.println("WARN - unrecognized JDWP option: "
116: + jdwpo);
117: continue;
118: }
119: jdwpOpt.put(jdwpo.substring(0, jdwpo.indexOf('=')), jdwpo
120: .substring(jdwpo.indexOf('=') + 1));
121: }
122: return jdwpOpt;
123: }
124:
125: /**
126: * Sort list of String for "transport" to be in first position
127: */
128: private List jdwpOptionSort(List opt) {
129: Comparator c = new Comparator() {
130: public int compare(Object o1, Object o2) {
131: if (o1 instanceof String && o2 instanceof String) {
132: if ("transport".equals((String) o1)) {
133: return -1000;
134: }
135: if ("transport".equals((String) o2)) {
136: return 1000;
137: }
138: return 0;
139: }
140: return 0;
141: }
142: };
143: Collections.sort(opt, c);
144: return opt;
145: }
146: }
|