001: package de.ixdb.squirrel_sql.plugins.cache;
002:
003: import com.intersys.cache.CacheObject;
004: import com.intersys.cache.Dataholder;
005: import com.intersys.cache.jbind.JBindDatabase;
006: import com.intersys.classes.CharacterStream;
007: import com.intersys.objects.*;
008: import net.sourceforge.squirrel_sql.client.session.ISession;
009:
010: import java.io.BufferedReader;
011: import java.sql.Connection;
012: import java.sql.ResultSet;
013: import java.sql.SQLException;
014: import java.sql.Statement;
015: import java.util.Hashtable;
016: import java.util.Vector;
017: import java.util.regex.Matcher;
018: import java.util.regex.Pattern;
019:
020: public class ShowProcessesCommand {
021: private ISession _session;
022: private ProcessListTab _processListTab;
023:
024: public ShowProcessesCommand(ISession session) {
025: _session = session;
026: }
027:
028: public void execute() {
029: try {
030: ProcessData[] procData = getProcessesFromCache(_session);
031:
032: ProcessListTabListener ptl = new ProcessListTabListener() {
033: public ProcessData[] refreshRequested(ISession session) {
034: return onRefreshRequested(session);
035: }
036:
037: public int terminateRequested(ISession session,
038: ProcessData processData) {
039: return onTerminateRequested(session, processData);
040: }
041:
042: public void closeRequested(ISession session) {
043: _session.getSessionSheet().removeMainTab(
044: _processListTab);
045: }
046: };
047:
048: _processListTab = new ProcessListTab(procData, ptl);
049: int index = _session.getSessionSheet().addMainTab(
050: _processListTab);
051: _session.getSessionSheet().selectMainTab(index);
052:
053: } catch (Exception ex) {
054: throw new RuntimeException(ex);
055: }
056: }
057:
058: private int onTerminateRequested(ISession session,
059: ProcessData processData) {
060: try {
061: Database conn = (JBindDatabase) CacheDatabase
062: .getDatabase(session.getSQLConnection()
063: .getConnection());
064:
065: Id id = new Id(processData.pid);
066: com.intersys.classes.SYSTEM.Process proc = (com.intersys.classes.SYSTEM.Process) com.intersys.classes.SYSTEM.Process
067: ._open(conn, id);
068: Dataholder dataholder = proc.terminate();
069: return dataholder.getIntValue();
070: } catch (Exception e) {
071: throw new RuntimeException(e);
072: }
073: }
074:
075: private ProcessData[] onRefreshRequested(ISession session) {
076: try {
077: return getProcessesFromCache(session);
078: } catch (Exception e) {
079: throw new RuntimeException(e);
080: }
081: }
082:
083: private ProcessData[] getProcessesFromCache(ISession session)
084: throws CacheException, SQLException {
085: Database conn = (JBindDatabase) CacheDatabase
086: .getDatabase(session.getSQLConnection().getConnection());
087: CacheQuery qryNamespaces = new CacheQuery(conn,
088: "%SYSTEM.Process", "CONTROLPANEL");
089: ResultSet procList = qryNamespaces
090: .execute(new Object[] { "*" });
091:
092: Vector procData = new Vector();
093: while (procList.next()) {
094: procData.add(new ProcessData(procList));
095: }
096:
097: ProcessData[] ret = (ProcessData[]) procData
098: .toArray(new ProcessData[procData.size()]);
099:
100: fillLocks(ret);
101:
102: fillBlocksAndDeadLocks(ret);
103:
104: return ret;
105:
106: }
107:
108: private void fillBlocksAndDeadLocks(ProcessData[] procData) {
109:
110: for (int i = 0; i < procData.length; i++) {
111: procData[i].fillBlocks(procData);
112: }
113:
114: for (int i = 0; i < procData.length; i++) {
115: procData[i].fillDeadLockChain();
116: }
117:
118: }
119:
120: private void fillLocks(ProcessData[] procData) {
121: try {
122: Dataholder[] argv = new Dataholder[0];
123:
124: Connection con = _session.getSQLConnection()
125: .getConnection();
126: Database database = (JBindDatabase) CacheDatabase
127: .getDatabase(con);
128:
129: Dataholder res = null;
130: try {
131: res = database.runClassMethod("CM.methM1", "M1", argv,
132: Database.RET_OBJECT);
133: } catch (CacheException e) {
134: Statement stat = con.createStatement();
135: stat
136: .executeUpdate(
137:
138: "CREATE METHOD CM.M1()"
139: + " RETURNS %GlobalCharacterStream"
140: + " LANGUAGE COS"
141: + " {"
142: + " SET outStream = ##class(%GlobalCharacterStream).%New()"
143: + " SET c=\"\""
144: + " DO list^%Wslocks(,.d,.c)"
145: + " SET lockCount=$Length(d,$$del1^%Wprim)"
146: + " FOR index=1:1:lockCount-1 {"
147: + " DO outStream.WriteLine($PIECE(d,$$del1^%Wprim,index))"
148: + " }" + " quit outStream"
149: + " }");
150: stat.close();
151:
152: res = database.runClassMethod("CM.methM1", "M1", argv,
153: Database.RET_OBJECT);
154: }
155:
156: CacheObject cobj = res.getCacheObject();
157: if (cobj == null) {
158: System.out.println("null");
159: }
160: CharacterStream cs = (CharacterStream) (cobj
161: .newJavaInstance());
162: BufferedReader br = new BufferedReader(cs.getReader());
163: String line = br.readLine();
164:
165: Pattern patJobNr = Pattern
166: .compile("([\\x01\\x13\\^]+)(\\d+)([\\x01\\x13\\^]+)");
167: Pattern pat = Pattern.compile("[\\x01\\x13\\^]+");
168:
169: Hashtable locksByProcID = new Hashtable();
170:
171: int len = 0;
172:
173: while (null != line) {
174: len += line.length();
175:
176: Matcher matJobNr = patJobNr.matcher(line);
177: Matcher mat = pat.matcher(line);
178:
179: if (matJobNr.find()) {
180: Integer pid = new Integer(matJobNr.group(matJobNr
181: .groupCount() - 1));
182: LockData lockData = (LockData) locksByProcID
183: .get(pid);
184: if (null == lockData) {
185: lockData = new LockData();
186: locksByProcID.put(pid, lockData);
187: lockData.locks.append(mat.replaceAll(" "));
188: ++lockData.lockCount;
189: } else {
190: lockData.locks.append('\n').append(
191: mat.replaceAll(" "));
192: ++lockData.lockCount;
193: }
194: }
195:
196: line = br.readLine();
197: }
198:
199: if (27500 < len) {
200: String msg = "Too many locks! "
201: + "The process list does probably not show all existing locks. "
202: + "Deadlock and blocking information might be incomplete too.";
203: _session.showErrorMessage(msg);
204: }
205:
206: System.out.println("len = " + len);
207:
208: for (int i = 0; i < procData.length; i++) {
209: LockData lockData = (LockData) locksByProcID
210: .get(new Integer(procData[i].pid));
211:
212: if (null != lockData) {
213: procData[i].locks = lockData.locks.toString();
214: procData[i].lockCount = lockData.lockCount;
215: }
216:
217: }
218:
219: } catch (Exception e) {
220: throw new RuntimeException(e);
221: }
222: }
223:
224: public void setSession(ISession session) {
225: _session = session;
226: }
227:
228: private static class LockData {
229: StringBuffer locks = new StringBuffer();
230: int lockCount = 0;
231: }
232:
233: }
|