001: //
002: // This file is part of the prose package.
003: //
004: // The contents of this file are subject to the Mozilla Public License
005: // Version 1.1 (the "License"); you may not use this file except in
006: // compliance with the License. You may obtain a copy of the License at
007: // http://www.mozilla.org/MPL/
008: //
009: // Software distributed under the License is distributed on an "AS IS" basis,
010: // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
011: // for the specific language governing rights and limitations under the
012: // License.
013: //
014: // The Original Code is prose.
015: //
016: // The Initial Developer of the Original Code is Andrei Popovici. Portions
017: // created by Andrei Popovici are Copyright (C) 2002 Andrei Popovici.
018: // All Rights Reserved.
019: //
020: // Contributor(s):
021: /*
022: * WorksheetSingleClientModel.java
023: *
024: * Created on December 12, 2002, 10:06 AM
025: */
026:
027: package ch.ethz.prose.tools;
028:
029: import java.net.MalformedURLException;
030: import java.rmi.RemoteException;
031: import java.util.Arrays;
032: import java.util.Iterator;
033: import java.util.List;
034: import java.util.Vector;
035: import java.util.HashSet;
036:
037: import javax.swing.event.TableModelEvent;
038: import javax.swing.table.DefaultTableModel;
039:
040: import ch.ethz.prose.Aspect;
041: import ch.ethz.prose.query.QueryManager;
042: import ch.ethz.prose.query.JoinPointRequestSurrogate;
043: import ch.ethz.prose.query.AspectSurrogate;
044: import ch.ethz.prose.query.Tuple;
045:
046: /**
047: *
048: * @author pschoch
049: */
050: public class WorksheetSingleClientModel extends DefaultTableModel {
051:
052: private static final long serialVersionUID = 3257566222009905465L;
053:
054: public static final int BY_ASPECT = QueryManager.GROUP_BY_ASPECT;
055: public static final int BY_CROSSCUT = QueryManager.GROUP_BY_CROSSCUT;
056: public static final int BY_JOINPOINT = QueryManager.GROUP_BY_JOINPOINT;
057: public static final int SELECT_ASPECT = QueryManager.SELECT_ASPECT;
058: public static final int SELECT_CROSSCUT = QueryManager.SELECT_CROSSCUT;
059: public static final int SELECT_JOINPOINT = QueryManager.SELECT_JOINPOINT;
060: public static final int SELECT_ALL = QueryManager.SELECT_ALL;
061: private static final int NR_OF_ROWS = 40; // minimum number of rows displayed
062: private static Vector nullVector = new Vector();
063:
064: protected List table = new Vector(); // query result of prose
065: protected Vector data = new Vector(); // the query result in a form so it is readable for a swing table
066: protected int select = SELECT_ALL;
067: protected int groupBy = BY_ASPECT;
068: protected int[] selectedCells = null;
069: protected int selectedColumn = -1;
070: protected int[] pastedCells = null; // used for storing the cells that get colored
071: protected RemoteAspectManager exMngr;
072: protected String address;
073: protected boolean isReal;
074: protected MultipleClientModel parentModel;
075: protected String name;
076: protected String host;
077: protected String port;
078:
079: private boolean addedFlag = false; // so the extra empty cell at the bottom of the table is inserted only when required
080:
081: {
082: nullVector.add(null);
083: nullVector.add(null);
084: nullVector.add(null);
085: }
086:
087: private void checkIsConnected() throws IllegalUserInputException {
088: if (exMngr == null)
089: throw new IllegalUserInputException(
090: "Please select an active worksheet");
091: }
092:
093: /** Creates a new instance of WorksheetSingleClientModel */
094: public WorksheetSingleClientModel(MultipleClientModel ownerModel,
095: Object[][] initData, String[] initColumnNames, String name,
096: String host, String port, boolean isReal)
097:
098: {
099: super (initData, initColumnNames);
100: this .parentModel = ownerModel;
101: this .isReal = isReal;
102: this .host = host;
103: this .port = port;
104: this .address = host + ":" + port;
105: this .name = name;
106: selectedCells = new int[0];
107: int i = 0;
108: for (i = 0; i < initData.length; i++) {
109: Vector dataElement = new Vector();
110: dataElement.add(initData[i][1]);
111: dataElement.add(initData[i][2]);
112: dataElement.add(initData[i][3]);
113: }
114:
115: updateTable(data);
116: }
117:
118: public String getName() {
119: return name;
120: }
121:
122: public String getHost() {
123: return host;
124: }
125:
126: public String getPort() {
127: return port;
128: }
129:
130: public String getAddress() {
131: return address;
132: }
133:
134: public boolean isReal() {
135: return isReal;
136: }
137:
138: public void setDisplayAspect() {
139: select ^= SELECT_ASPECT;
140: }
141:
142: public void setDisplayCrosscut() {
143: select ^= SELECT_CROSSCUT;
144: }
145:
146: public void setDisplayJoinpoint() {
147: select ^= SELECT_JOINPOINT;
148: }
149:
150: public void setGroupByAspect() {
151: groupBy = BY_ASPECT;
152: }
153:
154: public void setGroupByCrosscut() {
155: groupBy = BY_CROSSCUT;
156: }
157:
158: public void setGroupByJoinpoint() {
159: groupBy = BY_JOINPOINT;
160: }
161:
162: public void setSelectedCells(int[] indices) {
163: selectedCells = indices;
164: }
165:
166: public int getSelectedColumn() {
167: return selectedColumn;
168: }
169:
170: public void setSelectedColumn(int ind) {
171: selectedColumn = ind;
172: }
173:
174: public boolean isCellEditable(int rowIndex, int columnIndex) {
175: return false;
176: }
177:
178: public synchronized void allAspects() throws RemoteException,
179: IllegalUserInputException {
180: checkIsConnected();
181: table = new Vector();
182: Iterator i = exMngr.allAspects().iterator();
183: while (i.hasNext()) {
184: table
185: .add(new Tuple((AspectSurrogate) i.next(), null,
186: null));
187: }
188: convertDataForGUI();
189: updateTable(data);
190: }
191:
192: // NOTE: it will be better to have a function in the Aspect Manager Interface e.g. 'getAllJoinpoints'
193: // that provides all joinpoints as JoinPointRequestSurrogate's. But this will not been implemented
194: // at the moment as discussed with Andrei. So it is choosed another way to come to a solution...
195: public synchronized void allJoinpoints() throws RemoteException,
196: IllegalUserInputException {
197: checkIsConnected();
198:
199: table = new Vector();
200: Iterator i = ((RemoteAspectManager) exMngr).allJoinpoints()
201: .iterator();
202: while (i.hasNext())
203: table.add(new Tuple(null, null,
204: (JoinPointRequestSurrogate) i.next()));
205: // table = exMngr.queryAspects(exMngr.getAllAspects(), SELECT_JOINPOINT, BY_JOINPOINT);
206: convertDataForGUI();
207: updateTable(data);
208: }
209:
210: public synchronized void query() throws RemoteException,
211: IllegalUserInputException {
212: checkIsConnected();
213: try {
214: if (selectedColumn == -1) {
215: throw new RuntimeException(
216: "BUG: multiple selection over columns not allowed");
217: }
218:
219: List inputList = new Vector();
220: if (selectedColumn == 0) {
221: for (int j = 0; j < selectedCells.length; j++)
222: inputList.add(((Tuple) table.get(selectedCells[j]))
223: .getAspectSurrogate());
224: table = exMngr.queryAspects(inputList, select, groupBy);
225: } else if (selectedColumn == 1) {
226: for (int j = 0; j < selectedCells.length; j++)
227: inputList.add(((Tuple) table.get(selectedCells[j]))
228: .getCrosscutSurrogate());
229: table = exMngr.queryCrosscuts(inputList, select,
230: groupBy);
231: } else if (selectedColumn == 2) {
232: for (int j = 0; j < selectedCells.length; j++)
233: inputList.add(((Tuple) table.get(selectedCells[j]))
234: .getRequestSurrogate());
235: table = exMngr.queryJoinpoints(inputList, select,
236: groupBy);
237: } else
238: throw new RuntimeException(
239: "Row selection failed! [rowNumber: "
240: + selectedColumn + "]");
241:
242: convertDataForGUI();
243: updateTable(data);
244: } catch (RemoteException e) {
245: throw e;
246: }
247: }
248:
249: public int getSelect() {
250: return select;
251: }
252:
253: public int getGroupBy() {
254: return groupBy;
255: }
256:
257: public boolean isMixedSelection() {
258: if (pastedCells == null)
259: return false;
260: int mixdex = 0;
261: for (int j = 0; j < selectedCells.length; j++)
262: if ((selectedCells[j] >= pastedCells[0])
263: && (selectedCells[j] <= pastedCells[pastedCells.length - 1]))
264: mixdex++;
265: else
266: mixdex--;
267: if (Math.abs(mixdex) != selectedCells.length)
268: return true;
269: else
270: return false;
271: }
272:
273: protected void pasteJoinpoints(List pasteList) {
274:
275: int pastedCellsTmp[];
276: if (pastedCells == null)
277: pastedCellsTmp = new int[pasteList.size()];
278: else {
279: pastedCellsTmp = new int[pasteList.size()
280: + pastedCells.length];
281: for (int i = 0; i < pastedCells.length; i++)
282: pastedCellsTmp[i] = pastedCells[i];
283: }
284:
285: int basicIndex = table.size();
286: for (int i = 0; i < pasteList.size(); i++) {
287: Vector dataElement = new Vector();
288: dataElement.add(null);
289: dataElement.add(null);
290: dataElement.add(pasteList.get(i));
291: if (basicIndex + i == data.size() - 1) {
292: addedFlag = true;
293: data.set(basicIndex + i, dataElement);
294: } else if (basicIndex + i > data.size() - 1) {
295: addedFlag = true;
296: data.add(dataElement);
297: } else
298: // basicIndex + i < data.size() -1
299: data.set(basicIndex + i, dataElement);
300:
301: Tuple tup = new Tuple(null, null,
302: (JoinPointRequestSurrogate) pasteList.get(i));
303: table.add(tup);
304:
305: if (pastedCells == null)
306: pastedCellsTmp[i] = basicIndex + i;
307: else
308: pastedCellsTmp[pastedCells.length + i] = basicIndex + i;
309: }
310:
311: pastedCells = pastedCellsTmp;
312: Arrays.sort(pastedCells); // actually not needed anymore since it is sorted already
313:
314: updateTable(data);
315: }
316:
317: // this is a list of aspect surrogates
318: protected synchronized void pasteAspects(List pasteList)
319: throws RemoteException, IllegalUserInputException,
320: PasteAspectsException, TableSelectionException {
321: checkIsConnected();
322: PasteAspectsException pae = new PasteAspectsException();
323:
324: if (pasteList == null)
325: throw new TableSelectionException("Nothing to paste!");
326:
327: if (parentModel.getClasspath() == null
328: || parentModel.getClasspath().trim().equals(""))
329: throw new IllegalUserInputException(
330: "Missing classpath information");
331:
332: parentModel.addVMToActiveTransaction(this );
333:
334: int j = 0;
335: int basicIndex = table.size();
336: List errorList = new Vector();
337: List alreadyContained = exMngr.allAspects();
338: for (int i = 0; i < pasteList.size(); i++) {
339: AspectSurrogate aspectSur = (AspectSurrogate) pasteList
340: .get(i);
341: if (alreadyContained.contains(aspectSur))
342: continue;
343:
344: Aspect realAsp = null;
345: try {
346: String[] execArgs = CommandlineProseClient
347: .insertScriptCommandline(parentModel
348: .getClasspath(), aspectSur
349: .getAspectClassName(), aspectSur
350: .getAssociatedObject(), address,
351: parentModel.getActiveTransactionID(),
352: isReal);
353:
354: for (int k = 0; k < execArgs.length; k++)
355: parentModel.getConsole().append(execArgs[k] + " ");
356: parentModel.getConsole().append("\n");
357: Process p = Runtime.getRuntime().exec(execArgs);
358: parentModel.getConsole().useProcessOutput(p);
359: try {
360: p.waitFor();
361: } catch (InterruptedException e) {
362: }
363: if (p.exitValue() != 0)
364: throw new RuntimeException("Cannot insert aspect");
365:
366: } catch (Exception e) {
367: e.printStackTrace();
368: pae.add(e);
369: continue;
370: }
371:
372: Tuple tup = new Tuple(aspectSur, null, null);
373: table.add(tup);
374:
375: Vector dataElement = new Vector();
376: dataElement.add(aspectSur);
377: dataElement.add(null);
378: dataElement.add(null);
379: if (basicIndex + j == data.size() - 1) {
380: addedFlag = true;
381: data.set(basicIndex + j, dataElement);
382: } else if (basicIndex + j > data.size() - 1) {
383: addedFlag = true;
384: data.add(dataElement);
385: } else
386: // basicIndex + j < data.size() -1
387: data.set(basicIndex + j, dataElement);
388:
389: j++;
390: }
391: updateTable(data);
392: if (pae.containsExceptions()) {
393: pae.fillInStackTrace();
394: throw pae;
395: }
396: }
397:
398: protected synchronized void cutAspects() throws RemoteException,
399: TableSelectionException, WithdrawAspectsException {
400: if (getSelectedColumn() == -1)
401: throw new TableSelectionException("Nothing to Cut!");
402: if (getSelectedColumn() != JWorksheetProseClientPane.ASPECT_COL_INDEX)
403: throw new TableSelectionException(
404: "Cutting is allowed only on 'Aspects'.");
405:
406: // find out what aspects to cut
407: HashSet myRememberList = new HashSet();
408: for (int i = 0; i < selectedCells.length; i++) {
409: AspectSurrogate aspect = (AspectSurrogate) ((Vector) data
410: .get(selectedCells[i]))
411: .get(JWorksheetProseClientPane.ASPECT_COL_INDEX);
412: if (aspect == null)
413: throw new TableSelectionException(
414: "Empty cells in selection!");
415: myRememberList.add(aspect);
416: }
417:
418: // cut the aspects
419: Iterator toCut = myRememberList.iterator();
420: WithdrawAspectsException maE = new WithdrawAspectsException();
421: while (toCut.hasNext()) {
422: try {
423: if (parentModel.getActiveTransactionID() == null)
424: exMngr.withdraw((AspectSurrogate) toCut.next());
425: else
426: exMngr.withdraw((AspectSurrogate) toCut.next(),
427: parentModel.getActiveTransactionID());
428: } catch (Exception e) {
429: maE.add(e);
430: }
431: }
432:
433: // update the table
434: for (int i = 0; i < table.size(); i++) {
435: AspectSurrogate aspect = (AspectSurrogate) ((Vector) data
436: .get(i))
437: .get(JWorksheetProseClientPane.ASPECT_COL_INDEX);
438: if (myRememberList.contains(aspect)) {
439: data.remove(i);
440: table.remove(i);
441: i--;
442: }
443: }
444: updateTable(data);
445:
446: if (maE.containsExceptions())
447: throw maE;
448: }
449:
450: public void updateTable(Vector data) {
451: for (int i = data.size(); i < NR_OF_ROWS; i++)
452: data.add(nullVector);
453:
454: if (addedFlag)
455: data.add(nullVector);
456: addedFlag = false;
457: this .setDataVector(data, createHeaders());
458: fireTableChanged(new TableModelEvent(this ));
459: }
460:
461: private Vector createHeaders() {
462: Vector v = new Vector();
463: v.add(new String("Aspect"));
464: v.add(new String("Crosscut"));
465: v.add(new String("Joinpoint"));
466: return v;
467: }
468:
469: private void convertDataForGUI() {
470: pastedCells = null; // you can say, that at this point the pastedCells could be reset to null.
471: data = new Vector();
472: if (table == null)
473: return;
474: for (int i = 0; i < table.size(); i++) {
475: Vector dataElement = new Vector();
476: dataElement
477: .add(((Tuple) table.get(i)).getAspectSurrogate());
478: dataElement.add(((Tuple) table.get(i))
479: .getCrosscutSurrogate());
480: dataElement.add(((Tuple) table.get(i))
481: .getRequestSurrogate());
482: data.add(dataElement);
483: }
484: if (data.size() >= NR_OF_ROWS)
485: addedFlag = true;
486: }
487:
488: public synchronized void refresh() throws java.rmi.RemoteException,
489: java.rmi.NotBoundException, java.net.MalformedURLException,
490: java.net.UnknownHostException {
491: int intPort;
492: RemoteAspectManager[] rams;
493: try {
494: intPort = Integer.parseInt(port);
495: } catch (NumberFormatException this IsNotAPortNum) {
496: throw new MalformedURLException("Illegal port number");
497: }
498: try {
499: rams = RemoteProseComponent.doGetRemoteAspectManagers(host,
500: intPort);
501: if (isReal)
502: exMngr = rams[0];
503: else
504: exMngr = rams[1];
505: } catch (java.io.IOException e) {
506: throw new RemoteException(e.toString());
507: }
508: }
509:
510: public synchronized void commit(Object transactionId)
511: throws java.rmi.RemoteException {
512: exMngr.commit(transactionId);
513: }
514:
515: public synchronized void abort(Object transactionId)
516: throws java.rmi.RemoteException {
517: exMngr.abort(transactionId);
518: }
519:
520: public String toString() {
521: return name;
522: }
523: }
|