This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 209038
Collapse All | Expand All

(-)a/java.source/apichanges.xml (+13 lines)
Lines 108-113 Link Here
108
    <!-- ACTUAL CHANGES BEGIN HERE: -->
108
    <!-- ACTUAL CHANGES BEGIN HERE: -->
109
109
110
    <changes>
110
    <changes>
111
        <change id="references-count">
112
             <api name="general"/>
113
             <summary>Added <code>ReferencesCount</code> support class which provides frequences of type usage in a source root.</summary>
114
             <version major="0" minor="97"/>
115
             <date day="11" month="3" year="2012"/>
116
             <author login="tzezula"/>
117
             <compatibility addition="yes" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="compatible" source="compatible"/>
118
             <description>
119
                 Added <code>ReferencesCount</code> support class which provides information how many classes on the source path (source root) are using
120
                 given type or package.
121
             </description>
122
             <issue number="209038"/>
123
        </change>
111
        <change id="class-members-order">
124
        <change id="class-members-order">
112
             <api name="general"/>
125
             <api name="general"/>
113
             <summary>Added several methods to <code>CodeStyle</code> supporting customization of the generated class members order and other minor formatting enhancements.</summary>
126
             <summary>Added several methods to <code>CodeStyle</code> supporting customization of the generated class members order and other minor formatting enhancements.</summary>
(-)a/java.source/nbproject/project.properties (-1 / +1 lines)
Lines 46-52 Link Here
46
javadoc.title=Java Source
46
javadoc.title=Java Source
47
javadoc.arch=${basedir}/arch.xml
47
javadoc.arch=${basedir}/arch.xml
48
javadoc.apichanges=${basedir}/apichanges.xml
48
javadoc.apichanges=${basedir}/apichanges.xml
49
spec.version.base=0.96.0
49
spec.version.base=0.97.0
50
test.qa-functional.cp.extra=${refactoring.java.dir}/modules/ext/javac-api-nb-7.0-b07.jar
50
test.qa-functional.cp.extra=${refactoring.java.dir}/modules/ext/javac-api-nb-7.0-b07.jar
51
test.unit.run.cp.extra=${o.n.core.dir}/core/core.jar:\
51
test.unit.run.cp.extra=${o.n.core.dir}/core/core.jar:\
52
    ${o.n.core.dir}/lib/boot.jar:\
52
    ${o.n.core.dir}/lib/boot.jar:\
(-)a/java.source/nbproject/project.xml (-1 / +1 lines)
Lines 267-273 Link Here
267
                    <compile-dependency/>
267
                    <compile-dependency/>
268
                    <run-dependency>
268
                    <run-dependency>
269
                        <release-version>2</release-version>
269
                        <release-version>2</release-version>
270
                        <specification-version>2.9</specification-version>
270
                        <specification-version>2.10</specification-version>
271
                    </run-dependency>
271
                    </run-dependency>
272
                </dependency>
272
                </dependency>
273
                <dependency>
273
                <dependency>
(-)a/java.source/src/org/netbeans/api/java/source/support/ReferencesCount.java (+275 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.java.source.support;
43
44
import java.io.IOException;
45
import java.net.URL;
46
import java.util.ArrayList;
47
import java.util.Collections;
48
import java.util.HashMap;
49
import java.util.Iterator;
50
import java.util.List;
51
import java.util.Map;
52
import javax.lang.model.element.ElementKind;
53
import javax.lang.model.element.PackageElement;
54
import javax.lang.model.element.TypeElement;
55
import org.netbeans.api.annotations.common.NonNull;
56
import org.netbeans.api.java.classpath.ClassPath;
57
import org.netbeans.api.java.source.ClasspathInfo;
58
import org.netbeans.api.java.source.ElementHandle;
59
import org.netbeans.api.java.source.SourceUtils;
60
import org.netbeans.modules.java.source.ElementHandleAccessor;
61
import org.netbeans.modules.java.source.usages.ClassIndexImpl;
62
import org.netbeans.modules.java.source.usages.ClassIndexManager;
63
import org.netbeans.modules.parsing.lucene.support.Convertor;
64
import org.openide.util.Parameters;
65
66
/**
67
 * Provides an information about frequencies of type and package usages
68
 * in given source root or source path.
69
 * @since 0.97
70
 * @author Tomas Zezula
71
 */
72
public final class ReferencesCount {
73
    
74
    private final Object lck = new Object();
75
    private final Iterable<? extends URL> roots;
76
    //@GuardedBy("lck")
77
    private Map<String,Integer> typeFreqs;
78
    //@GuardedBy("lck")
79
    private Map<String,Integer> pkgFreqs;
80
    
81
    private ReferencesCount(@NonNull final Iterable<? extends URL> roots) {
82
        this.roots = roots;
83
    }
84
    
85
    /**
86
     * Returns a number of classes on given source path (source root) which are
87
     * using given type.
88
     * @param type the type type to find the usage frequency for.
89
     * @return number of classes using the type.
90
     */
91
    public int getTypeReferenceCount(@NonNull final ElementHandle<? extends TypeElement> type) {
92
        Parameters.notNull("binaryName", type);   //NOI18N
93
        if (!type.getKind().isClass() &&
94
            !type.getKind().isInterface() &&
95
             type.getKind() != ElementKind.OTHER) {
96
            throw new IllegalArgumentException(type.toString());
97
        }
98
        try {
99
            init();
100
            final Integer count = typeFreqs.get(SourceUtils.getJVMSignature(type)[0]);
101
            return count == null ? 0 : count;
102
        } catch (InterruptedException ie) {
103
            return 0;
104
        }
105
    }
106
    
107
    /**
108
     * Returns a number of classes on given source path (source root) which are
109
     * using given package.
110
     * @param pkg  the package to find the usage frequency for.
111
     * @return number of classes using types from given package.
112
     */
113
    public int getPackageReferenceCount(@NonNull final ElementHandle<? extends PackageElement> pkg) {
114
        Parameters.notNull("pkgName", pkg); //NOI18N
115
        if (pkg.getKind() != ElementKind.PACKAGE) {
116
            throw new IllegalArgumentException(pkg.toString());
117
        }
118
        try {
119
            init();
120
            final Integer count = pkgFreqs.get(SourceUtils.getJVMSignature(pkg)[0]);
121
            return count == null ? 0 : count;
122
        } catch (InterruptedException ie) {
123
            return 0;
124
        }
125
    }
126
    
127
    /**
128
     * Returns all types used by classes on given source path (source root).
129
     * @return the used classes
130
     */
131
    @NonNull
132
    public Iterable<? extends ElementHandle<? extends TypeElement>> getUsedTypes() {
133
        try {
134
            init();
135
            return new AsHandlesIterable<String, ElementHandle<TypeElement>>(
136
                typeFreqs.keySet(),
137
                new Convertor<String, ElementHandle<TypeElement>>() {
138
                    @NonNull
139
                    @Override
140
                    public ElementHandle<TypeElement> convert(@NonNull final String p) {
141
                        return ElementHandleAccessor.INSTANCE.create(ElementKind.OTHER, p);   //FIXME
142
                    }
143
                });
144
        } catch (InterruptedException ie) {
145
            return Collections.<ElementHandle<TypeElement>>emptySet();
146
        }
147
    }
148
    
149
    /**
150
     * Returns all packages used by classes on given source path (source root).
151
     * @return the used packages
152
     */
153
    @NonNull
154
    public Iterable<? extends ElementHandle<? extends PackageElement>> getUsedPackages() {
155
        try {
156
            init();
157
            return new AsHandlesIterable<String, ElementHandle<PackageElement>>(
158
                pkgFreqs.keySet(),
159
                new Convertor<String, ElementHandle<PackageElement>>() {
160
                    @NonNull
161
                    @Override
162
                    public ElementHandle<PackageElement> convert(@NonNull final String p) {
163
                        return ElementHandleAccessor.INSTANCE.create(ElementKind.PACKAGE, p);
164
                    }
165
                });
166
        } catch (InterruptedException ie) {
167
            return Collections.<ElementHandle<PackageElement>>emptySet();
168
        }
169
    }
170
    
171
    private void init() throws InterruptedException {
172
        synchronized (lck) {
173
            if (typeFreqs == null) {
174
                final ClassIndexManager cim = ClassIndexManager.getDefault();
175
                final Map<String,Integer> typef = new HashMap<String, Integer>();
176
                final Map<String,Integer> pkgf = new HashMap<String, Integer>();
177
                try {
178
                    for (URL root : roots) {
179
                        final ClassIndexImpl ci = cim.getUsagesQuery(root, true);
180
                        ci.getReferencesFrequences(typef, pkgf);
181
                    }
182
                    typeFreqs = Collections.<String,Integer>unmodifiableMap(typef);
183
                    pkgFreqs = Collections.<String,Integer>unmodifiableMap(pkgf);
184
                } catch (IOException ioe) {
185
                    typeFreqs = Collections.<String,Integer>emptyMap();
186
                    pkgFreqs = Collections.<String,Integer>emptyMap();
187
                }
188
            }
189
        }
190
        assert typeFreqs != null;
191
        assert pkgFreqs != null;
192
    }
193
    
194
    private static class AsHandlesIterable<P,R> implements Iterable<R> {
195
        
196
        private final Iterable<P> from;
197
        private final Convertor<P,R> fnc;
198
        
199
        private AsHandlesIterable(
200
            @NonNull Iterable<P> from,
201
            @NonNull Convertor<P,R> fnc) {
202
            assert from != null;
203
            assert fnc != null;
204
            this.from = from;
205
            this.fnc = fnc;
206
        }
207
208
        @Override
209
        public Iterator<R> iterator() {
210
            return new AsHandlesIterator<P, R>(from.iterator(),fnc);
211
        }
212
        
213
    }
214
    
215
    private static class AsHandlesIterator<P,R> implements Iterator<R> {
216
        
217
        private final Iterator<P> from;
218
        private final Convertor<P,R> fnc;
219
        
220
        private AsHandlesIterator(
221
            @NonNull Iterator<P> from,
222
            @NonNull Convertor<P,R> fnc) {
223
            assert from != null;
224
            assert fnc != null;
225
            this.from = from;
226
            this.fnc = fnc;
227
        }
228
229
        @Override
230
        public boolean hasNext() {
231
            return from.hasNext();
232
        }
233
234
        @Override
235
        public R next() {
236
            return fnc.convert(from.next());
237
        }
238
239
        @Override
240
        public void remove() {
241
            throw new UnsupportedOperationException("Read only Collection.");   //NOI18N
242
        }
243
        
244
        
245
    }
246
    
247
    /**
248
     * Creates a {@link ReferencesCount} for source classpath represented by given
249
     * {@link ClasspathInfo}.
250
     * @param cpInfo the {@link ClasspathInfo} to create {@link ReferencesCount} for.
251
     * @return the {@link ReferencesCount}
252
     */
253
    @NonNull
254
    public static ReferencesCount get(@NonNull final ClasspathInfo cpInfo) {
255
        Parameters.notNull("cpInfo", cpInfo);   //NOI18N
256
        final List<? extends ClassPath.Entry> scp = cpInfo.getClassPath(ClasspathInfo.PathKind.SOURCE).entries();
257
        final List<URL> roots = new ArrayList<URL>(scp.size());
258
        for (ClassPath.Entry e : scp) {
259
            roots.add(e.getURL());
260
        }
261
        return new ReferencesCount(roots);
262
    }
263
    
264
    
265
    /**
266
     * Creates a {@link ReferencesCount} for source root.
267
     * @param root the root to create {@link ReferencesCount} for.
268
     * @return the {@link ReferencesCount}
269
     */
270
    @NonNull
271
    public static ReferencesCount get(@NonNull final URL root) {
272
        Parameters.notNull("cpInfo", root);   //NOI18N
273
        return new ReferencesCount(Collections.<URL>singleton(root));
274
    }
275
}
(-)a/java.source/src/org/netbeans/modules/java/source/usages/ClassIndexImpl.java (+4 lines)
Lines 135-140 Link Here
135
    
135
    
136
    public abstract void getPackageNames (String prefix, boolean directOnly, Set<String> result) throws IOException, InterruptedException;
136
    public abstract void getPackageNames (String prefix, boolean directOnly, Set<String> result) throws IOException, InterruptedException;
137
    
137
    
138
    public abstract void getReferencesFrequences (
139
            @NonNull final Map<String,Integer> typeFreq,
140
            @NonNull final Map<String,Integer> pkgFreq) throws IOException, InterruptedException;
141
    
138
    public abstract FileObject[] getSourceRoots ();
142
    public abstract FileObject[] getSourceRoots ();
139
   
143
   
140
    public abstract BinaryAnalyser getBinaryAnalyser ();
144
    public abstract BinaryAnalyser getBinaryAnalyser ();
(-)a/java.source/src/org/netbeans/modules/java/source/usages/DocumentUtil.java (-9 / +11 lines)
Lines 218-233 Link Here
218
        final Set<? extends ClassIndexImpl.UsageType> usageType,
218
        final Set<? extends ClassIndexImpl.UsageType> usageType,
219
        final boolean javaRegEx) {
219
        final boolean javaRegEx) {
220
        assert resourceName  != null;
220
        assert resourceName  != null;
221
        final char wildcard = javaRegEx ? REGEX_QUERY_WILDCARD : WILDCARD_QUERY_WILDCARD;
221
        if (!resourceName.isEmpty()) {
222
        final char[] yes = javaRegEx ? new char[] {'\\',YES} : new char[] {YES};
222
            final char wildcard = javaRegEx ? REGEX_QUERY_WILDCARD : WILDCARD_QUERY_WILDCARD;
223
        if (usageType != null) {
223
            final char[] yes = javaRegEx ? new char[] {'\\',YES} : new char[] {YES};
224
            resourceName = encodeUsage (resourceName, usageType, wildcard, yes).toString();
224
            if (usageType != null) {
225
        } else {
225
                resourceName = encodeUsage (resourceName, usageType, wildcard, yes).toString();
226
            final StringBuilder sb = new StringBuilder (resourceName);
226
            } else {
227
            for (int i = 0; i< SIZE; i++) {
227
                final StringBuilder sb = new StringBuilder (resourceName);
228
                sb.append(wildcard);
228
                for (int i = 0; i< SIZE; i++) {
229
                    sb.append(wildcard);
230
                }
231
                resourceName = sb.toString();
229
            }
232
            }
230
            resourceName = sb.toString();
231
        }
233
        }
232
        return new Term (FIELD_REFERENCES, resourceName);
234
        return new Term (FIELD_REFERENCES, resourceName);
233
    }
235
    }
(-)a/java.source/src/org/netbeans/modules/java/source/usages/PersistentClassIndex.java (+78 lines)
Lines 53-58 Link Here
53
import java.util.logging.Logger;
53
import java.util.logging.Logger;
54
import javax.lang.model.element.ElementKind;
54
import javax.lang.model.element.ElementKind;
55
import org.apache.lucene.document.Document;
55
import org.apache.lucene.document.Document;
56
import org.apache.lucene.index.IndexReader;
56
import org.apache.lucene.index.Term;
57
import org.apache.lucene.index.Term;
57
import org.apache.lucene.search.BooleanClause.Occur;
58
import org.apache.lucene.search.BooleanClause.Occur;
58
import org.apache.lucene.search.Query;
59
import org.apache.lucene.search.Query;
Lines 70-77 Link Here
70
import org.netbeans.modules.parsing.lucene.support.Convertor;
71
import org.netbeans.modules.parsing.lucene.support.Convertor;
71
import org.netbeans.modules.parsing.lucene.support.Index;
72
import org.netbeans.modules.parsing.lucene.support.Index;
72
import org.netbeans.modules.parsing.lucene.support.IndexManager;
73
import org.netbeans.modules.parsing.lucene.support.IndexManager;
74
import org.netbeans.modules.parsing.lucene.support.IndexReaderInjection;
73
import org.netbeans.modules.parsing.lucene.support.Queries;
75
import org.netbeans.modules.parsing.lucene.support.Queries;
74
import org.netbeans.modules.parsing.lucene.support.StoppableConvertor;
76
import org.netbeans.modules.parsing.lucene.support.StoppableConvertor;
77
import org.netbeans.modules.parsing.lucene.support.StoppableConvertor.Stop;
75
import org.openide.filesystems.FileObject;
78
import org.openide.filesystems.FileObject;
76
import org.openide.filesystems.FileUtil;
79
import org.openide.filesystems.FileUtil;
77
import org.openide.filesystems.URLMapper;
80
import org.openide.filesystems.URLMapper;
Lines 368-373 Link Here
368
            this.<Void,IOException>handleException(null, ioe);
371
            this.<Void,IOException>handleException(null, ioe);
369
        }
372
        }
370
    }
373
    }
374
    
375
    @Override
376
    public void getReferencesFrequences (
377
            @NonNull final Map<String,Integer> typeFreq,
378
            @NonNull final Map<String,Integer> pkgFreq) throws IOException, InterruptedException {
379
        assert typeFreq != null;
380
        assert pkgFreq != null;
381
        try {
382
            IndexManager.priorityAccess(new IndexManager.Action<Void>() {
383
                @Override
384
                public Void run() throws IOException, InterruptedException {
385
                    final Term startTerm = DocumentUtil.referencesTerm("", null, true);    //NOI18N
386
                    final StoppableConvertor<Term,Void> convertor = new FreqCollector(
387
                            startTerm, typeFreq, pkgFreq);
388
                    index.queryTerms(
389
                        Collections.<Void>emptyList(),
390
                        startTerm,
391
                        convertor,
392
                        cancel.get());
393
                    return null;
394
                }
395
            });
396
        } catch (IOException ioe) {
397
            this.<Void,IOException>handleException(null, ioe);
398
        }
399
    }
371
        
400
        
372
    @Override
401
    @Override
373
    public void setDirty (final URL url) {
402
    public void setDirty (final URL url) {
Lines 657-660 Link Here
657
            }
686
            }
658
        }
687
        }
659
    }
688
    }
689
    
690
    private static final class FreqCollector implements StoppableConvertor<Term, Void>, IndexReaderInjection {
691
        
692
        private final String fieldName;
693
        private final Map<String,Integer> typeFreq;
694
        private final Map<String,Integer> pkgFreq;
695
        private IndexReader in;
696
        
697
        
698
        FreqCollector(
699
                @NonNull final Term startTerm,
700
                @NonNull final Map<String,Integer> typeFreqs,
701
                @NonNull final Map<String,Integer> pkgFreq) {
702
            this.fieldName = startTerm.field();
703
            this.typeFreq = typeFreqs;
704
            this.pkgFreq = pkgFreq;
705
        }
706
707
        @CheckForNull
708
        @Override
709
        public Void convert(@NonNull final Term param) throws Stop {
710
            if (fieldName != param.field()) {
711
                throw new Stop();
712
            }
713
            try {
714
                final String encBinName = param.text();
715
                final String binName = encBinName.substring(
716
                    0,
717
                    encBinName.length() - ClassIndexImpl.UsageType.values().length);
718
                final int dotIndex = binName.lastIndexOf('.');  //NOI18N
719
                final String pkgName = dotIndex == -1 ? "" : binName.substring(0, dotIndex);    //NOI18N
720
                final int docCount = in.docFreq(param);
721
                final Integer typeCount = typeFreq.get(binName);
722
                final Integer pkgCount = pkgFreq.get(pkgName);
723
                typeFreq.put(binName, typeCount == null ? docCount : docCount + typeCount);
724
                pkgFreq.put(pkgName, pkgCount == null ? docCount : docCount + pkgCount);                
725
            } catch (IOException ioe) {
726
                Exceptions.printStackTrace(ioe);
727
                throw new Stop();
728
            }
729
            return null;
730
        }
731
732
        @Override
733
        public void setIndexReader(IndexReader indexReader) {
734
            in = indexReader;
735
        }
736
        
737
    }
660
}
738
}

Return to bug 209038