Computing duplicates incrementally, including incremental computation UI.
1.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/duplicates/Bundle.properties Sat Feb 12 00:49:24 2011 +0100
1.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/duplicates/Bundle.properties Mon Feb 14 20:43:35 2011 +0100
1.3 @@ -1,1 +1,3 @@
1.4 CTL_GlobalFindDuplicates=Global Find Duplicates
1.5 +DuplicatesListPanel.findMore.text=<html><body><a href="">Look for More</a>
1.6 +DuplicatesListPanel.progressLabel.text=
2.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/duplicates/ComputeDuplicates.java Sat Feb 12 00:49:24 2011 +0100
2.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/duplicates/ComputeDuplicates.java Mon Feb 14 20:43:35 2011 +0100
2.3 @@ -44,7 +44,6 @@
2.4 import java.util.ArrayList;
2.5 import java.util.Arrays;
2.6 import java.util.BitSet;
2.7 -import java.util.Collection;
2.8 import java.util.Collections;
2.9 import java.util.Comparator;
2.10 import java.util.HashSet;
2.11 @@ -54,6 +53,7 @@
2.12 import java.util.List;
2.13 import java.util.Map;
2.14 import java.util.Map.Entry;
2.15 +import java.util.NoSuchElementException;
2.16 import java.util.Set;
2.17 import java.util.concurrent.atomic.AtomicBoolean;
2.18 import org.apache.lucene.document.Document;
2.19 @@ -86,7 +86,7 @@
2.20 */
2.21 public class ComputeDuplicates {
2.22
2.23 - public Collection<? extends DuplicateDescription> computeDuplicatesForAllOpenedProjects(ProgressHandle progress, AtomicBoolean cancel) throws IOException {
2.24 + public Iterator<? extends DuplicateDescription> computeDuplicatesForAllOpenedProjects(ProgressHandle progress, AtomicBoolean cancel) throws IOException {
2.25 Set<URL> urls = new HashSet<URL>();
2.26
2.27 for (ClassPath cp : GlobalPathRegistry.getDefault().getPaths(ClassPath.SOURCE)) {
2.28 @@ -103,7 +103,7 @@
2.29 }
2.30 }
2.31
2.32 - public Collection<? extends DuplicateDescription> computeDuplicates(Set<URL> forURLs, ProgressHandle progress, AtomicBoolean cancel) throws IOException {
2.33 + public Iterator<? extends DuplicateDescription> computeDuplicates(Set<URL> forURLs, ProgressHandle progress, AtomicBoolean cancel) throws IOException {
2.34 Map<IndexReader, FileObject> readers2Roots = new LinkedHashMap<IndexReader, FileObject>();
2.35
2.36 progress.progress("Updating indices");
2.37 @@ -142,19 +142,27 @@
2.38 //TODO: only show valuable duplicates?:
2.39 // dd = dd.subList(0, dd.size() / 10 + 1);
2.40
2.41 - progress.switchToDeterminate(dd.size());
2.42 -
2.43 - List<DuplicateDescription> result = new LinkedList<DuplicateDescription>();
2.44 - int done = 0;
2.45 + return new DuplicatesIterator(readers2Roots, dd);
2.46 + }
2.47
2.48 - for (String longest : dd) {
2.49 + private static final class DuplicatesIterator implements Iterator<DuplicateDescription> {
2.50 + private final Map<IndexReader, FileObject> readers2Roots;
2.51 + private final Iterator<String> duplicateCandidates;
2.52 + private final List<DuplicateDescription> result = new LinkedList<DuplicateDescription>();
2.53 +
2.54 + public DuplicatesIterator(Map<IndexReader, FileObject> readers2Roots, Iterable<String> duplicateCandidates) {
2.55 + this.readers2Roots = readers2Roots;
2.56 + this.duplicateCandidates = duplicateCandidates.iterator();
2.57 + }
2.58 +
2.59 + private DuplicateDescription nextDescription() throws IOException {
2.60 + while (duplicateCandidates.hasNext()) {
2.61 + String longest = duplicateCandidates.next();
2.62 List<Span> foundDuplicates = new LinkedList<Span>();
2.63
2.64 Query query = new TermQuery(new Term("generalized", longest));
2.65
2.66 for (Entry<IndexReader, FileObject> e : readers2Roots.entrySet()) {
2.67 - if (cancel.get()) return Collections.emptyList();
2.68 -
2.69 Searcher s = new IndexSearcher(e.getKey());
2.70 BitSet matchingDocuments = new BitSet(e.getKey().maxDoc());
2.71 Collector c = new BitSetCollector(matchingDocuments);
2.72 @@ -201,16 +209,45 @@
2.73 }
2.74 }
2.75
2.76 - if (add)
2.77 + if (add) {
2.78 result.add(current);
2.79 + return current;
2.80 + }
2.81 }
2.82
2.83 - progress.progress(++done);
2.84 + }
2.85 + return null;
2.86 }
2.87
2.88 - progress.finish();
2.89 + private DuplicateDescription next;
2.90
2.91 - return result;
2.92 + public boolean hasNext() {
2.93 + if (next == null) {
2.94 + try {
2.95 + next = nextDescription();
2.96 + } catch (IOException ex) {
2.97 + Exceptions.printStackTrace(ex);
2.98 + }
2.99 + }
2.100 +
2.101 + return next != null;
2.102 + }
2.103 +
2.104 + public DuplicateDescription next() {
2.105 + if (!hasNext()) {
2.106 + throw new NoSuchElementException();
2.107 + }
2.108 +
2.109 + DuplicateDescription r = next;
2.110 +
2.111 + next = null;
2.112 + return r;
2.113 + }
2.114 +
2.115 + public void remove() {
2.116 + throw new UnsupportedOperationException("Not supported.");
2.117 + }
2.118 +
2.119 }
2.120
2.121 private static List<String> getDuplicatedValues(IndexReader ir, String field, AtomicBoolean cancel) throws IOException {
3.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/duplicates/DuplicatesListPanel.form Sat Feb 12 00:49:24 2011 +0100
3.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/duplicates/DuplicatesListPanel.form Mon Feb 14 20:43:35 2011 +0100
3.3 @@ -1,9 +1,6 @@
3.4 -<?xml version="1.0" encoding="UTF-8" ?>
3.5 +<?xml version="1.1" encoding="UTF-8" ?>
3.6
3.7 <Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
3.8 - <SyntheticProperties>
3.9 - <SyntheticProperty name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,56,0,0,1,-98"/>
3.10 - </SyntheticProperties>
3.11 <AuxValues>
3.12 <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
3.13 <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
3.14 @@ -19,11 +16,12 @@
3.15 <Layout>
3.16 <DimensionLayout dim="0">
3.17 <Group type="103" groupAlignment="0" attributes="0">
3.18 - <Group type="102" alignment="0" attributes="0">
3.19 + <Group type="102" alignment="1" attributes="0">
3.20 <EmptySpace max="-2" attributes="0"/>
3.21 - <Group type="103" groupAlignment="0" attributes="0">
3.22 - <Component id="jSplitPane1" alignment="1" pref="390" max="32767" attributes="0"/>
3.23 - <Component id="jScrollPane4" alignment="1" pref="390" max="32767" attributes="0"/>
3.24 + <Group type="103" groupAlignment="1" attributes="0">
3.25 + <Component id="mainSplit2" alignment="0" pref="906" max="32767" attributes="0"/>
3.26 + <Component id="jScrollPane1" alignment="0" pref="906" max="32767" attributes="0"/>
3.27 + <Component id="jPanel1" alignment="1" min="-2" max="-2" attributes="0"/>
3.28 </Group>
3.29 <EmptySpace max="-2" attributes="0"/>
3.30 </Group>
3.31 @@ -32,99 +30,118 @@
3.32 <DimensionLayout dim="1">
3.33 <Group type="103" groupAlignment="0" attributes="0">
3.34 <Group type="102" attributes="0">
3.35 - <EmptySpace max="-2" attributes="0"/>
3.36 - <Component id="jScrollPane4" min="-2" pref="76" max="-2" attributes="0"/>
3.37 - <EmptySpace max="-2" attributes="0"/>
3.38 - <Component id="jSplitPane1" pref="206" max="32767" attributes="0"/>
3.39 - <EmptySpace max="-2" attributes="0"/>
3.40 + <EmptySpace min="-2" max="-2" attributes="0"/>
3.41 + <Component id="jScrollPane1" min="-2" pref="67" max="-2" attributes="0"/>
3.42 + <EmptySpace min="-2" max="-2" attributes="0"/>
3.43 + <Component id="mainSplit2" pref="467" max="32767" attributes="0"/>
3.44 + <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
3.45 + <Component id="jPanel1" min="-2" max="-2" attributes="0"/>
3.46 + <EmptySpace min="-2" max="-2" attributes="0"/>
3.47 </Group>
3.48 </Group>
3.49 </DimensionLayout>
3.50 </Layout>
3.51 <SubComponents>
3.52 - <Container class="javax.swing.JSplitPane" name="jSplitPane1">
3.53 + <Container class="javax.swing.JScrollPane" name="jScrollPane1">
3.54 +
3.55 + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
3.56 + <SubComponents>
3.57 + <Component class="javax.swing.JList" name="duplicatesList">
3.58 + <Properties>
3.59 + <Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
3.60 + <StringArray count="0"/>
3.61 + </Property>
3.62 + <Property name="prototypeCellValue" type="java.lang.Object" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
3.63 + <Connection code=""9999999999999999999999999999999999999999999999999999999999999999999999"" type="code"/>
3.64 + </Property>
3.65 + <Property name="visibleRowCount" type="int" value="4"/>
3.66 + </Properties>
3.67 + </Component>
3.68 + </SubComponents>
3.69 + </Container>
3.70 + <Container class="javax.swing.JSplitPane" name="mainSplit2">
3.71 + <Properties>
3.72 + <Property name="dividerLocation" type="int" value="400"/>
3.73 + </Properties>
3.74 <AuxValues>
3.75 <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new BalancedSplitPane()"/>
3.76 </AuxValues>
3.77
3.78 <Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
3.79 <SubComponents>
3.80 - <Container class="javax.swing.JScrollPane" name="jScrollPane2">
3.81 - <AuxValues>
3.82 - <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
3.83 - </AuxValues>
3.84 + <Container class="javax.swing.JPanel" name="rightPanel">
3.85 + <Constraints>
3.86 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
3.87 + <JSplitPaneConstraints position="right"/>
3.88 + </Constraint>
3.89 + </Constraints>
3.90 +
3.91 + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
3.92 + <SubComponents>
3.93 + <Component class="javax.swing.JComboBox" name="rightFileList">
3.94 + <Properties>
3.95 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
3.96 + <StringArray count="0"/>
3.97 + </Property>
3.98 + </Properties>
3.99 + <Constraints>
3.100 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.101 + <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="324" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
3.102 + </Constraint>
3.103 + </Constraints>
3.104 + </Component>
3.105 + <Container class="javax.swing.JScrollPane" name="jScrollPane3">
3.106 + <AuxValues>
3.107 + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
3.108 + </AuxValues>
3.109 + <Constraints>
3.110 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.111 + <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="1.0"/>
3.112 + </Constraint>
3.113 + </Constraints>
3.114 +
3.115 + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
3.116 + <SubComponents>
3.117 + <Component class="javax.swing.JEditorPane" name="right">
3.118 + </Component>
3.119 + </SubComponents>
3.120 + </Container>
3.121 + </SubComponents>
3.122 + </Container>
3.123 + <Container class="javax.swing.JPanel" name="leftPanel">
3.124 <Constraints>
3.125 <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
3.126 <JSplitPaneConstraints position="left"/>
3.127 </Constraint>
3.128 </Constraints>
3.129
3.130 - <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
3.131 + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
3.132 <SubComponents>
3.133 - <Component class="javax.swing.JEditorPane" name="left">
3.134 - </Component>
3.135 - </SubComponents>
3.136 - </Container>
3.137 - <Container class="javax.swing.JScrollPane" name="jScrollPane3">
3.138 - <AuxValues>
3.139 - <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
3.140 - </AuxValues>
3.141 - <Constraints>
3.142 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
3.143 - <JSplitPaneConstraints position="right"/>
3.144 - </Constraint>
3.145 - </Constraints>
3.146 + <Container class="javax.swing.JScrollPane" name="jScrollPane2">
3.147 + <AuxValues>
3.148 + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
3.149 + </AuxValues>
3.150 + <Constraints>
3.151 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.152 + <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="1.0"/>
3.153 + </Constraint>
3.154 + </Constraints>
3.155
3.156 - <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
3.157 - <SubComponents>
3.158 - <Component class="javax.swing.JEditorPane" name="right">
3.159 - </Component>
3.160 - </SubComponents>
3.161 - </Container>
3.162 - </SubComponents>
3.163 - </Container>
3.164 - <Container class="javax.swing.JScrollPane" name="jScrollPane4">
3.165 -
3.166 - <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
3.167 - <SubComponents>
3.168 - <Container class="javax.swing.JSplitPane" name="jSplitPane2">
3.169 - <Properties>
3.170 - <Property name="dividerLocation" type="int" value="250"/>
3.171 - <Property name="dividerSize" type="int" value="1"/>
3.172 - </Properties>
3.173 - <AuxValues>
3.174 - <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new BalancedSplitPane()"/>
3.175 - </AuxValues>
3.176 -
3.177 - <Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
3.178 - <SubComponents>
3.179 - <Component class="javax.swing.JList" name="rightList">
3.180 + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
3.181 + <SubComponents>
3.182 + <Component class="javax.swing.JEditorPane" name="left">
3.183 + </Component>
3.184 + </SubComponents>
3.185 + </Container>
3.186 + <Component class="javax.swing.JComboBox" name="leftFileList">
3.187 <Properties>
3.188 - <Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
3.189 - <Connection code="createListModel()" type="code"/>
3.190 - </Property>
3.191 - <Property name="cellRenderer" type="javax.swing.ListCellRenderer" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
3.192 - <Connection code="new RendererImpl(false)" type="code"/>
3.193 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
3.194 + <StringArray count="0"/>
3.195 </Property>
3.196 </Properties>
3.197 <Constraints>
3.198 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
3.199 - <JSplitPaneConstraints position="right"/>
3.200 - </Constraint>
3.201 - </Constraints>
3.202 - </Component>
3.203 - <Component class="javax.swing.JList" name="leftList">
3.204 - <Properties>
3.205 - <Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
3.206 - <Connection code="createListModel()" type="code"/>
3.207 - </Property>
3.208 - <Property name="cellRenderer" type="javax.swing.ListCellRenderer" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
3.209 - <Connection code="new RendererImpl(true)" type="code"/>
3.210 - </Property>
3.211 - </Properties>
3.212 - <Constraints>
3.213 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
3.214 - <JSplitPaneConstraints position="left"/>
3.215 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.216 + <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
3.217 </Constraint>
3.218 </Constraints>
3.219 </Component>
3.220 @@ -132,5 +149,41 @@
3.221 </Container>
3.222 </SubComponents>
3.223 </Container>
3.224 + <Container class="javax.swing.JPanel" name="jPanel1">
3.225 +
3.226 + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
3.227 + <SubComponents>
3.228 + <Component class="javax.swing.JLabel" name="progressLabel">
3.229 + <Properties>
3.230 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
3.231 + <ResourceString bundle="org/netbeans/modules/jackpot30/impl/duplicates/Bundle.properties" key="DuplicatesListPanel.progressLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
3.232 + </Property>
3.233 + </Properties>
3.234 + <Constraints>
3.235 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.236 + <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
3.237 + </Constraint>
3.238 + </Constraints>
3.239 + </Component>
3.240 + <Component class="javax.swing.JLabel" name="findMore">
3.241 + <Properties>
3.242 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
3.243 + <ResourceString bundle="org/netbeans/modules/jackpot30/impl/duplicates/Bundle.properties" key="DuplicatesListPanel.findMore.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
3.244 + </Property>
3.245 + <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor">
3.246 + <Color id="Hand Cursor"/>
3.247 + </Property>
3.248 + </Properties>
3.249 + <Events>
3.250 + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="findMoreMouseClicked"/>
3.251 + </Events>
3.252 + <Constraints>
3.253 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.254 + <GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
3.255 + </Constraint>
3.256 + </Constraints>
3.257 + </Component>
3.258 + </SubComponents>
3.259 + </Container>
3.260 </SubComponents>
3.261 </Form>
4.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/duplicates/DuplicatesListPanel.java Sat Feb 12 00:49:24 2011 +0100
4.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/duplicates/DuplicatesListPanel.java Mon Feb 14 20:43:35 2011 +0100
4.3 @@ -41,14 +41,19 @@
4.4 import java.awt.Color;
4.5 import java.awt.Component;
4.6 import java.awt.Rectangle;
4.7 +import java.awt.event.ActionEvent;
4.8 +import java.awt.event.ActionListener;
4.9 import java.io.IOException;
4.10 import java.util.Collection;
4.11 +import java.util.Iterator;
4.12 +import java.util.LinkedHashSet;
4.13 +import java.util.Set;
4.14 +import javax.swing.DefaultComboBoxModel;
4.15 import javax.swing.DefaultListCellRenderer;
4.16 import javax.swing.DefaultListModel;
4.17 import javax.swing.JEditorPane;
4.18 import javax.swing.JList;
4.19 import javax.swing.JSplitPane;
4.20 -import javax.swing.ListModel;
4.21 import javax.swing.SwingUtilities;
4.22 import javax.swing.event.ListSelectionEvent;
4.23 import javax.swing.event.ListSelectionListener;
4.24 @@ -68,6 +73,8 @@
4.25 import org.openide.filesystems.FileUtil;
4.26 import org.openide.util.Exceptions;
4.27 import org.openide.util.Lookup;
4.28 +import org.openide.util.RequestProcessor;
4.29 +import org.openide.util.RequestProcessor.Task;
4.30 import org.openide.util.lookup.Lookups;
4.31 import org.openide.util.lookup.ServiceProvider;
4.32
4.33 @@ -76,12 +83,14 @@
4.34 * @author lahvac
4.35 */
4.36 public class DuplicatesListPanel extends javax.swing.JPanel {
4.37 - private final Collection<? extends DuplicateDescription> dupes;
4.38 - private final int commonPrefixLength;
4.39 + private final Collection<String> sourceRoots;
4.40 + private final Iterator<? extends DuplicateDescription> dupes;
4.41
4.42 - public DuplicatesListPanel(Collection<? extends DuplicateDescription> dupes) {
4.43 + private int targetCount;
4.44 +
4.45 + public DuplicatesListPanel(Collection<String> sourceRoots, final Iterator<? extends DuplicateDescription> dupes) {
4.46 + this.sourceRoots = sourceRoots;
4.47 this.dupes = dupes;
4.48 - this.commonPrefixLength = computeCommonPrefixLen(dupes);
4.49
4.50 initComponents();
4.51
4.52 @@ -91,20 +100,44 @@
4.53 right.setContentType("text/x-java");
4.54 right.putClientProperty(DuplicatesListPanel.class, new OffsetsBag(right.getDocument()));
4.55
4.56 - leftList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
4.57 + duplicatesList.setModel(new DefaultListModel());
4.58 + duplicatesList.setCellRenderer(new DuplicatesRendererImpl());
4.59 + duplicatesList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
4.60 public void valueChanged(ListSelectionEvent arg0) {
4.61 - setDiff((DuplicateDescription) leftList.getSelectedValue());
4.62 - rightList.setSelectedValue(leftList.getSelectedValue(), false);
4.63 + DuplicateDescription dd = (DuplicateDescription) duplicatesList.getSelectedValue();
4.64 + DefaultComboBoxModel l = new DefaultComboBoxModel();
4.65 + DefaultComboBoxModel r = new DefaultComboBoxModel();
4.66 +
4.67 + for (Span s : dd.dupes) {
4.68 + l.addElement(s);
4.69 + r.addElement(s);
4.70 + }
4.71 +
4.72 + leftFileList.setModel(l);
4.73 + rightFileList.setModel(r);
4.74 +
4.75 + leftFileList.setSelectedIndex(0);
4.76 + rightFileList.setSelectedIndex(1);
4.77 }
4.78 });
4.79
4.80 - rightList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
4.81 - public void valueChanged(ListSelectionEvent arg0) {
4.82 - leftList.setSelectedValue(rightList.getSelectedValue(), false);
4.83 + leftFileList.setRenderer(new SpanRendererImpl());
4.84 + leftFileList.addActionListener(new ActionListener() {
4.85 +
4.86 + public void actionPerformed(ActionEvent e) {
4.87 + setSpan(left, (Span) leftFileList.getSelectedItem());
4.88 + }
4.89 + });
4.90 + rightFileList.setRenderer(new SpanRendererImpl());
4.91 + rightFileList.addActionListener(new ActionListener() {
4.92 + public void actionPerformed(ActionEvent e) {
4.93 + setSpan(right, (Span) rightFileList.getSelectedItem());
4.94 }
4.95 });
4.96
4.97 - leftList.setSelectedIndex(0);
4.98 + progressLabel.setText("Looking for duplicates...");
4.99 +
4.100 + findMore();
4.101 }
4.102
4.103 /** This method is called from within the constructor to
4.104 @@ -115,81 +148,136 @@
4.105 @SuppressWarnings("unchecked")
4.106 // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
4.107 private void initComponents() {
4.108 + java.awt.GridBagConstraints gridBagConstraints;
4.109
4.110 - jSplitPane1 = new BalancedSplitPane();
4.111 + jScrollPane1 = new javax.swing.JScrollPane();
4.112 + duplicatesList = new javax.swing.JList();
4.113 + mainSplit2 = new BalancedSplitPane();
4.114 + rightPanel = new javax.swing.JPanel();
4.115 + rightFileList = new javax.swing.JComboBox();
4.116 + jScrollPane3 = new javax.swing.JScrollPane();
4.117 + right = new javax.swing.JEditorPane();
4.118 + leftPanel = new javax.swing.JPanel();
4.119 jScrollPane2 = new javax.swing.JScrollPane();
4.120 left = new javax.swing.JEditorPane();
4.121 - jScrollPane3 = new javax.swing.JScrollPane();
4.122 - right = new javax.swing.JEditorPane();
4.123 - jScrollPane4 = new javax.swing.JScrollPane();
4.124 - jSplitPane2 = new BalancedSplitPane();
4.125 - rightList = new javax.swing.JList();
4.126 - leftList = new javax.swing.JList();
4.127 + leftFileList = new javax.swing.JComboBox();
4.128 + jPanel1 = new javax.swing.JPanel();
4.129 + progressLabel = new javax.swing.JLabel();
4.130 + findMore = new javax.swing.JLabel();
4.131 +
4.132 + duplicatesList.setPrototypeCellValue("9999999999999999999999999999999999999999999999999999999999999999999999");
4.133 + duplicatesList.setVisibleRowCount(4);
4.134 + jScrollPane1.setViewportView(duplicatesList);
4.135 +
4.136 + mainSplit2.setDividerLocation(400);
4.137 +
4.138 + rightPanel.setLayout(new java.awt.GridBagLayout());
4.139 +
4.140 + gridBagConstraints = new java.awt.GridBagConstraints();
4.141 + gridBagConstraints.gridx = 0;
4.142 + gridBagConstraints.gridy = 0;
4.143 + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
4.144 + gridBagConstraints.ipadx = 324;
4.145 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
4.146 + gridBagConstraints.weightx = 1.0;
4.147 + rightPanel.add(rightFileList, gridBagConstraints);
4.148 +
4.149 + jScrollPane3.setViewportView(right);
4.150 +
4.151 + gridBagConstraints = new java.awt.GridBagConstraints();
4.152 + gridBagConstraints.gridx = 0;
4.153 + gridBagConstraints.gridy = 1;
4.154 + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
4.155 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
4.156 + gridBagConstraints.weightx = 1.0;
4.157 + gridBagConstraints.weighty = 1.0;
4.158 + gridBagConstraints.insets = new java.awt.Insets(6, 0, 0, 0);
4.159 + rightPanel.add(jScrollPane3, gridBagConstraints);
4.160 +
4.161 + mainSplit2.setRightComponent(rightPanel);
4.162 +
4.163 + leftPanel.setLayout(new java.awt.GridBagLayout());
4.164
4.165 jScrollPane2.setViewportView(left);
4.166
4.167 - jSplitPane1.setLeftComponent(jScrollPane2);
4.168 + gridBagConstraints = new java.awt.GridBagConstraints();
4.169 + gridBagConstraints.gridx = 0;
4.170 + gridBagConstraints.gridy = 1;
4.171 + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
4.172 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
4.173 + gridBagConstraints.weightx = 1.0;
4.174 + gridBagConstraints.weighty = 1.0;
4.175 + gridBagConstraints.insets = new java.awt.Insets(6, 0, 0, 0);
4.176 + leftPanel.add(jScrollPane2, gridBagConstraints);
4.177
4.178 - jScrollPane3.setViewportView(right);
4.179 + gridBagConstraints = new java.awt.GridBagConstraints();
4.180 + gridBagConstraints.gridx = 0;
4.181 + gridBagConstraints.gridy = 0;
4.182 + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
4.183 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
4.184 + gridBagConstraints.weightx = 1.0;
4.185 + leftPanel.add(leftFileList, gridBagConstraints);
4.186
4.187 - jSplitPane1.setRightComponent(jScrollPane3);
4.188 + mainSplit2.setLeftComponent(leftPanel);
4.189
4.190 - jSplitPane2.setDividerLocation(250);
4.191 - jSplitPane2.setDividerSize(1);
4.192 + jPanel1.setLayout(new java.awt.GridBagLayout());
4.193
4.194 - rightList.setModel(createListModel());
4.195 - rightList.setCellRenderer(new RendererImpl(false));
4.196 - jSplitPane2.setRightComponent(rightList);
4.197 + progressLabel.setText(org.openide.util.NbBundle.getMessage(DuplicatesListPanel.class, "DuplicatesListPanel.progressLabel.text")); // NOI18N
4.198 + gridBagConstraints = new java.awt.GridBagConstraints();
4.199 + gridBagConstraints.gridx = 0;
4.200 + gridBagConstraints.gridy = 0;
4.201 + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
4.202 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
4.203 + gridBagConstraints.weightx = 1.0;
4.204 + jPanel1.add(progressLabel, gridBagConstraints);
4.205
4.206 - leftList.setModel(createListModel());
4.207 - leftList.setCellRenderer(new RendererImpl(true));
4.208 - jSplitPane2.setLeftComponent(leftList);
4.209 -
4.210 - jScrollPane4.setViewportView(jSplitPane2);
4.211 + findMore.setText(org.openide.util.NbBundle.getMessage(DuplicatesListPanel.class, "DuplicatesListPanel.findMore.text")); // NOI18N
4.212 + findMore.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
4.213 + findMore.addMouseListener(new java.awt.event.MouseAdapter() {
4.214 + public void mouseClicked(java.awt.event.MouseEvent evt) {
4.215 + findMoreMouseClicked(evt);
4.216 + }
4.217 + });
4.218 + gridBagConstraints = new java.awt.GridBagConstraints();
4.219 + gridBagConstraints.gridx = 1;
4.220 + gridBagConstraints.gridy = 0;
4.221 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
4.222 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 0, 0);
4.223 + jPanel1.add(findMore, gridBagConstraints);
4.224
4.225 javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
4.226 this.setLayout(layout);
4.227 layout.setHorizontalGroup(
4.228 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
4.229 - .addGroup(layout.createSequentialGroup()
4.230 + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
4.231 .addContainerGap()
4.232 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
4.233 - .addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 390, Short.MAX_VALUE)
4.234 - .addComponent(jScrollPane4, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 390, Short.MAX_VALUE))
4.235 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
4.236 + .addComponent(mainSplit2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 906, Short.MAX_VALUE)
4.237 + .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 906, Short.MAX_VALUE)
4.238 + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
4.239 .addContainerGap())
4.240 );
4.241 layout.setVerticalGroup(
4.242 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
4.243 .addGroup(layout.createSequentialGroup()
4.244 .addContainerGap()
4.245 - .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 76, javax.swing.GroupLayout.PREFERRED_SIZE)
4.246 + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE)
4.247 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
4.248 - .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 206, Short.MAX_VALUE)
4.249 + .addComponent(mainSplit2, javax.swing.GroupLayout.DEFAULT_SIZE, 467, Short.MAX_VALUE)
4.250 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
4.251 + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
4.252 .addContainerGap())
4.253 );
4.254 }// </editor-fold>//GEN-END:initComponents
4.255
4.256 + private void findMoreMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_findMoreMouseClicked
4.257 + findMore();
4.258 + }//GEN-LAST:event_findMoreMouseClicked
4.259
4.260 - private ListModel createListModel() {
4.261 - DefaultListModel dlm = new DefaultListModel();
4.262 -
4.263 - for (DuplicateDescription dd : dupes) {
4.264 - dlm.addElement(dd);
4.265 - }
4.266 -
4.267 - return dlm;
4.268 - }
4.269 -
4.270 - private static int computeCommonPrefixLen(Collection<? extends DuplicateDescription> dupes) {
4.271 - String commonPrefix = null;
4.272 -
4.273 - for (DuplicateDescription dd : dupes) {
4.274 - for (Span s : dd.dupes) {
4.275 - commonPrefix = computeCommonPrefix(commonPrefix, s.file);
4.276 - }
4.277 - }
4.278 -
4.279 - return commonPrefix != null ? commonPrefix.length() : 0;
4.280 + private void findMore() {
4.281 + targetCount = duplicatesList.getModel().getSize() + 100;
4.282 + findMore.setVisible(false);
4.283 + WORKER.schedule(0);
4.284 }
4.285
4.286 private static String computeCommonPrefix(String origCommonPrefix, FileObject file) {
4.287 @@ -208,11 +296,6 @@
4.288 return origCommonPrefix;
4.289 }
4.290
4.291 - private void setDiff(DuplicateDescription dd) {
4.292 - setSpan(left, dd.dupes.get(0));
4.293 - setSpan(right, dd.dupes.get(1));
4.294 - }
4.295 -
4.296 private static void setSpan(JEditorPane pane, Span s) {
4.297 try {
4.298 pane.setText(s.file.asText());
4.299 @@ -241,17 +324,49 @@
4.300
4.301 private static final AttributeSet HIGHLIGHT = AttributesUtilities.createImmutable(StyleConstants.Background, new Color(0xDF, 0xDF, 0xDF, 0xff));
4.302
4.303 - private final class RendererImpl extends DefaultListCellRenderer {
4.304 - private final boolean left;
4.305 - public RendererImpl(boolean left) {
4.306 - this.left = left;
4.307 - }
4.308 + private final class DuplicatesRendererImpl extends DefaultListCellRenderer {
4.309 @Override
4.310 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
4.311 + if (!(value instanceof DuplicateDescription)) return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
4.312 DuplicateDescription dd = (DuplicateDescription) value;
4.313 - String name = left ? FileUtil.getFileDisplayName(dd.dupes.get(0).file).substring(commonPrefixLength) : FileUtil.getFileDisplayName(dd.dupes.get(1).file).substring(commonPrefixLength);
4.314 + Set<FileObject> files = new LinkedHashSet<FileObject>();
4.315 + String commonPrefix = null;
4.316
4.317 - return super.getListCellRendererComponent(list, name, index, isSelected, cellHasFocus);
4.318 + for (Span s : dd.dupes) {
4.319 + commonPrefix = computeCommonPrefix(commonPrefix, s.file);
4.320 + files.add(s.file);
4.321 + }
4.322 +
4.323 + StringBuilder cap = new StringBuilder();
4.324 +
4.325 + OUTER: for (FileObject file : files) {
4.326 + String name = FileUtil.getFileDisplayName(file);
4.327 +
4.328 + if (cap.length() > 0) {
4.329 + cap.append(" ");
4.330 + }
4.331 +
4.332 + for (String sr : sourceRoots) {
4.333 + if (name.startsWith(sr)) {
4.334 + cap.append(name.substring(Math.max(0, sr.lastIndexOf('/') + 1)));
4.335 + continue OUTER;
4.336 + }
4.337 + }
4.338 + }
4.339 +
4.340 + return super.getListCellRendererComponent(list, cap.toString(), index, isSelected, cellHasFocus);
4.341 + }
4.342 + }
4.343 +
4.344 + private final class SpanRendererImpl extends DefaultListCellRenderer {
4.345 + @Override
4.346 + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
4.347 + if (!(value instanceof Span)) {
4.348 + return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
4.349 + }
4.350 + Span span = (Span) value;
4.351 +
4.352 + return super.getListCellRendererComponent(list, FileUtil.getFileDisplayName(span.file), index, isSelected, cellHasFocus);
4.353 }
4.354 }
4.355
4.356 @@ -287,6 +402,7 @@
4.357 private static final class BalancedSplitPane extends JSplitPane {
4.358
4.359 @Override
4.360 + @SuppressWarnings("deprecation")
4.361 public void reshape(int x, int y, int w, int h) {
4.362 super.reshape(x, y, w, h);
4.363 SwingUtilities.invokeLater(new Runnable() {
4.364 @@ -299,15 +415,50 @@
4.365 }
4.366
4.367 // Variables declaration - do not modify//GEN-BEGIN:variables
4.368 + private javax.swing.JList duplicatesList;
4.369 + private javax.swing.JLabel findMore;
4.370 + private javax.swing.JPanel jPanel1;
4.371 + private javax.swing.JScrollPane jScrollPane1;
4.372 private javax.swing.JScrollPane jScrollPane2;
4.373 private javax.swing.JScrollPane jScrollPane3;
4.374 - private javax.swing.JScrollPane jScrollPane4;
4.375 - private javax.swing.JSplitPane jSplitPane1;
4.376 - private javax.swing.JSplitPane jSplitPane2;
4.377 private javax.swing.JEditorPane left;
4.378 - private javax.swing.JList leftList;
4.379 + private javax.swing.JComboBox leftFileList;
4.380 + private javax.swing.JPanel leftPanel;
4.381 + private javax.swing.JSplitPane mainSplit2;
4.382 + private javax.swing.JLabel progressLabel;
4.383 private javax.swing.JEditorPane right;
4.384 - private javax.swing.JList rightList;
4.385 + private javax.swing.JComboBox rightFileList;
4.386 + private javax.swing.JPanel rightPanel;
4.387 // End of variables declaration//GEN-END:variables
4.388
4.389 + private static final RequestProcessor DEFAULT_WORKER = new RequestProcessor(DuplicatesListPanel.class.getName(), 1, false, false);
4.390 + private final Task WORKER = DEFAULT_WORKER.create(new Runnable() {
4.391 + public void run() {
4.392 + if (dupes.hasNext()) {
4.393 + final DuplicateDescription dd = dupes.next();
4.394 +
4.395 + SwingUtilities.invokeLater(new Runnable() {
4.396 +
4.397 + public void run() {
4.398 + ((DefaultListModel)duplicatesList.getModel()).addElement(dd);
4.399 +
4.400 + int size = duplicatesList.getModel().getSize();
4.401 +
4.402 + if (size == 1) {
4.403 + duplicatesList.setSelectedIndex(0);
4.404 + }
4.405 +
4.406 + if (size >= targetCount) {
4.407 + findMore.setVisible(true);
4.408 + progressLabel.setText("Found " + size + " duplicated snippets.");
4.409 + } else {
4.410 + progressLabel.setText("Found " + size + " duplicated snippets and searching...");
4.411 + WORKER.schedule(0);
4.412 + }
4.413 + }
4.414 + });
4.415 + }
4.416 + }
4.417 + });
4.418 +
4.419 }
5.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/duplicates/GlobalFindDuplicates.java Sat Feb 12 00:49:24 2011 +0100
5.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/duplicates/GlobalFindDuplicates.java Mon Feb 14 20:43:35 2011 +0100
5.3 @@ -46,18 +46,22 @@
5.4 import java.awt.event.ActionListener;
5.5 import java.io.IOException;
5.6 import java.util.Collection;
5.7 -import java.util.Collections;
5.8 +import java.util.Iterator;
5.9 import java.util.LinkedList;
5.10 import java.util.concurrent.atomic.AtomicBoolean;
5.11 import javax.swing.JLabel;
5.12 import javax.swing.JPanel;
5.13 import javax.swing.SwingUtilities;
5.14 +import org.netbeans.api.java.classpath.ClassPath;
5.15 +import org.netbeans.api.java.classpath.GlobalPathRegistry;
5.16 import org.netbeans.api.progress.ProgressHandle;
5.17 import org.netbeans.api.progress.ProgressHandleFactory;
5.18 import org.netbeans.modules.jackpot30.impl.duplicates.ComputeDuplicates.DuplicateDescription;
5.19 import org.openide.DialogDescriptor;
5.20 import org.openide.DialogDisplayer;
5.21 import org.openide.NotifyDescriptor;
5.22 +import org.openide.filesystems.FileObject;
5.23 +import org.openide.filesystems.FileUtil;
5.24 import org.openide.util.Exceptions;
5.25 import org.openide.util.HelpCtx;
5.26 import org.openide.util.RequestProcessor;
5.27 @@ -65,7 +69,7 @@
5.28 public final class GlobalFindDuplicates implements ActionListener {
5.29
5.30 public void actionPerformed(ActionEvent e) {
5.31 - final Collection<DuplicateDescription> dupes = Collections.synchronizedList(new LinkedList<DuplicateDescription>());
5.32 + final Iterator<? extends DuplicateDescription>[] dupes = new Iterator[1];
5.33 final ProgressHandle handle = ProgressHandleFactory.createHandle("Compute Duplicates");
5.34 JPanel panel = createPanel(handle);
5.35 final AtomicBoolean cancel = new AtomicBoolean();
5.36 @@ -79,11 +83,22 @@
5.37
5.38 final Dialog d = DialogDisplayer.getDefault().createDialog(w);
5.39 final AtomicBoolean done = new AtomicBoolean();
5.40 + final Collection<String> sourceRoots = new LinkedList<String>();
5.41
5.42 WORKER.post(new Runnable() {
5.43 public void run() {
5.44 try {
5.45 - dupes.addAll(new ComputeDuplicates().computeDuplicatesForAllOpenedProjects(handle, cancel));
5.46 + for (ClassPath cp : GlobalPathRegistry.getDefault().getPaths(ClassPath.SOURCE)) {
5.47 + for (ClassPath.Entry e : cp.entries()) {
5.48 + FileObject root = e.getRoot();
5.49 +
5.50 + if (root == null) continue;
5.51 +
5.52 + sourceRoots.add(FileUtil.getFileDisplayName(root));
5.53 + }
5.54 + }
5.55 +
5.56 + dupes[0] = new ComputeDuplicates().computeDuplicatesForAllOpenedProjects(handle, cancel);
5.57 done.set(true);
5.58 } catch (IOException ex) {
5.59 Exceptions.printStackTrace(ex);
5.60 @@ -111,7 +126,7 @@
5.61
5.62 if (cancel.get()) return;
5.63
5.64 - NotifyDescriptor nd = new NotifyDescriptor.Message(new DuplicatesListPanel(dupes));
5.65 + NotifyDescriptor nd = new NotifyDescriptor.Message(new DuplicatesListPanel(sourceRoots, dupes[0]));
5.66
5.67 DialogDisplayer.getDefault().notifyLater(nd);
5.68 }
6.1 --- a/api/test/unit/src/org/netbeans/modules/jackpot30/impl/duplicates/ComputeDuplicatesTest.java Sat Feb 12 00:49:24 2011 +0100
6.2 +++ b/api/test/unit/src/org/netbeans/modules/jackpot30/impl/duplicates/ComputeDuplicatesTest.java Mon Feb 14 20:43:35 2011 +0100
6.3 @@ -42,6 +42,7 @@
6.4 import org.netbeans.api.progress.ProgressHandle;
6.5 import org.openide.filesystems.FileObject;
6.6 import java.util.HashMap;
6.7 +import java.util.LinkedList;
6.8 import java.util.Map;
6.9 import java.util.concurrent.atomic.AtomicBoolean;
6.10 import org.netbeans.api.java.source.TestUtilities;
6.11 @@ -51,6 +52,7 @@
6.12 import org.netbeans.modules.jackpot30.impl.indexing.IndexTestBase;
6.13 import org.netbeans.modules.jackpot30.impl.indexing.IndexingTestUtils.File;
6.14 import org.openide.filesystems.FileUtil;
6.15 +import org.openide.util.NbCollections;
6.16 import static org.junit.Assert.*;
6.17
6.18 import static org.netbeans.modules.jackpot30.impl.indexing.IndexingTestUtils.writeFilesAndWaitForScan;
6.19 @@ -101,7 +103,7 @@
6.20
6.21 handle.start();
6.22
6.23 - for (DuplicateDescription dd : new ComputeDuplicates().computeDuplicatesForAllOpenedProjects(handle, new AtomicBoolean())) {
6.24 + for (DuplicateDescription dd : NbCollections.iterable(new ComputeDuplicates().computeDuplicatesForAllOpenedProjects(handle, new AtomicBoolean()))) {
6.25 for (Span s : dd.dupes) {
6.26 duplicatesReal.put(relativePath(s.file), TestUtilities.copyFileToString(FileUtil.toFile(s.file)).substring(s.startOff, s.endOff));
6.27 }