diff -r cbdf0aa62e1e java.hints.ui/src/org/netbeans/modules/java/hints/onsave/Bundle.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java.hints.ui/src/org/netbeans/modules/java/hints/onsave/Bundle.properties Thu Sep 06 17:47:19 2012 +0200 @@ -0,0 +1,2 @@ +OnSaveCustomizer.removeUnusedImports.text=Remove Unused Imports +OnSaveCustomizer.organizeImports.text=Organize Imports diff -r cbdf0aa62e1e java.hints.ui/src/org/netbeans/modules/java/hints/onsave/OnSaveCustomizer.form --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java.hints.ui/src/org/netbeans/modules/java/hints/onsave/OnSaveCustomizer.form Thu Sep 06 17:47:19 2012 +0200 @@ -0,0 +1,63 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff -r cbdf0aa62e1e java.hints.ui/src/org/netbeans/modules/java/hints/onsave/OnSaveCustomizer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java.hints.ui/src/org/netbeans/modules/java/hints/onsave/OnSaveCustomizer.java Thu Sep 06 17:47:19 2012 +0200 @@ -0,0 +1,123 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2012 Sun Microsystems, Inc. + */ +package org.netbeans.modules.java.hints.onsave; + +import java.util.prefs.Preferences; + +/** + * + * @author lahvac + */ +public class OnSaveCustomizer extends javax.swing.JPanel { + private final Preferences settings; + + /** + * Creates new form OnSaveCustomizer + */ + public OnSaveCustomizer(Preferences settings) { + initComponents(); + this.settings = settings; + removeUnusedImports.setSelected(RemoveUnusedAfterSave.getValue(settings, "Imports_UNUSED")); + organizeImports.setSelected(RemoveUnusedAfterSave.getValue(settings, "org.netbeans.modules.java.hints.OrganizeImports")); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + removeUnusedImports = new javax.swing.JCheckBox(); + organizeImports = new javax.swing.JCheckBox(); + + org.openide.awt.Mnemonics.setLocalizedText(removeUnusedImports, org.openide.util.NbBundle.getMessage(OnSaveCustomizer.class, "OnSaveCustomizer.removeUnusedImports.text")); // NOI18N + removeUnusedImports.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + removeUnusedImportsActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(organizeImports, org.openide.util.NbBundle.getMessage(OnSaveCustomizer.class, "OnSaveCustomizer.organizeImports.text")); // NOI18N + organizeImports.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + organizeImportsActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(removeUnusedImports) + .addComponent(organizeImports)) + .addContainerGap(196, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(removeUnusedImports) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(organizeImports) + .addContainerGap(242, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void removeUnusedImportsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeUnusedImportsActionPerformed + settings.putBoolean(RemoveUnusedAfterSave.KEY_SETTINGS_PREFIX + "Imports_UNUSED", removeUnusedImports.isSelected()); + }//GEN-LAST:event_removeUnusedImportsActionPerformed + + private void organizeImportsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_organizeImportsActionPerformed + settings.putBoolean(RemoveUnusedAfterSave.KEY_SETTINGS_PREFIX + "org.netbeans.modules.java.hints.OrganizeImports", organizeImports.isSelected()); + }//GEN-LAST:event_organizeImportsActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JCheckBox organizeImports; + private javax.swing.JCheckBox removeUnusedImports; + // End of variables declaration//GEN-END:variables +} diff -r cbdf0aa62e1e java.hints.ui/src/org/netbeans/modules/java/hints/onsave/OnSavePreferencesCustomizer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java.hints.ui/src/org/netbeans/modules/java/hints/onsave/OnSavePreferencesCustomizer.java Thu Sep 06 17:47:19 2012 +0200 @@ -0,0 +1,90 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2012 Sun Microsystems, Inc. + */ +package org.netbeans.modules.java.hints.onsave; + +import java.util.prefs.Preferences; +import javax.swing.JComponent; +import org.netbeans.modules.options.editor.spi.PreferencesCustomizer; +import org.openide.util.HelpCtx; + +/** + * + * @author lahvac + */ +public class OnSavePreferencesCustomizer implements PreferencesCustomizer { + + private final Preferences preferences; + + public OnSavePreferencesCustomizer(Preferences preferences) { + this.preferences = preferences; + } + + @Override + public String getId() { + return "java-hints-on-save"; + } + + @Override + public String getDisplayName() { + return "Java"; + } + + @Override + public HelpCtx getHelpCtx() { + return null; + } + + @Override + public JComponent getComponent() { + return new OnSaveCustomizer(preferences); + } + + public static final class FactoryImpl implements Factory { + + @Override + public PreferencesCustomizer create(Preferences preferences) { + return new OnSavePreferencesCustomizer(preferences); + } + + } + +} diff -r cbdf0aa62e1e java.hints.ui/src/org/netbeans/modules/java/hints/onsave/RemoveUnusedAfterSave.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java.hints.ui/src/org/netbeans/modules/java/hints/onsave/RemoveUnusedAfterSave.java Thu Sep 06 17:47:19 2012 +0200 @@ -0,0 +1,166 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2012 Sun Microsystems, Inc. + */ +package org.netbeans.modules.java.hints.onsave; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.prefs.Preferences; +import javax.swing.undo.UndoableEdit; +import org.netbeans.api.editor.mimelookup.MimeLookup; +import org.netbeans.api.editor.mimelookup.MimePath; +import org.netbeans.api.editor.mimelookup.MimeRegistration; +import org.netbeans.api.java.source.CompilationController; +import org.netbeans.api.java.source.JavaSource; +import org.netbeans.api.java.source.ModificationResult; +import org.netbeans.api.java.source.Task; +import org.netbeans.modules.java.hints.providers.spi.HintDescription; +import org.netbeans.modules.java.hints.providers.spi.HintMetadata; +import org.netbeans.modules.java.hints.spiimpl.MessageImpl; +import org.netbeans.modules.java.hints.spiimpl.RulesManager; +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch; +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.BatchResult; +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Folder; +import org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities; +import org.netbeans.modules.java.hints.spiimpl.batch.ProgressHandleWrapper; +import org.netbeans.modules.java.hints.spiimpl.batch.Scopes; +import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation; +import org.netbeans.spi.editor.document.OnSaveTask; +import org.openide.filesystems.FileObject; +import org.openide.util.Exceptions; + +/** + * + * @author lahvac + */ +public class RemoveUnusedAfterSave implements OnSaveTask { + + public static final String KEY_SETTINGS_PREFIX = "on-save."; + + private final Context c; + private final JavaSource javaSource; + private final Set toRun; + private final AtomicBoolean cancel = new AtomicBoolean(); + + public RemoveUnusedAfterSave(Context c, JavaSource javaSource, Set toRun) { + this.c = c; + this.javaSource = javaSource; + this.toRun = toRun; + } + + @Override + public void performTask(UndoableEdit undoEdit) { + try { + List hints = new ArrayList(); + for (Entry> e : RulesManager.getInstance().readHints(null, null, cancel).entrySet()) { + if (toRun.contains(e.getKey().id)) { + hints.addAll(e.getValue()); + } + } + FileObject file = javaSource.getFileObjects().iterator().next(); + BatchResult batchResult = BatchSearch.findOccurrences(hints, Scopes.specifiedFoldersScope(Folder.convert(file))); + for (ModificationResult mr : BatchUtilities.applyFixes(batchResult, new ProgressHandleWrapper(1), cancel, new ArrayList(), null, true, new ArrayList())) { + mr.commit(); + } + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + + @Override + public void runLocked(final Runnable run) { + try { + javaSource.runUserActionTask(new Task() { + @Override public void run(CompilationController parameter) throws Exception { + run.run(); + } + }, true); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + + @MimeRegistration(mimeType="text/x-java", service=Factory.class) + public static class TaskFactory implements Factory { + @Override public OnSaveTask createTask(Context context) { + JavaSource javaSource = JavaSource.forDocument(context.getDocument()); + + if (javaSource == null) return NOOP; + + Set toRun = new HashSet(); + Preferences settings = MimeLookup.getLookup(MimePath.get("text/x-java")).lookup(Preferences.class); + + for (Entry e : id2DefaultState.entrySet()) { + if (settings.getBoolean(KEY_SETTINGS_PREFIX + e.getKey(), e.getValue())) toRun.add(e.getKey()); + } + + if (toRun.isEmpty()) return NOOP; + + return new RemoveUnusedAfterSave(context, javaSource, toRun); + } + } + + private static final Map id2DefaultState = new HashMap(); + + static { + id2DefaultState.put("Imports_UNUSED", false); + id2DefaultState.put("org.netbeans.modules.java.hints.OrganizeImports", false); + } + + static boolean getValue(Preferences settings, String id) { + return settings.getBoolean(KEY_SETTINGS_PREFIX + id, id2DefaultState.get(id)); + } + + private static final OnSaveTask NOOP = new OnSaveTask() { + @Override public void performTask(UndoableEdit undoEdit) { } + @Override public void runLocked(Runnable run) { + run.run(); + } + }; +} diff -r cbdf0aa62e1e spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchSearch.java --- a/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchSearch.java Thu Sep 06 17:34:27 2012 +0200 +++ b/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchSearch.java Thu Sep 06 17:47:19 2012 +0200 @@ -550,7 +550,7 @@ super(src); } public void validateResource(Collection resources, ProgressHandleWrapper progress, VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, Collection problems, AtomicBoolean cancel) { - getLocalVerifiedSpans(resources, progress, callback, false/*XXX*/, problems, cancel); + getLocalVerifiedSpans(resources, progress, callback, doNotRegisterClassPath, problems, cancel); } } diff -r cbdf0aa62e1e spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchUtilities.java --- a/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchUtilities.java Thu Sep 06 17:34:27 2012 +0200 +++ b/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchUtilities.java Thu Sep 06 17:47:19 2012 +0200 @@ -124,6 +124,10 @@ } public static Collection applyFixes(BatchResult candidates, @NonNull final ProgressHandleWrapper progress, AtomicBoolean cancel, final Collection fileChanges, final Map changesPerFix, final Collection problems) { + return applyFixes(candidates, progress, cancel, fileChanges, changesPerFix, false, problems); + } + + public static Collection applyFixes(BatchResult candidates, @NonNull final ProgressHandleWrapper progress, AtomicBoolean cancel, final Collection fileChanges, final Map changesPerFix, boolean doNotRegisterClassPath, final Collection problems) { final Map> processedDependencyChanges = new IdentityHashMap>(); final Map> result = new LinkedHashMap>(); final Map resourceContentChanges = new HashMap(); @@ -175,7 +179,7 @@ } }; - BatchSearch.getVerifiedSpans(candidates, progress, callback, problems, cancel); + BatchSearch.getVerifiedSpans(candidates, progress, callback, doNotRegisterClassPath, problems, cancel); addResourceContentChanges(resourceContentChanges, result);