|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.editor.java; import java.awt.Cursor; import java.awt.Dialog; import java.awt.Frame; import java.awt.event.ActionEvent; import java.util.*; import javax.swing.text.Document; import javax.swing.text.JTextComponent; import org.netbeans.api.mdr.MDRepository; import org.netbeans.editor.BaseAction; import org.netbeans.editor.BaseDocument; import org.netbeans.jmi.javamodel.*; import org.netbeans.jmi.javamodel.JavaPackage; import org.netbeans.modules.javacore.ClassIndex; import org.netbeans.modules.javacore.internalapi.JavaMetamodel; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; import org.openide.awt.StatusDisplayer; import org.openide.filesystems.FileObject; import org.openide.loaders.DataObject; import org.openide.util.NbBundle; import org.openide.windows.WindowManager; public class JavaFixAllImports extends BaseAction { static final long serialVersionUID = 6020950800832542269L; private static final int HAS_SYNTAX_ERROR = 16; // [PENDING] private Cursor editCursor, mainCursor; private Frame mainWindow; private JMIUtils jmiUtils; public JavaFixAllImports() { super(JavaKit.fixImportsAction); putValue(SHORT_DESCRIPTION, NbBundle.getBundle(JavaKit.class).getString("fix-imports")); putValue("helpID", JavaFixAllImports.class.getName()); // NOI18N } public void actionPerformed(ActionEvent evt, JTextComponent target) { if (target == null) return; addAllNeededImports(target.getText(), (BaseDocument)target.getDocument(), target); } public void addAllNeededImports(String txt, BaseDocument doc, JTextComponent target) { Object sdp = doc.getProperty(Document.StreamDescriptionProperty); FileObject fo = null; if (sdp instanceof FileObject) { fo = (FileObject)sdp; } else if (sdp instanceof DataObject) { fo = ((DataObject)sdp).getPrimaryFile(); } else { return; } editCursor = target.getCursor(); mainWindow = WindowManager.getDefault().getMainWindow(); mainCursor = mainWindow.getCursor(); Cursor waitCursor = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR); target.setCursor(waitCursor); mainWindow.setCursor(waitCursor); ArrayList importsToAdd = null, importsToRemove = null; HashSet unresolved = null; boolean failed = true; boolean diagPassed = true; boolean hasSyntaxError; jmiUtils = JMIUtils.get(doc); jmiUtils.beginTrans(true); try { Resource resource = JavaMetamodel.getManager().getResource(fo); hasSyntaxError = (resource.getStatus() & HAS_SYNTAX_ERROR) > 0; if (!hasSyntaxError) { HashSet clsNames = new HashSet(); HashSet resolvedClsNames = new HashSet(); findPotentialClassNames(resource, clsNames, resolvedClsNames); HashMap importedPackages = new HashMap(); HashMap importedClasses = new HashMap(); for (Iterator iter = resource.getImports().iterator(); iter.hasNext();) { Import imp = (Import) iter.next(); if (imp.isStatic()) continue; String id = idToName(imp.getIdentifier()); if (imp.getImportedElement() instanceof JavaPackage) { importedPackages.put(id, imp); } else { if (imp.isOnDemand()) { id = id + ".*"; // NOI18N } importedClasses.put(id, imp); } } importsToAdd = new ArrayList(); importsToRemove = new ArrayList(); unresolved = new HashSet(); diagPassed = calculateAndAddImports(clsNames, resolvedClsNames, importedPackages, importedClasses, resource, importsToAdd, importsToRemove, unresolved, target); } failed = false; } finally { target.setCursor(editCursor); mainWindow.setCursor(mainCursor); jmiUtils.endTrans(failed); } if (hasSyntaxError) { String msg = NbBundle.getMessage(JavaFixAllImports.class, "SourceContainsSyntaxErrors_Lbl"); StatusDisplayer.getDefault().setStatusText(msg); } else if (unresolved.size() > 0) { showInformational(unresolved); } else if (diagPassed) { String msg = null; if (importsToAdd.size() > 0 || importsToRemove.size() > 0) { msg = NbBundle.getMessage(JavaFixAllImports.class, "AllImportsWereFixed_Lbl"); } else { msg = NbBundle.getMessage(JavaFixAllImports.class, "NoImportsToFix_Lbl"); } StatusDisplayer.getDefault().setStatusText(msg); } } boolean calculateAndAddImports(HashSet names, HashSet resolvedNames, HashMap importedPackages, HashMap importedClasses, Resource resource, ArrayList importsToAdd, List importsToRemove, HashSet unresolved, JTextComponent target) { HashMap ambigs = new HashMap(); HashSet usedImports = new HashSet(); Import imp; FileObject[] cpRoots = JavaMetamodel.getManager().getClassPath().getRoots(); ClassIndex[] cis = new ClassIndex[cpRoots.length]; for (int i = 0; i < cpRoots.length; i++) { cis[i] = ClassIndex.getIndex(JavaMetamodel.getManager().getJavaExtent(cpRoots[i])); } // detect imports corresponding to resolved types for (Iterator iter = resolvedNames.iterator(); iter.hasNext();) { JavaClass jc = (JavaClass)iter.next(); imp = (Import)importedClasses.get(jc.getName()); if (imp != null) { usedImports.add(imp); } else { Object comp = jc.refImmediateComposite(); if (comp instanceof Resource) { imp = (Import)importedPackages.get(((Resource)comp).getPackageName()); if (imp != null) { usedImports.add(imp); } } else if (comp instanceof JavaClass) { imp = (Import)importedClasses.get(((JavaClass)comp).getName() + ".*"); // NOI18N if (imp != null) { usedImports.add(imp); } } } } // for Iterator classifiers = resource.getClassifiers().iterator(); JavaClass from = classifiers.hasNext() ? (JavaClass)classifiers.next() : null; Outer: for (Iterator iter = names.iterator(); iter.hasNext();) { String simpleName = (String)iter.next(); Collection ret = new ArrayList(); for (int i = 0; i < cis.length; i++) { if (cis[i] == null) continue; Collection res = cis[i].getClassesBySimpleName(simpleName); if (res != null) { for (Iterator tmpIt = res.iterator(); tmpIt.hasNext();) { JavaClass javaClass = (JavaClass) tmpIt.next(); if (jmiUtils.isAccessible(javaClass, from)) ret.add(javaClass); } } } if (ret.size() == 0) { unresolved.add(simpleName); continue; } for (Iterator iter2 = ret.iterator(); iter2.hasNext();) { JavaClass cls = (JavaClass)iter2.next(); Object comp = cls.refImmediateComposite(); String pkg = null; if (comp instanceof Resource) { pkg = ((Resource)comp).getPackageName(); } if (pkg != null) { if (pkg.equals("java.lang")) { // NOI18N continue Outer; } imp = (Import) importedPackages.get(pkg); if (imp != null) { // NOI18N usedImports.add(imp); continue Outer; } } imp = (Import) importedClasses.get(cls.getName()); if (imp != null) { usedImports.add(imp); continue Outer; } if (comp instanceof JavaClass) { imp = (Import)importedClasses.get(((JavaClass)comp).getName() + ".*"); // NOI18N if (imp != null) { usedImports.add(imp); continue Outer; } } } int sz = ret.size(); if (sz > 1) ambigs.put(simpleName, ret); else if (sz > 0) importsToAdd.add(((JavaClass)ret.iterator().next()).getName()); } target.setCursor(editCursor); mainWindow.setCursor(mainCursor); String[] selections = null; boolean ambigsWasCalled = false; if (ambigs != null && ambigs.size() > 0) { selections = userResolvesAmbiguities(ambigs); ambigsWasCalled = true; } if (ambigsWasCalled) { if (selections != null) { for (int i = 0; i < selections.length; i++) importsToAdd.add(selections[i]); } else { // user Cancelled the "Add Imports" Action return false; } } changeImports(importsToAdd, importsToRemove, usedImports, resource); return true; } // Present to the user all the ambiguous imports and get their repsonse back private static String[] userResolvesAmbiguities(HashMap ambigs) { int numberOfAmbigs = ambigs.size(); // For now, we simply use the first element as the default. We could be smarter in the future int cnt = 0; String[] simpleNames = new String[numberOfAmbigs]; String[][] choices = new String[numberOfAmbigs][]; String[] defaults = new String[numberOfAmbigs]; int [] defaultWeights = new int[numberOfAmbigs]; for (Iterator ambigIter = ambigs.keySet().iterator(); ambigIter.hasNext(); cnt++) { String simpleName = (String)ambigIter.next(); List l = (List)ambigs.get(simpleName); simpleNames[cnt] = simpleName; String[] curChoice = choices[cnt] = new String[l.size()]; defaultWeights[cnt] = -1; for (int k = 0; k < l.size(); k++) { JavaClass cls = (JavaClass)l.get(k); String fullName = cls.getName(); curChoice[k] = fullName; int weight = JMIUtils.getDefaultSelectionWeight(cls); if (weight > defaultWeights[cnt]) { defaults[cnt] = fullName; defaultWeights[cnt] = weight; } } Arrays.sort(curChoice); } FixDuplicateImportStmts pp = new FixDuplicateImportStmts(simpleNames, choices, defaults); DialogDescriptor dd = new DialogDescriptor(pp, NbBundle.getMessage(JavaFixAllImports.class, "FixDuplicateImports_dlgTitle")); dd.setOptionType(DialogDescriptor.OK_CANCEL_OPTION); final Dialog d = org.openide.DialogDisplayer.getDefault().createDialog(dd); d.pack(); d.setVisible(true); Object o = dd.getValue(); if (o == DialogDescriptor.OK_OPTION) { return pp.getSelections(); } else { // Cancel pressed d.setVisible(false); d.dispose(); return null; } } private static void showInformational(HashSet unresolved) { StringBuffer sb = new StringBuffer(NbBundle.getMessage(JavaFixAllImports.class, "NoImportsFound_Lbl")); sb.append('\n'); for (Iterator iter = unresolved.iterator(); iter.hasNext();) { sb.append(" - "); // NOI18N sb.append((String)iter.next()); sb.append('\n'); // NOI18N } NotifyDescriptor d = new NotifyDescriptor.Message(sb.toString()); DialogDisplayer.getDefault().notify(d); } private static void changeImports(ArrayList importsToAdd, List importsToRemove, Set usedImports, Resource resource) { ListIterator iter; Object[] importsArray = importsToAdd.toArray(); Arrays.sort(importsArray, new Comparator() { public int compare(Object o1, Object o2) { return ((String)o1).compareTo((String)o2); } }); String thisPkgName = resource.getPackageName(); List imports = resource.getImports(); for (iter = imports.listIterator(); iter.hasNext();) { Import imp = (Import)iter.next(); if (imp.isStatic()) continue; if (!usedImports.contains(imp)) { importsToRemove.add(imp); iter.remove(); } else { String pkgName = null; if (!imp.isOnDemand()) { JavaClass jc = (JavaClass) imp.getImportedElement(); pkgName = jc.getResource().getPackageName(); } else { Object obj = imp.getImportedElement(); if (obj instanceof JavaPackage) { pkgName = ((JavaPackage) obj).getName(); } } if (pkgName != null && (pkgName.equals("java.lang") || pkgName.equals(thisPkgName))) { importsToRemove.add(imp); iter.remove(); } } } if (importsArray.length == 0) return; ImportClass proxy = ((JavaModelPackage)resource.refOutermostPackage()).getImport(); Import imp = null; iter = imports.listIterator(imports.size()); String currName = null; if (iter.hasPrevious()) { currName = ((Import)iter.previous()).getName(); iter.next(); } for (int i = importsArray.length - 1; i >=0; i--) { String impName = (String)importsArray[i]; imp = proxy.createImport(impName, null, false, false); while (currName != null && (currName.compareTo(impName) > 0)) { iter.previous(); if (iter.hasPrevious()) { currName = ((Import)iter.previous()).getName(); iter.next(); } else { currName = null; } } iter.add(imp); iter.previous(); } } // ........................................................................... private static void idToName(StringBuffer buffer, MultipartId id) { MultipartId parent = id.getParent(); if (parent != null) { idToName(buffer, parent); buffer.append('.'); } buffer.append(id.getName()); } private static String idToName(MultipartId id) { StringBuffer buffer = new StringBuffer(); idToName(buffer, id); return buffer.toString(); } private static void findPotentialClassNames(Set set, Set resolved, Element elem, Set checkedElements) { Iterator iterator; if (elem instanceof ArrayReference) { elem = ((ArrayReference)elem).getParent(); } if (elem instanceof MultipartId) { List typeArgs = new ArrayList(); MultipartId id = (MultipartId)elem; typeArgs.addAll(id.getTypeArguments()); while (id.getParent() != null) { id = id.getParent(); typeArgs.addAll(id.getTypeArguments()); } NamedElement namedElem = id.getElement(); if (namedElem instanceof UnresolvedClass) { set.add(idToName(id)); } else if (namedElem instanceof JavaClass) { resolved.add(namedElem); } iterator = typeArgs.iterator(); } else { iterator = elem.getChildren().iterator(); } for (; iterator.hasNext();) { Element usedElem = (Element)iterator.next(); if (!checkedElements.contains(usedElem)) { checkedElements.add(usedElem); findPotentialClassNames(set, resolved, usedElem, checkedElements); } } } private static void findPotentialClassNames(Resource resource, Set unresolved, Set resolved) { HashSet checkedElements = new HashSet(); for (Iterator iter = resource.getClassifiers().iterator(); iter.hasNext();) { findPotentialClassNames(unresolved, resolved, (Element)iter.next(), checkedElements); } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.