001: /* Soot - a J*va Optimization Framework
002: * Copyright (C) 2003 Jennifer Lhotak
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the
016: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017: * Boston, MA 02111-1307, USA.
018: */
019:
020: package ca.mcgill.sable.soot.attributes;
021:
022: import java.util.ArrayList;
023: import java.util.Iterator;
024: import java.util.ResourceBundle;
025: import org.eclipse.core.resources.*;
026: import org.eclipse.core.runtime.*;
027:
028: import org.eclipse.jdt.core.*;
029: import org.eclipse.jface.text.*;
030: import org.eclipse.jface.text.source.*;
031: import org.eclipse.swt.graphics.Rectangle;
032: import org.eclipse.ui.IEditorInput;
033: import org.eclipse.ui.IMarkerResolution;
034: import org.eclipse.ui.IWorkbenchWindow;
035: import org.eclipse.ui.PartInitException;
036: import org.eclipse.ui.texteditor.*;
037:
038: import ca.mcgill.sable.soot.editors.JimpleEditor;
039: import ca.mcgill.sable.soot.ui.PopupListSelector;
040: import ca.mcgill.sable.soot.*;
041:
042: public abstract class SootAttributeSelectAction extends ResourceAction {
043:
044: AbstractTextEditor editor;
045: AbstractTextEditor linkToEditor;
046: IVerticalRulerInfo rulerInfo;
047: AbstractMarkerAnnotationModel model;
048: int lineNumber;
049:
050: /**
051: * @param bundle
052: * @param prefix
053: */
054: public SootAttributeSelectAction(ResourceBundle bundle,
055: String prefix, ITextEditor editor,
056: IVerticalRulerInfo rulerInfo) {
057:
058: super (bundle, prefix);
059: setEditor((AbstractTextEditor) editor);
060:
061: setRulerInfo(rulerInfo);
062: }
063:
064: public IResource getResource(AbstractTextEditor textEditor) {
065: IEditorInput input = textEditor.getEditorInput();
066: return (IResource) ((IAdaptable) input)
067: .getAdapter(IResource.class);
068: }
069:
070: protected IDocument getDocument() {
071: IDocumentProvider provider = getEditor().getDocumentProvider();
072: return provider.getDocument(getEditor().getEditorInput());
073: }
074:
075: public void run() {
076:
077: // need to get list of texts
078: IAnnotationModel model = getEditor().getDocumentProvider()
079: .getAnnotationModel(getEditor().getEditorInput());
080: if (model instanceof AbstractMarkerAnnotationModel) {
081: setModel((AbstractMarkerAnnotationModel) model);
082: }
083:
084: int markerLine = getRulerInfo()
085: .getLineOfLastMouseButtonActivity();
086: IResource rec = getResource(getEditor());
087: try {
088: IMarker[] markers = rec.findMarkers(
089: "ca.mcgill.sable.soot.sootattributemarker", true,
090: IResource.DEPTH_INFINITE);
091: for (int i = 0; i < markers.length; i++) {
092: if (getModel().getMarkerPosition(markers[i]) == null)
093: continue;
094: setLineNumber(getDocument().getLineOfOffset(
095: getModel().getMarkerPosition(markers[i])
096: .getOffset()));
097:
098: if (getLineNumber() == markerLine) {
099:
100: ArrayList links = getMarkerLinks();
101: Iterator lit = links.iterator();
102: String[] list = getMarkerLabels(links);
103: if ((list == null) || (list.length == 0)) {
104: // show no links
105: } else {
106: IWorkbenchWindow window = SootPlugin
107: .getDefault().getWorkbench()
108: .getActiveWorkbenchWindow()
109: .getActivePage().getWorkbenchWindow();
110:
111: PopupListSelector popup = new PopupListSelector(
112: window.getShell());
113: popup.setItems(list);
114:
115: int listWidth = getListWidth(list);
116:
117: if (getEditor() instanceof JimpleEditor) {
118: int topIndex = ((JimpleEditor) getEditor())
119: .getViewer().getTopIndex();
120: Rectangle rect = new Rectangle(320,
121: (getLineNumber() + 1 - topIndex),
122: listWidth, 45);
123:
124: popup.open(rect);
125: } else {
126: int topIndex = ((ITextViewer) ((AbstractTextEditor) getEditor())
127: .getAdapter(ITextOperationTarget.class))
128: .getTopIndex();
129: int pos = getModel().getMarkerPosition(
130: markers[i]).getOffset();
131: pos = pos / getLineNumber();
132: Rectangle rect = new Rectangle(320,
133: getLineNumber() + 1 - topIndex,
134: listWidth, 45);
135: popup.open(rect);
136:
137: }
138:
139: handleSelection(popup.getSelected(), links);
140: }
141: }
142: }
143: } catch (CoreException e) {
144:
145: } catch (BadLocationException e1) {
146: }
147:
148: }
149:
150: public int getListWidth(String[] list) {
151: int width = 0;
152: for (int i = 0; i < list.length; i++) {
153:
154: String next = list[i];
155: width = next.length() > width ? next.length() : width;
156: }
157:
158: return width * 6;
159: }
160:
161: public void handleSelection(String selected, ArrayList links) {
162: if (selected == null)
163: return;
164: try {
165: int toShow = 0;
166: String className;
167: Iterator it = links.iterator();
168: while (it.hasNext()) {
169: LinkAttribute la = (LinkAttribute) it.next();
170: if (la.getLabel().equals(selected)) {
171: toShow = getLinkLine(la) - 1;//.getJimpleLink() - 1;
172:
173: className = la.getClassName();
174: findClass(className);
175: }
176: }
177: int selOffset = getLinkToEditor().getDocumentProvider()
178: .getDocument(getLinkToEditor().getEditorInput())
179: .getLineOffset(toShow);
180: if ((selOffset != -1) && (selOffset != 0)) {
181:
182: if (getLinkToEditor() instanceof JimpleEditor) {
183:
184: ((JimpleEditor) getLinkToEditor()).getViewer()
185: .setRangeIndication(selOffset, 1, true);
186: SootPlugin.getDefault().getWorkbench()
187: .getActiveWorkbenchWindow().getActivePage()
188: .activate(getLinkToEditor());
189:
190: } else {
191: SootPlugin.getDefault().getWorkbench()
192: .getActiveWorkbenchWindow().getActivePage()
193: .activate(getLinkToEditor());
194: ((AbstractTextEditor) SootPlugin.getDefault()
195: .getWorkbench().getActiveWorkbenchWindow()
196: .getActivePage().getActiveEditor())
197: .selectAndReveal(selOffset, 0);
198: ((AbstractTextEditor) SootPlugin.getDefault()
199: .getWorkbench().getActiveWorkbenchWindow()
200: .getActivePage().getActiveEditor())
201: .setHighlightRange(selOffset, 1, true);
202:
203: }
204: }
205: } catch (BadLocationException e) {
206: System.out.println(e.getMessage());
207: }
208: }
209:
210: protected abstract int getLinkLine(LinkAttribute la);
211:
212: public abstract void findClass(String className);
213:
214: public String removeExt(String fileName) {
215: return fileName.substring(0, fileName.lastIndexOf("."));
216: }
217:
218: public abstract ArrayList getMarkerLinks();
219:
220: public String[] getMarkerLabels(ArrayList links) {
221:
222: if ((links == null) || (links.size() == 0))
223: return null;
224: ArrayList list = new ArrayList();
225: String[] attributeTexts = new String[links.size()];
226: Iterator it = links.iterator();
227: while (it.hasNext()) {
228: list.add(((LinkAttribute) it.next()).getLabel());
229: }
230: list.toArray(attributeTexts);
231: return attributeTexts;
232:
233: }
234:
235: public String[] fixLabels(String[] at) {
236: for (int i = 0; i < at.length; i++) {
237: String temp = at[i];
238: temp.replaceAll("<", "<");
239: temp.replaceAll(">", ">");
240: at[i] = temp;
241: }
242: return at;
243: }
244:
245: public void getMarkerResolutions(IMarker marker) {
246:
247: SootAttributeResolutionGenerator sarg = new SootAttributeResolutionGenerator();
248: if (sarg.hasResolutions(marker)) {
249: IMarkerResolution[] res = sarg.getResolutions(marker);
250: for (int i = 0; i < res.length; i++) {
251: //System.out.println("res: "+res[i].getLabel());
252: }
253: }
254: }
255:
256: /**
257: * @return
258: */
259: public AbstractTextEditor getEditor() {
260: return editor;
261: }
262:
263: /**
264: * @param editor
265: */
266: public void setEditor(AbstractTextEditor editor) {
267: this .editor = editor;
268: }
269:
270: /**
271: * @return
272: */
273: public IVerticalRulerInfo getRulerInfo() {
274: return rulerInfo;
275: }
276:
277: /**
278: * @param info
279: */
280: public void setRulerInfo(IVerticalRulerInfo info) {
281: rulerInfo = info;
282: }
283:
284: /**
285: * @return
286: */
287: public AbstractMarkerAnnotationModel getModel() {
288: return model;
289: }
290:
291: /**
292: * @param model
293: */
294: public void setModel(AbstractMarkerAnnotationModel model) {
295: this .model = model;
296: }
297:
298: /**
299: * @return
300: */
301: public int getLineNumber() {
302: return lineNumber;
303: }
304:
305: /**
306: * @param i
307: */
308: public void setLineNumber(int i) {
309: lineNumber = i;
310: }
311:
312: /**
313: * @return
314: */
315: public AbstractTextEditor getLinkToEditor() {
316: return linkToEditor;
317: }
318:
319: /**
320: * @param editor
321: */
322: public void setLinkToEditor(AbstractTextEditor editor) {
323: linkToEditor = editor;
324: }
325:
326: }
|