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-2007 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: package org.netbeans.modules.refactoring.javascript.ui;
042:
043: import java.awt.BorderLayout;
044: import java.awt.Component;
045: import java.awt.Dimension;
046: import java.awt.event.ItemEvent;
047: import java.io.IOException;
048: import java.text.MessageFormat;
049: import java.util.HashSet;
050: import java.util.Set;
051: import javax.swing.SwingUtilities;
052: import javax.swing.event.ChangeListener;
053: import org.netbeans.modules.refactoring.javascript.RetoucheUtils;
054: import org.netbeans.modules.refactoring.spi.ui.CustomRefactoringPanel;
055: import org.openide.awt.Mnemonics;
056: import org.openide.util.NbBundle;
057: import org.netbeans.modules.refactoring.javascript.RefactoringModule;
058: import javax.swing.JPanel;
059: import org.netbeans.modules.gsf.api.CancellableTask;
060: import org.netbeans.modules.gsf.api.ElementKind;
061: import org.netbeans.modules.gsf.api.Modifier;
062: import org.netbeans.napi.gsfret.source.CompilationController;
063: import org.netbeans.napi.gsfret.source.Phase;
064: import org.netbeans.napi.gsfret.source.Source;
065: import org.netbeans.modules.refactoring.javascript.JsElementCtx;
066:
067: /**
068: * Based on the WhereUsedPanel in Java refactoring by Jan Becicka.
069: * @author Jan Becicka
070: * @author Tor Norbye
071: */
072: public class WhereUsedPanel extends JPanel implements
073: CustomRefactoringPanel {
074:
075: private final transient JsElementCtx element;
076: private JsElementCtx newElement;
077: private final transient ChangeListener parent;
078:
079: /** Creates new form WhereUsedPanel */
080: public WhereUsedPanel(String name, JsElementCtx e,
081: ChangeListener parent) {
082: setName(NbBundle.getMessage(WhereUsedPanel.class,
083: "LBL_WhereUsed")); // NOI18N
084: this .element = e;
085: this .parent = parent;
086: initComponents();
087: }
088:
089: private boolean initialized = false;
090: private String methodDeclaringSuperClass = null;
091: private String methodDeclaringClass = null;
092:
093: String getMethodDeclaringClass() {
094: return isMethodFromBaseClass() ? methodDeclaringSuperClass
095: : methodDeclaringClass;
096: }
097:
098: public void initialize() {
099: if (initialized)
100: return;
101: Source source = RetoucheUtils
102: .getSource(element.getFileObject());
103: CancellableTask<CompilationController> task = new CancellableTask<CompilationController>() {
104: public void cancel() {
105: throw new UnsupportedOperationException(
106: "Not supported yet.");
107: }
108:
109: // // TODO - handle methods in modules!!!!
110: // private String getClassName(JsElementCtx element) {
111: // return element.getDefClass();
112: // }
113:
114: /**
115: * @todo For method calls, try to figure out the call type with the type analyzer
116: */
117: public void run(CompilationController info)
118: throws Exception {
119: info.toPhase(Phase.RESOLVED);
120: String m_isBaseClassText = null;
121: final String labelText;
122: Set<Modifier> modif = new HashSet<Modifier>();
123: // TODO - resolve elements against the current info?
124: if (element.getKind() == ElementKind.METHOD) {
125: if (element.getElement() != null) {
126: modif = element.getElement().getModifiers();
127: }
128: String methodName = element.getName();
129: // String className = getClassName(element);
130: //String className = "noclass";
131: //String displayClassName = RubyIndex.UNKNOWN_CLASS.equals(className) ? "<Unknown>" : className;
132: labelText = NbBundle.getMessage(
133: WhereUsedPanel.class, "DSC_FuncUsages",
134: methodName);
135:
136: methodDeclaringClass = "";//className;
137:
138: // IndexedMethod method = RetoucheUtils.getOverridingMethod(element, info);
139: Object method = null;
140: if (method != null) {
141: m_isBaseClassText = new MessageFormat(NbBundle
142: .getMessage(WhereUsedPanel.class,
143: "LBL_UsagesOfBaseClass"))
144: .format(new Object[] {
145: //methodDeclaringSuperClass = method.getIn()
146: });
147: // newElement = new JsElementCtx(method, info);
148: }
149: } else if (element.getKind() == ElementKind.CLASS
150: || element.getKind() == ElementKind.MODULE) {
151: labelText = NbBundle.getMessage(
152: WhereUsedPanel.class, "DSC_ClassUsages",
153: element.getName()); // NOI18N
154: } else if (element.getKind() == ElementKind.CONSTRUCTOR) {
155: String methodName = element.getName();
156: // String className = getClassName(element);
157: String className = "clz";
158: labelText = NbBundle.getMessage(
159: WhereUsedPanel.class,
160: "DSC_ConstructorUsages", methodName,
161: className); // NOI18N
162: } else if (element.getKind() == ElementKind.FIELD) {
163: String fieldName = element.getName();
164: // String className = getClassName(element);
165: String className = "clz";
166: labelText = NbBundle.getMessage(
167: WhereUsedPanel.class, "DSC_FieldUsages",
168: fieldName, className); // NOI18N
169: } else {
170: labelText = NbBundle.getMessage(
171: WhereUsedPanel.class, "DSC_VariableUsages",
172: element.getName()); // NOI18N
173: }
174:
175: final Set<Modifier> modifiers = modif;
176: final String isBaseClassText = m_isBaseClassText;
177:
178: SwingUtilities.invokeLater(new Runnable() {
179: public void run() {
180: remove(classesPanel);
181: remove(methodsPanel);
182: // WARNING for now since this feature is not ready yet
183: //label.setText(labelText);
184: String combinedLabelText = NbBundle.getMessage(
185: WhereUsedPanel.class,
186: "DSC_WhereUsedWarningInDevelopment",
187: labelText);
188: label.setText(combinedLabelText);
189: if (element.getKind() == ElementKind.METHOD) {
190: add(methodsPanel, BorderLayout.CENTER);
191: methodsPanel.setVisible(true);
192: m_usages.setVisible(!modifiers
193: .contains(Modifier.STATIC));
194: // TODO - worry about frozen?
195: m_overriders
196: .setVisible(/*!modifiers.contains(Modifier.FINAL) ||*/modifiers
197: .contains(Modifier.STATIC)
198: || modifiers
199: .contains(Modifier.PRIVATE));
200: if (methodDeclaringSuperClass != null) {
201: m_isBaseClass.setVisible(true);
202: m_isBaseClass.setSelected(true);
203: Mnemonics.setLocalizedText(
204: m_isBaseClass, isBaseClassText);
205: } else {
206: m_isBaseClass.setVisible(false);
207: m_isBaseClass.setSelected(false);
208: }
209: } else if ((element.getKind() == ElementKind.CLASS)
210: || (element.getKind() == ElementKind.MODULE)) {
211: add(classesPanel, BorderLayout.CENTER);
212: classesPanel.setVisible(true);
213: } else {
214: remove(classesPanel);
215: remove(methodsPanel);
216: c_subclasses.setVisible(false);
217: m_usages.setVisible(false);
218: c_usages.setVisible(false);
219: c_directOnly.setVisible(false);
220: }
221: validate();
222: }
223: });
224: }
225: };
226: try {
227: source.runUserActionTask(task, true);
228: } catch (IOException ioe) {
229: throw (RuntimeException) new RuntimeException()
230: .initCause(ioe);
231: }
232: initialized = true;
233: }
234:
235: public JsElementCtx getBaseMethod() {
236: return newElement;
237: }
238:
239: /** This method is called from within the constructor to
240: * initialize the form.
241: * WARNING: Do NOT modify this code. The content of this method is
242: * always regenerated by the Form Editor.
243: */
244: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
245: private void initComponents() {
246: java.awt.GridBagConstraints gridBagConstraints;
247:
248: buttonGroup = new javax.swing.ButtonGroup();
249: methodsPanel = new javax.swing.JPanel();
250: m_isBaseClass = new javax.swing.JCheckBox();
251: jPanel1 = new javax.swing.JPanel();
252: m_overriders = new javax.swing.JCheckBox();
253: m_usages = new javax.swing.JCheckBox();
254: classesPanel = new javax.swing.JPanel();
255: jPanel2 = new javax.swing.JPanel();
256: c_subclasses = new javax.swing.JRadioButton();
257: c_usages = new javax.swing.JRadioButton();
258: c_directOnly = new javax.swing.JRadioButton();
259: jPanel3 = new javax.swing.JPanel();
260: label = new javax.swing.JLabel();
261: searchInComments = new javax.swing.JCheckBox();
262:
263: setLayout(new java.awt.BorderLayout());
264:
265: methodsPanel.setLayout(new java.awt.GridBagLayout());
266:
267: m_isBaseClass.setSelected(true);
268: m_isBaseClass
269: .addActionListener(new java.awt.event.ActionListener() {
270: public void actionPerformed(
271: java.awt.event.ActionEvent evt) {
272: m_isBaseClassActionPerformed(evt);
273: }
274: });
275: gridBagConstraints = new java.awt.GridBagConstraints();
276: gridBagConstraints.gridx = 0;
277: gridBagConstraints.gridy = 3;
278: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
279: gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 0);
280: methodsPanel.add(m_isBaseClass, gridBagConstraints);
281: java.util.ResourceBundle bundle = java.util.ResourceBundle
282: .getBundle("org/netbeans/modules/refactoring/javascript/ui/Bundle"); // NOI18N
283: m_isBaseClass.getAccessibleContext().setAccessibleDescription(
284: bundle.getString("ACSD_isBaseClass")); // NOI18N
285:
286: gridBagConstraints = new java.awt.GridBagConstraints();
287: gridBagConstraints.gridx = 0;
288: gridBagConstraints.gridy = 4;
289: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
290: gridBagConstraints.weightx = 1.0;
291: gridBagConstraints.weighty = 1.0;
292: methodsPanel.add(jPanel1, gridBagConstraints);
293:
294: org.openide.awt.Mnemonics.setLocalizedText(m_overriders,
295: org.openide.util.NbBundle.getMessage(
296: WhereUsedPanel.class,
297: "LBL_FindOverridingMethods")); // NOI18N
298: m_overriders
299: .addActionListener(new java.awt.event.ActionListener() {
300: public void actionPerformed(
301: java.awt.event.ActionEvent evt) {
302: m_overridersActionPerformed(evt);
303: }
304: });
305: gridBagConstraints = new java.awt.GridBagConstraints();
306: gridBagConstraints.gridx = 0;
307: gridBagConstraints.gridy = 2;
308: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
309: gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 0);
310: methodsPanel.add(m_overriders, gridBagConstraints);
311: m_overriders.getAccessibleContext().setAccessibleDescription(
312: bundle.getString("ACSD_overriders")); // NOI18N
313:
314: m_usages.setSelected(true);
315: org.openide.awt.Mnemonics.setLocalizedText(m_usages,
316: org.openide.util.NbBundle.getMessage(
317: WhereUsedPanel.class, "LBL_FindUsages")); // NOI18N
318: m_usages.setMargin(new java.awt.Insets(10, 2, 2, 2));
319: m_usages.addActionListener(new java.awt.event.ActionListener() {
320: public void actionPerformed(java.awt.event.ActionEvent evt) {
321: m_usagesActionPerformed(evt);
322: }
323: });
324: gridBagConstraints = new java.awt.GridBagConstraints();
325: gridBagConstraints.gridx = 0;
326: gridBagConstraints.gridy = 1;
327: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
328: gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 0);
329: methodsPanel.add(m_usages, gridBagConstraints);
330: m_usages.getAccessibleContext().setAccessibleDescription(
331: bundle.getString("ACSD_usages")); // NOI18N
332:
333: add(methodsPanel, java.awt.BorderLayout.CENTER);
334:
335: classesPanel.setLayout(new java.awt.GridBagLayout());
336: gridBagConstraints = new java.awt.GridBagConstraints();
337: gridBagConstraints.gridx = 0;
338: gridBagConstraints.gridy = 4;
339: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
340: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
341: gridBagConstraints.weightx = 1.0;
342: gridBagConstraints.weighty = 1.0;
343: classesPanel.add(jPanel2, gridBagConstraints);
344:
345: buttonGroup.add(c_subclasses);
346: org.openide.awt.Mnemonics.setLocalizedText(c_subclasses,
347: org.openide.util.NbBundle.getMessage(
348: WhereUsedPanel.class, "LBL_FindAllSubtypes")); // NOI18N
349: gridBagConstraints = new java.awt.GridBagConstraints();
350: gridBagConstraints.gridx = 0;
351: gridBagConstraints.gridy = 2;
352: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
353: gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 0);
354: classesPanel.add(c_subclasses, gridBagConstraints);
355: c_subclasses.getAccessibleContext().setAccessibleDescription(
356: bundle.getString("ACSD_subclasses")); // NOI18N
357:
358: buttonGroup.add(c_usages);
359: c_usages.setSelected(true);
360: org.openide.awt.Mnemonics.setLocalizedText(c_usages,
361: org.openide.util.NbBundle.getMessage(
362: WhereUsedPanel.class, "LBL_FindUsages")); // NOI18N
363: c_usages.setMargin(new java.awt.Insets(4, 2, 2, 2));
364: gridBagConstraints = new java.awt.GridBagConstraints();
365: gridBagConstraints.gridx = 0;
366: gridBagConstraints.gridy = 1;
367: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
368: gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 0);
369: classesPanel.add(c_usages, gridBagConstraints);
370: c_usages.getAccessibleContext().setAccessibleDescription(
371: bundle.getString("ACSD_usages")); // NOI18N
372:
373: buttonGroup.add(c_directOnly);
374: org.openide.awt.Mnemonics.setLocalizedText(c_directOnly,
375: org.openide.util.NbBundle.getMessage(
376: WhereUsedPanel.class,
377: "LBL_FindDirectSubtypesOnly")); // NOI18N
378: gridBagConstraints = new java.awt.GridBagConstraints();
379: gridBagConstraints.gridx = 0;
380: gridBagConstraints.gridy = 3;
381: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
382: gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 0);
383: classesPanel.add(c_directOnly, gridBagConstraints);
384: c_directOnly.getAccessibleContext().setAccessibleDescription(
385: bundle.getString("ACSD_directOnly")); // NOI18N
386:
387: add(classesPanel, java.awt.BorderLayout.CENTER);
388:
389: jPanel3.setLayout(new java.awt.BorderLayout());
390: jPanel3.add(label, java.awt.BorderLayout.NORTH);
391:
392: searchInComments
393: .setSelected(((Boolean) RefactoringModule.getOption(
394: "searchInComments.whereUsed", Boolean.FALSE))
395: .booleanValue());
396: org.openide.awt.Mnemonics.setLocalizedText(searchInComments,
397: org.openide.util.NbBundle.getBundle(
398: WhereUsedPanel.class).getString(
399: "LBL_SearchInComents")); // NOI18N
400: searchInComments.setMargin(new java.awt.Insets(10, 14, 2, 2));
401: searchInComments
402: .addItemListener(new java.awt.event.ItemListener() {
403: public void itemStateChanged(
404: java.awt.event.ItemEvent evt) {
405: searchInCommentsItemStateChanged(evt);
406: }
407: });
408: jPanel3.add(searchInComments, java.awt.BorderLayout.CENTER);
409: searchInComments.getAccessibleContext()
410: .setAccessibleDescription(searchInComments.getText());
411:
412: add(jPanel3, java.awt.BorderLayout.NORTH);
413: }// </editor-fold>//GEN-END:initComponents
414:
415: private void searchInCommentsItemStateChanged(
416: java.awt.event.ItemEvent evt) {//GEN-FIRST:event_searchInCommentsItemStateChanged
417: // used for change default value for searchInComments check-box.
418: // The value is persisted and then used as default in next IDE run.
419: Boolean b = evt.getStateChange() == ItemEvent.SELECTED ? Boolean.TRUE
420: : Boolean.FALSE;
421: RefactoringModule.setOption("searchInComments.whereUsed", b);
422: }//GEN-LAST:event_searchInCommentsItemStateChanged
423:
424: private void m_isBaseClassActionPerformed(
425: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_isBaseClassActionPerformed
426: parent.stateChanged(null);
427: }//GEN-LAST:event_m_isBaseClassActionPerformed
428:
429: private void m_overridersActionPerformed(
430: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_overridersActionPerformed
431: parent.stateChanged(null);
432: }//GEN-LAST:event_m_overridersActionPerformed
433:
434: private void m_usagesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_usagesActionPerformed
435: parent.stateChanged(null);
436: }//GEN-LAST:event_m_usagesActionPerformed
437:
438: // Variables declaration - do not modify//GEN-BEGIN:variables
439: private javax.swing.ButtonGroup buttonGroup;
440: private javax.swing.JRadioButton c_directOnly;
441: private javax.swing.JRadioButton c_subclasses;
442: private javax.swing.JRadioButton c_usages;
443: private javax.swing.JPanel classesPanel;
444: private javax.swing.JPanel jPanel1;
445: private javax.swing.JPanel jPanel2;
446: private javax.swing.JPanel jPanel3;
447: private javax.swing.JLabel label;
448: private javax.swing.JCheckBox m_isBaseClass;
449: private javax.swing.JCheckBox m_overriders;
450: private javax.swing.JCheckBox m_usages;
451: private javax.swing.JPanel methodsPanel;
452: private javax.swing.JCheckBox searchInComments;
453:
454: // End of variables declaration//GEN-END:variables
455:
456: public boolean isMethodFromBaseClass() {
457: return m_isBaseClass.isSelected();
458: }
459:
460: public boolean isMethodOverriders() {
461: return m_overriders.isSelected();
462: }
463:
464: public boolean isClassSubTypes() {
465: return c_subclasses.isSelected();
466: }
467:
468: public boolean isClassSubTypesDirectOnly() {
469: return c_directOnly.isSelected();
470: }
471:
472: public boolean isMethodFindUsages() {
473: return m_usages.isSelected();
474: }
475:
476: public boolean isClassFindUsages() {
477: return c_usages.isSelected();
478: }
479:
480: public @Override
481: Dimension getPreferredSize() {
482: Dimension orig = super .getPreferredSize();
483: return new Dimension(orig.width + 30, orig.height + 80);
484: }
485:
486: public boolean isSearchInComments() {
487: return searchInComments.isSelected();
488: }
489:
490: public Component getComponent() {
491: return this;
492: }
493: }
|