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 202063
Collapse All | Expand All

(-)a/java.editor/nbproject/project.properties (-1 / +1 lines)
Lines 42-48 Link Here
42
42
43
javadoc.title=Java Editor
43
javadoc.title=Java Editor
44
44
45
spec.version.base=2.37.0
45
spec.version.base=2.38.0
46
test.qa-functional.cp.extra=${editor.dir}/modules/org-netbeans-modules-editor-fold.jar
46
test.qa-functional.cp.extra=${editor.dir}/modules/org-netbeans-modules-editor-fold.jar
47
javac.source=1.6
47
javac.source=1.6
48
#test.unit.cp.extra=
48
#test.unit.cp.extra=
(-)a/java.editor/nbproject/project.xml (-10 / +1 lines)
Lines 285-299 Link Here
285
                    </run-dependency>
285
                    </run-dependency>
286
                </dependency>
286
                </dependency>
287
                <dependency>
287
                <dependency>
288
                    <code-name-base>org.netbeans.modules.parsing.lucene</code-name-base>
289
                    <build-prerequisite/>
290
                    <compile-dependency/>
291
                    <run-dependency>
292
                        <release-version>2</release-version>
293
                        <specification-version>2.3</specification-version>
294
                    </run-dependency>
295
                </dependency>
296
                <dependency>
297
                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
288
                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
298
                    <build-prerequisite/>
289
                    <build-prerequisite/>
299
                    <compile-dependency/>
290
                    <compile-dependency/>
Lines 315-321 Link Here
315
                    <build-prerequisite/>
306
                    <build-prerequisite/>
316
                    <compile-dependency/>
307
                    <compile-dependency/>
317
                    <run-dependency>
308
                    <run-dependency>
318
                        <specification-version>1.0</specification-version>
309
                        <specification-version>1.2</specification-version>
319
                    </run-dependency>
310
                    </run-dependency>
320
                </dependency>
311
                </dependency>
321
                <dependency>
312
                <dependency>
(-)a/java.editor/src/org/netbeans/modules/java/editor/whitelist/WhiteListCheckTask.java (-13 / +21 lines)
Lines 42-53 Link Here
42
package org.netbeans.modules.java.editor.whitelist;
42
package org.netbeans.modules.java.editor.whitelist;
43
43
44
import com.sun.source.tree.CompilationUnitTree;
44
import com.sun.source.tree.CompilationUnitTree;
45
import com.sun.source.tree.Tree;
45
import com.sun.source.util.SourcePositions;
46
import com.sun.source.util.SourcePositions;
46
import java.util.ArrayList;
47
import java.util.ArrayList;
47
import java.util.Collection;
48
import java.util.Collection;
48
import java.util.Collections;
49
import java.util.Collections;
49
import java.util.LinkedList;
50
import java.util.List;
50
import java.util.List;
51
import java.util.Map;
52
import java.util.concurrent.Callable;
51
import java.util.concurrent.atomic.AtomicBoolean;
53
import java.util.concurrent.atomic.AtomicBoolean;
52
import org.netbeans.api.editor.mimelookup.MimeRegistration;
54
import org.netbeans.api.editor.mimelookup.MimeRegistration;
53
import org.netbeans.api.java.source.CompilationInfo;
55
import org.netbeans.api.java.source.CompilationInfo;
Lines 65-70 Link Here
65
import org.netbeans.spi.editor.hints.ErrorDescriptionFactory;
67
import org.netbeans.spi.editor.hints.ErrorDescriptionFactory;
66
import org.netbeans.spi.editor.hints.HintsController;
68
import org.netbeans.spi.editor.hints.HintsController;
67
import org.netbeans.spi.editor.hints.Severity;
69
import org.netbeans.spi.editor.hints.Severity;
70
import org.netbeans.api.whitelist.support.WhiteListSupport;
68
import org.openide.filesystems.FileObject;
71
import org.openide.filesystems.FileObject;
69
72
70
/**
73
/**
Lines 96-124 Link Here
96
        if (whiteList == null) {
99
        if (whiteList == null) {
97
            return;
100
            return;
98
        }
101
        }
99
        final List<WhiteListScanner.Problem> problems = new LinkedList<WhiteListScanner.Problem>();
102
        final CompilationUnitTree cu = info.getCompilationUnit();
100
        final WhiteListScanner scanner = new WhiteListScanner(
103
        final Map<? extends Tree, ? extends WhiteListQuery.Result> problems = WhiteListSupport.getWhiteListViolations(
104
                cu,
105
                whiteList,
101
                info.getTrees(),
106
                info.getTrees(),
102
                whiteList,
107
                new Callable<Boolean>() {
103
                canceled);
108
                    @Override
104
        final CompilationUnitTree cu = info.getCompilationUnit();
109
                    public Boolean call() throws Exception {
105
        try {
110
                        return canceled.get();
106
            scanner.scan(cu, problems);
111
                    }
107
        } catch (WhiteListScanner.Cancel cancel) {
112
                });
113
        if (problems == null) {
114
            //Canceled
108
            return;
115
            return;
109
        }
116
        }
110
        final SourcePositions sp = info.getTrees().getSourcePositions();
117
        final SourcePositions sp = info.getTrees().getSourcePositions();
111
        final List<ErrorDescription> errors = new ArrayList<ErrorDescription>(problems.size());
118
        final List<ErrorDescription> errors = new ArrayList<ErrorDescription>(problems.size());
112
        for (WhiteListScanner.Problem problem : problems) {
119
        for (Map.Entry<? extends Tree, ? extends WhiteListQuery.Result> problem : problems.entrySet()) {
113
            if (canceled.get()) {
120
            if (canceled.get()) {
114
                return;
121
                return;
115
            }
122
            }
116
            final int start = (int) sp.getStartPosition(cu, problem.tree);
123
            final Tree tree = problem.getKey();
117
            final int end = (int) sp.getEndPosition(cu, problem.tree);
124
            final int start = (int) sp.getStartPosition(cu, tree);
125
            final int end = (int) sp.getEndPosition(cu, tree);
118
            if (start >= 0 && end >= 0) {
126
            if (start >= 0 && end >= 0) {
119
                errors.add(ErrorDescriptionFactory.createErrorDescription(
127
                errors.add(ErrorDescriptionFactory.createErrorDescription(
120
                        Severity.WARNING,
128
                        Severity.WARNING,
121
                        problem.description,
129
                        problem.getValue().getViolatedRuleDescription(),
122
                        file,
130
                        file,
123
                        start,
131
                        start,
124
                        end));
132
                        end));
(-)a/java.editor/src/org/netbeans/modules/java/editor/whitelist/WhiteListScanner.java (-171 lines)
Lines 1-171 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 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 2011 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.java.editor.whitelist;
43
44
import com.sun.source.tree.ClassTree;
45
import com.sun.source.tree.IdentifierTree;
46
import com.sun.source.tree.MemberSelectTree;
47
import com.sun.source.tree.MethodInvocationTree;
48
import com.sun.source.tree.MethodTree;
49
import com.sun.source.tree.NewClassTree;
50
import com.sun.source.tree.Tree;
51
import com.sun.source.util.TreePathScanner;
52
import com.sun.source.util.Trees;
53
import java.util.ArrayDeque;
54
import java.util.List;
55
import java.util.concurrent.atomic.AtomicBoolean;
56
import javax.lang.model.element.Element;
57
import javax.lang.model.element.ElementKind;
58
import org.netbeans.api.java.source.ElementHandle;
59
import org.netbeans.api.whitelist.WhiteListQuery;
60
import org.netbeans.api.whitelist.WhiteListQuery.WhiteList;
61
62
/**
63
 *
64
 * @author Tomas Zezula
65
 */
66
class WhiteListScanner extends TreePathScanner<Void, List<? super WhiteListScanner.Problem>> {
67
68
    private final Trees trees;
69
    private final AtomicBoolean cancel;
70
    private final WhiteList whiteList;
71
    private final ArrayDeque<MethodInvocationTree> methodInvocation;
72
73
    WhiteListScanner(
74
        final Trees trees,
75
        final WhiteList whiteList,
76
        final AtomicBoolean cancel) {
77
        this.trees = trees;
78
        this.whiteList = whiteList;
79
        this.cancel = cancel;
80
        methodInvocation = new ArrayDeque<MethodInvocationTree>();
81
    }
82
83
    @Override
84
    public Void visitMethod(MethodTree node, List<? super Problem> p) {
85
        checkCancel();
86
        return super.visitMethod(node, p);
87
    }
88
89
    @Override
90
    public Void visitClass(ClassTree node, List<? super Problem> p) {
91
        checkCancel();
92
        return super.visitClass(node, p);
93
    }
94
95
    @Override
96
    public Void visitIdentifier(IdentifierTree node, List<? super Problem> p) {
97
        handleNode(node,p);
98
        return super.visitIdentifier(node, p);
99
    }
100
101
    @Override
102
    public Void visitMemberSelect(MemberSelectTree node, List<? super Problem> p) {
103
        handleNode(node,p);
104
        return super.visitMemberSelect(node, p);
105
    }
106
107
    @Override
108
    public Void visitNewClass(NewClassTree node, List<? super Problem> p) {
109
        final Element e = trees.getElement(getCurrentPath());
110
        final WhiteListQuery.Result res;
111
        if (e != null && !(res=whiteList.check(ElementHandle.create(e),WhiteListQuery.Operation.USAGE)).isAllowed()) {
112
                p.add(new Problem(node,res.getViolatedRuleDescription()));
113
        }
114
        scan(node.getTypeArguments(), p);
115
        scan(node.getArguments(), p);
116
	scan(node.getClassBody(), p);
117
        return null;
118
    }
119
120
    @Override
121
    public Void visitMethodInvocation(MethodInvocationTree node, List<? super Problem> p) {
122
        methodInvocation.offerFirst(node);
123
        super.visitMethodInvocation(node, p);
124
        methodInvocation.removeFirst();
125
        return null;
126
    }
127
128
    private void handleNode(
129
            final Tree node,
130
            final List<? super Problem> p) {
131
        final Element e = trees.getElement(getCurrentPath());
132
        if (e == null) {
133
            return;
134
        }
135
        final ElementKind k = e.getKind();
136
        Tree toReport =  null;
137
        if (k.isClass() || k.isInterface()) {
138
            toReport=node;
139
        } else if ((k == ElementKind.METHOD || k == ElementKind.CONSTRUCTOR) &&
140
                !methodInvocation.isEmpty()) {
141
            toReport=methodInvocation.peekFirst();
142
        }
143
        final WhiteListQuery.Result res;
144
        if (toReport != null &&
145
            !(res=whiteList.check(ElementHandle.create(e),WhiteListQuery.Operation.USAGE)).isAllowed()) {
146
                p.add(new Problem(toReport,res.getViolatedRuleDescription()));
147
        }
148
    }
149
150
    private void checkCancel() {
151
        if (cancel.get()) {
152
            throw new Cancel();
153
        }
154
    }
155
156
    static final class Problem {
157
        final Tree tree;
158
        final String description;
159
160
        private Problem (
161
                final Tree tree,
162
                final String description) {
163
            this.tree = tree;
164
            this.description = description;
165
        }
166
    }
167
168
    static final class Cancel extends RuntimeException {
169
    }
170
171
}
(-)a/java.editor/src/org/netbeans/modules/java/editor/whitelist/WhiteListTaskProvider.java (-111 / +53 lines)
Lines 41-48 Link Here
41
 */
41
 */
42
package org.netbeans.modules.java.editor.whitelist;
42
package org.netbeans.modules.java.editor.whitelist;
43
43
44
import java.io.File;
45
import java.io.IOException;
46
import java.net.URL;
44
import java.net.URL;
47
import java.util.ArrayList;
45
import java.util.ArrayList;
48
import java.util.Collections;
46
import java.util.Collections;
Lines 62-79 Link Here
62
import org.netbeans.api.project.Project;
60
import org.netbeans.api.project.Project;
63
import org.netbeans.api.project.ProjectUtils;
61
import org.netbeans.api.project.ProjectUtils;
64
import org.netbeans.api.project.SourceGroup;
62
import org.netbeans.api.project.SourceGroup;
65
import org.netbeans.modules.parsing.lucene.support.DocumentIndex;
66
import org.netbeans.modules.parsing.lucene.support.Index;
67
import org.netbeans.modules.parsing.lucene.support.IndexDocument;
68
import org.netbeans.modules.parsing.lucene.support.IndexManager;
69
import org.netbeans.modules.parsing.lucene.support.Queries.QueryKind;
70
import org.netbeans.spi.tasklist.PushTaskScanner;
63
import org.netbeans.spi.tasklist.PushTaskScanner;
71
import org.netbeans.spi.tasklist.Task;
64
import org.netbeans.spi.tasklist.Task;
72
import org.netbeans.spi.tasklist.TaskScanningScope;
65
import org.netbeans.spi.tasklist.TaskScanningScope;
66
import org.netbeans.api.whitelist.index.WhiteListIndex;
67
import org.netbeans.api.whitelist.index.WhiteListIndexEvent;
68
import org.netbeans.api.whitelist.index.WhiteListIndexListener;
73
import org.openide.filesystems.FileObject;
69
import org.openide.filesystems.FileObject;
74
import org.openide.filesystems.FileUtil;
70
import org.openide.filesystems.FileUtil;
75
import org.openide.filesystems.URLMapper;
71
import org.openide.filesystems.URLMapper;
76
import org.openide.util.Exceptions;
77
import org.openide.util.NbBundle;
72
import org.openide.util.NbBundle;
78
import org.openide.util.RequestProcessor;
73
import org.openide.util.RequestProcessor;
79
import org.openide.util.TaskListener;
74
import org.openide.util.TaskListener;
Lines 109-136 Link Here
109
        super(Bundle.LBL_ProviderName(),
104
        super(Bundle.LBL_ProviderName(),
110
              Bundle.LBL_ProviderDescription(),
105
              Bundle.LBL_ProviderDescription(),
111
              null);
106
              null);
112
        INSTANCE = this;
107
        WhiteListIndex.getDefault().addWhiteListIndexListener(new WhiteListIndexListener() {
113
    }
108
            @Override
114
109
            public void indexChanged(WhiteListIndexEvent event) {
115
    @CheckForNull
110
                refresh(event.getRoot());
116
    static WhiteListTaskProvider getInstance() {
111
            }
117
        return INSTANCE;
112
        });
118
    }
119
120
    void refresh(final @NonNull URL root) {
121
        final FileObject rootFo = URLMapper.findFileObject(root);
122
        final Set<FileObject> files;
123
        final Callback callback;
124
        synchronized (this) {
125
            files = currentFiles;
126
            callback = currentCallback;
127
        }
128
        if (rootFo != null &&
129
            files != null &&
130
            files.contains(rootFo)) {
131
            assert callback != null;
132
            enqueue(new Work(rootFo, currentCallback));
133
        }
134
    }
113
    }
135
114
136
    @Override
115
    @Override
Lines 158-163 Link Here
158
        }
137
        }
159
    }
138
    }
160
139
140
    private void refresh(final @NonNull URL root) {
141
        assert root != null;
142
        final FileObject rootFo = URLMapper.findFileObject(root);
143
        final Set<FileObject> files;
144
        final Callback callback;
145
        synchronized (this) {
146
            files = currentFiles;
147
            callback = currentCallback;
148
        }
149
        if (rootFo != null &&
150
            files != null &&
151
            files.contains(rootFo)) {
152
            assert callback != null;
153
            enqueue(new Work(rootFo, currentCallback));
154
        }
155
    }
156
161
    private static void enqueue(Work w) {
157
    private static void enqueue(Work w) {
162
        synchronized (TASKS) {
158
        synchronized (TASKS) {
163
            final RequestProcessor.Task task = WORKER.post(w);
159
            final RequestProcessor.Task task = WORKER.post(w);
Lines 205-222 Link Here
205
    }
201
    }
206
202
207
    @CheckForNull
203
    @CheckForNull
208
    private static Map.Entry<FileObject,Task> createTask(
204
    private static Map.Entry<FileObject,Task> createTask(@NonNull final WhiteListIndex.Problem problem) {
209
            @NonNull final FileObject root,
205
        final FileObject file = problem.getFile();
210
            @NonNull final IndexDocument doc) {
211
        final FileObject file = root.getFileObject(doc.getPrimaryKey());
212
        if (file == null) {
206
        if (file == null) {
213
            return null;
207
            return null;
214
        }
208
        }
215
        final Task task = Task.create(
209
        final Task task = Task.create(
216
            file,
210
            file,
217
            "nb-whitelist-warning", //NOI18N
211
            "nb-whitelist-warning", //NOI18N
218
            doc.getValue(WhiteListIndexerPlugin.MSG),
212
            problem.getResult().getViolatedRuleDescription(),
219
            Integer.parseInt(doc.getValue(WhiteListIndexerPlugin.LINE)));
213
            problem.getLine());
220
        return new Map.Entry<FileObject, Task>() {
214
        return new Map.Entry<FileObject, Task>() {
221
            @Override
215
            @Override
222
            public FileObject getKey() {
216
            public FileObject getKey() {
Lines 233-252 Link Here
233
        };
227
        };
234
    }
228
    }
235
229
236
    @CheckForNull
237
    private static DocumentIndex getIndex(@NonNull final FileObject root) {
238
        try {
239
            final File whiteListFolder = WhiteListIndexerPlugin.getWhiteListDir(root.getURL());
240
            if (whiteListFolder != null) {
241
                final DocumentIndex index = IndexManager.createDocumentIndex(whiteListFolder);
242
                return index.getStatus() == Index.Status.VALID ? index : null;
243
            }
244
        } catch (IOException ioe) {
245
            Exceptions.printStackTrace(ioe);
246
        }
247
        return null;
248
    }
249
250
    private static void updateErrorsInRoot(
230
    private static void updateErrorsInRoot(
251
            @NonNull final Callback callback,
231
            @NonNull final Callback callback,
252
            @NonNull final FileObject root) {
232
            @NonNull final FileObject root) {
Lines 255-289 Link Here
255
        filesWithErrors.clear();
235
        filesWithErrors.clear();
256
        Set<FileObject> nueFilesWithErrors = new HashSet<FileObject>();
236
        Set<FileObject> nueFilesWithErrors = new HashSet<FileObject>();
257
        final Map<FileObject,List<Task>> filesToTasks = new HashMap<FileObject,List<Task>>();
237
        final Map<FileObject,List<Task>> filesToTasks = new HashMap<FileObject,List<Task>>();
258
        try {
238
        for (WhiteListIndex.Problem problem : WhiteListIndex.getDefault().getWhiteListViolations(root, null)) {
259
            IndexManager.readAccess(new IndexManager.Action<Void>() {
239
            final Map.Entry<FileObject,Task> task = createTask(problem);
260
                @Override
240
            if (task != null) {
261
                public Void run() throws IOException, InterruptedException {
241
                List<Task> tasks = filesToTasks.get(task.getKey());
262
                    final DocumentIndex index = getIndex(root);
242
                if (tasks == null) {
263
                    if (index != null) {
243
                    tasks = new ArrayList<Task>();
264
                        try {
244
                    filesToTasks.put(task.getKey(), tasks);
265
                            for (IndexDocument doc : index.findByPrimaryKey("", QueryKind.PREFIX)) {    //NOI18N
266
                                final Map.Entry<FileObject,Task> task = createTask(root, doc);
267
                                if (task != null) {
268
                                    List<Task> tasks = filesToTasks.get(task.getKey());
269
                                    if (tasks == null) {
270
                                        tasks = new ArrayList<Task>();
271
                                        filesToTasks.put(task.getKey(), tasks);
272
                                    }
273
                                    tasks.add(task.getValue());
274
                                }
275
                            }
276
                        } finally {
277
                            index.close();
278
                        }
279
                    }
280
                    return null;
281
                }
245
                }
282
            });
246
                tasks.add(task.getValue());
283
        } catch (IOException e) {
247
            }
284
            Exceptions.printStackTrace(e);
285
        } catch (InterruptedException e) {
286
            Exceptions.printStackTrace(e);
287
        }
248
        }
288
        for (Map.Entry<FileObject,List<Task>> e : filesToTasks.entrySet()) {
249
        for (Map.Entry<FileObject,List<Task>> e : filesToTasks.entrySet()) {
289
            LOG.log(Level.FINE, "Setting {1} for {0}\n",
250
            LOG.log(Level.FINE, "Setting {1} for {0}\n",
Lines 304-343 Link Here
304
        @NonNull final Callback callback,
265
        @NonNull final Callback callback,
305
        @NonNull final FileObject root,
266
        @NonNull final FileObject root,
306
        @NonNull final FileObject file) {
267
        @NonNull final FileObject file) {
307
        try {
268
        final List<Task> tasks = new ArrayList<Task>();
308
            IndexManager.readAccess(new IndexManager.Action<Void>(){
269
        for (WhiteListIndex.Problem problem : WhiteListIndex.getDefault().getWhiteListViolations(root, file)) {
309
                @Override
270
            final Map.Entry<FileObject,Task> task = createTask(problem);
310
                public Void run() throws IOException, InterruptedException {
271
            if (task != null) {
311
                    final List<Task> tasks = new ArrayList<Task>();
272
                tasks.add(task.getValue());
312
                    final DocumentIndex index = getIndex(root);
273
            }
313
                    if (index != null) {
314
                        try {
315
                            for (IndexDocument doc : index.findByPrimaryKey(FileUtil.getRelativePath(root, file), QueryKind.PREFIX)) {
316
                                final Map.Entry<FileObject,Task> task = createTask(root, doc);
317
                                if (task != null) {
318
                                    tasks.add(task.getValue());
319
                                }
320
                            }
321
                        } finally {
322
                            index.close();
323
                        }
324
                    }
325
                    Set<FileObject> filesWithErrors = getFilesWithAttachedErrors(root);
326
                    if (tasks.isEmpty()) {
327
                        filesWithErrors.remove(file);
328
                    } else {
329
                        filesWithErrors.add(file);
330
                    }
331
                    LOG.log(Level.FINE, "setting {1} for {0}", new Object[]{file, tasks});
332
                    callback.setTasks(file, tasks);
333
                    return null;
334
                }
335
            });
336
        } catch (IOException e) {
337
            Exceptions.printStackTrace(e);
338
        } catch (InterruptedException e) {
339
            Exceptions.printStackTrace(e);
340
        }
274
        }
275
        final Set<FileObject> filesWithErrors = getFilesWithAttachedErrors(root);
276
        if (tasks.isEmpty()) {
277
            filesWithErrors.remove(file);
278
        } else {
279
            filesWithErrors.add(file);
280
        }
281
        LOG.log(Level.FINE, "setting {1} for {0}", new Object[]{file, tasks});
282
        callback.setTasks(file, tasks);
341
    }
283
    }
342
284
343
    private static final class Work implements Runnable {
285
    private static final class Work implements Runnable {
(-)a/java.preprocessorbridge/nbproject/project.xml (+1 lines)
Lines 70-75 Link Here
70
                <friend>org.netbeans.modules.scala.editing</friend>
70
                <friend>org.netbeans.modules.scala.editing</friend>
71
                <friend>org.netbeans.modules.scala.editor</friend>
71
                <friend>org.netbeans.modules.scala.editor</friend>
72
                <friend>org.netbeans.modules.web.core.syntax</friend>
72
                <friend>org.netbeans.modules.web.core.syntax</friend>
73
                <friend>org.netbeans.modules.whitelist</friend>
73
                <package>org.netbeans.modules.java.preprocessorbridge.api</package>
74
                <package>org.netbeans.modules.java.preprocessorbridge.api</package>
74
                <package>org.netbeans.modules.java.preprocessorbridge.spi</package>
75
                <package>org.netbeans.modules.java.preprocessorbridge.spi</package>
75
            </friend-packages>
76
            </friend-packages>
(-)a/parsing.lucene/nbproject/project.xml (-1 / +1 lines)
Lines 56-65 Link Here
56
                </test-type>
56
                </test-type>
57
            </test-dependencies>
57
            </test-dependencies>
58
            <friend-packages>
58
            <friend-packages>
59
                <friend>org.netbeans.modules.java.editor</friend>
60
                <friend>org.netbeans.modules.java.source</friend>
59
                <friend>org.netbeans.modules.java.source</friend>
61
                <friend>org.netbeans.modules.java.sourceui</friend>
60
                <friend>org.netbeans.modules.java.sourceui</friend>
62
                <friend>org.netbeans.modules.parsing.api</friend>
61
                <friend>org.netbeans.modules.parsing.api</friend>
62
                <friend>org.netbeans.modules.whitelist</friend>
63
                <package>org.netbeans.modules.parsing.lucene.support</package>
63
                <package>org.netbeans.modules.parsing.lucene.support</package>
64
            </friend-packages>
64
            </friend-packages>
65
        </data>
65
        </data>
(-)a/whitelist/apichanges.xml (+18 lines)
Lines 75-80 Link Here
75
<!-- ACTUAL CHANGES BEGIN HERE: -->
75
<!-- ACTUAL CHANGES BEGIN HERE: -->
76
76
77
<changes>
77
<changes>
78
        <change id="WhiteListIndex">
79
            <api name="whitelist"/>
80
            <summary>Added WhiteListQuery to check violations of runtime restrictions</summary>
81
            <version major="1" minor="2"/>
82
            <date day="15" month="9" year="2011"/>
83
            <author login="tzezula"/>
84
            <compatibility addition="yes" modification="no" semantic="compatible" source="compatible" binary="compatible"/>
85
            <description>
86
                <p>
87
                    Added WhiteListIndex to provide persistent index of the white list violations.
88
                </p>
89
            </description>
90
            <class package="org.netbeans.api.whitelist.index" name="WhiteListIndex"/>
91
            <class package="org.netbeans.api.whitelist.index" name="WhiteListIndexListener"/>
92
            <class package="org.netbeans.api.whitelist.index" name="WhiteListIndexEvent"/>
93
            <class package="org.netbeans.api.whitelist.support" name="WhiteListSupport"/>
94
            <issue number="202063"/>
95
        </change>
78
        <change id="WhiteListQuery">
96
        <change id="WhiteListQuery">
79
            <api name="whitelist"/>
97
            <api name="whitelist"/>
80
            <summary>Added WhiteListQuery to check violations of runtime restrictions</summary>
98
            <summary>Added WhiteListQuery to check violations of runtime restrictions</summary>
(-)a/whitelist/manifest.mf (-1 / +1 lines)
Lines 2-6 Link Here
2
OpenIDE-Module: org.netbeans.modules.whitelist
2
OpenIDE-Module: org.netbeans.modules.whitelist
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/whitelist/Bundle.properties
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/whitelist/Bundle.properties
4
OpenIDE-Module-Layer: org/netbeans/modules/whitelist/resources/layer.xml
4
OpenIDE-Module-Layer: org/netbeans/modules/whitelist/resources/layer.xml
5
OpenIDE-Module-Specification-Version: 1.1
5
OpenIDE-Module-Specification-Version: 1.2
6
6
(-)a/whitelist/nbproject/project.xml (+46 lines)
Lines 15-20 Link Here
15
                    </run-dependency>
15
                    </run-dependency>
16
                </dependency>
16
                </dependency>
17
                <dependency>
17
                <dependency>
18
                    <code-name-base>org.netbeans.api.java.classpath</code-name-base>
19
                    <build-prerequisite/>
20
                    <compile-dependency/>
21
                    <run-dependency>
22
                        <release-version>1</release-version>
23
                        <specification-version>1.30</specification-version>
24
                    </run-dependency>
25
                </dependency>
26
                <dependency>
18
                    <code-name-base>org.netbeans.libs.javacapi</code-name-base>
27
                    <code-name-base>org.netbeans.libs.javacapi</code-name-base>
19
                    <build-prerequisite/>
28
                    <build-prerequisite/>
20
                    <compile-dependency/>
29
                    <compile-dependency/>
Lines 23-28 Link Here
23
                    </run-dependency>
32
                    </run-dependency>
24
                </dependency>
33
                </dependency>
25
                <dependency>
34
                <dependency>
35
                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
36
                    <build-prerequisite/>
37
                    <compile-dependency/>
38
                    <run-dependency>
39
                        <release-version>1</release-version>
40
                        <specification-version>1.23</specification-version>
41
                    </run-dependency>
42
                </dependency>
43
                <dependency>
44
                    <code-name-base>org.netbeans.modules.java.preprocessorbridge</code-name-base>
45
                    <build-prerequisite/>
46
                    <compile-dependency/>
47
                    <run-dependency>
48
                        <specification-version>1.22</specification-version>
49
                    </run-dependency>
50
                </dependency>
51
                <dependency>
26
                    <code-name-base>org.netbeans.modules.java.source</code-name-base>
52
                    <code-name-base>org.netbeans.modules.java.source</code-name-base>
27
                    <build-prerequisite/>
53
                    <build-prerequisite/>
28
                    <compile-dependency/>
54
                    <compile-dependency/>
Lines 31-36 Link Here
31
                    </run-dependency>
57
                    </run-dependency>
32
                </dependency>
58
                </dependency>
33
                <dependency>
59
                <dependency>
60
                    <code-name-base>org.netbeans.modules.parsing.api</code-name-base>
61
                    <build-prerequisite/>
62
                    <compile-dependency/>
63
                    <run-dependency>
64
                        <release-version>1</release-version>
65
                        <specification-version>1.43</specification-version>
66
                    </run-dependency>
67
                </dependency>
68
                <dependency>
69
                    <code-name-base>org.netbeans.modules.parsing.lucene</code-name-base>
70
                    <build-prerequisite/>
71
                    <compile-dependency/>
72
                    <run-dependency>
73
                        <release-version>2</release-version>
74
                        <specification-version>2.3</specification-version>
75
                    </run-dependency>
76
                </dependency>
77
                <dependency>
34
                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
78
                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
35
                    <build-prerequisite/>
79
                    <build-prerequisite/>
36
                    <compile-dependency/>
80
                    <compile-dependency/>
Lines 78-83 Link Here
78
                <friend>org.netbeans.modules.java.editor</friend>
122
                <friend>org.netbeans.modules.java.editor</friend>
79
                <friend>org.netbeans.modules.web.project</friend>
123
                <friend>org.netbeans.modules.web.project</friend>
80
                <package>org.netbeans.api.whitelist</package>
124
                <package>org.netbeans.api.whitelist</package>
125
                <package>org.netbeans.api.whitelist.index</package>
126
                <package>org.netbeans.api.whitelist.support</package>
81
                <package>org.netbeans.spi.whitelist</package>
127
                <package>org.netbeans.spi.whitelist</package>
82
                <package>org.netbeans.spi.whitelist.support</package>
128
                <package>org.netbeans.spi.whitelist.support</package>
83
            </friend-packages>
129
            </friend-packages>
(-)a/whitelist/src/org/netbeans/api/whitelist/index/WhiteListIndex.java (+213 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 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 2011 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.whitelist.index;
43
44
import java.net.URL;
45
import java.util.Collection;
46
import java.util.List;
47
import java.util.concurrent.CopyOnWriteArrayList;
48
import org.netbeans.api.annotations.common.CheckForNull;
49
import org.netbeans.api.annotations.common.NonNull;
50
import org.netbeans.api.annotations.common.NullAllowed;
51
import org.netbeans.api.whitelist.WhiteListQuery;
52
import org.netbeans.api.whitelist.WhiteListQuery.Result;
53
import org.netbeans.modules.whitelist.index.WhiteListIndexAccessor;
54
import org.netbeans.modules.whitelist.index.WhiteListIndexerPlugin;
55
import org.openide.filesystems.FileObject;
56
import org.openide.filesystems.FileUtil;
57
import org.openide.util.Parameters;
58
59
/**
60
 * A persistent index of white list violations.
61
 * @author Tomas Zezula
62
 * @since 1.2
63
 */
64
public final class WhiteListIndex {
65
66
    static {
67
        WhiteListIndexAccessor.setInstance(new WhiteListIndexAccessorImpl());
68
    }
69
70
    private static WhiteListIndex instance;
71
    private final List<WhiteListIndexListener> listeners = new CopyOnWriteArrayList<WhiteListIndexListener>();
72
73
    private WhiteListIndex() {}
74
75
    /**
76
     * Returns the white list violations for given root or file.
77
     * @param root the root to get white list violations for
78
     * @param file the file to restrict the white list violation search or null
79
     * @return a {@link Collection} of {@link Problem}s
80
     * @throws IllegalArgumentException in case when file is not under the root or it's not a valid file
81
     * @throws UnsupportedOperationException when the index is not supported by the IDE
82
     */
83
    @NonNull
84
    public Collection<? extends Problem> getWhiteListViolations(
85
            @NonNull final FileObject root,
86
            @NullAllowed final FileObject file) throws IllegalArgumentException, UnsupportedOperationException {
87
        Parameters.notNull("scope", root); //NOI18N
88
        if (file != null && !(root.equals(file) || FileUtil.isParentOf(root, file))) {
89
            throw new IllegalArgumentException(
90
                    "The file: " + //NOI18N
91
                    FileUtil.getFileDisplayName(file) +
92
                    " has to be inside the root: " + //NOI18N
93
                    FileUtil.getFileDisplayName(root));
94
        }
95
        if (file != null && !file.isData()) {
96
            throw new IllegalArgumentException(
97
                    "The file: " + //NOI18N
98
                    FileUtil.getFileDisplayName(file) +
99
                    " has to be file.");    //NOI18N
100
        }
101
        return WhiteListIndexerPlugin.getWhiteListViolations(root,file);
102
    }
103
104
    /**
105
     * Adds {@link WhiteListIndexListener}.
106
     * The listener is notified when the white list index is changed.
107
     * @param listener the listener to be added
108
     */
109
    public void addWhiteListIndexListener(@NonNull final WhiteListIndexListener listener) {
110
        Parameters.notNull("listener", listener);   //NOI18N
111
        listeners.add(listener);
112
    }
113
114
    /**
115
     * Removes {@link WhiteListIndexListener}.
116
     * @param listener the listener to be removed
117
     */
118
    public void removeWhiteListIndexListener(@NonNull final WhiteListIndexListener listener) {
119
        Parameters.notNull("listener", listener);   //NOI18N
120
        listeners.remove(listener);
121
    }
122
123
    /**
124
     * Returns an instance of {@link WhiteListIndex}
125
     * @return the instance of {@link WhiteListIndex}
126
     */
127
    public static synchronized WhiteListIndex getDefault() {
128
        if (instance == null) {
129
            instance = new WhiteListIndex();
130
        }
131
        return instance;
132
    }
133
134
135
    /**
136
     * Represent a white list violation
137
     */
138
    public static final class Problem {
139
140
        private final WhiteListQuery.Result result;
141
        private final FileObject root;
142
        private final String relPath;
143
        private final int line;
144
145
        private Problem (
146
                @NonNull final WhiteListQuery.Result result,
147
                @NonNull final FileObject root,
148
                @NonNull final String relPath,
149
                final int line) {
150
            Parameters.notNull("result", result);   //NOI18N
151
            Parameters.notNull("root", root);   //NOI18N
152
            Parameters.notNull("relPath", relPath); //NOI18N
153
            this.result = result;
154
            this.root = root;
155
            this.relPath = relPath;
156
            this.line = line;
157
        }
158
159
        /**
160
         * Returns {@link WhiteListQuery.Result} describing the
161
         * white list violation.
162
         * @return the {@link WhiteListQuery.Result}
163
         */
164
        @NonNull
165
        public WhiteListQuery.Result getResult() {
166
            return result;
167
        }
168
169
        /**
170
         * Returns the file in which the white list violation occured.
171
         * @return the {@link FileObject}
172
         */
173
        @CheckForNull
174
        public FileObject getFile() {
175
            return root.getFileObject(relPath);
176
        }
177
178
        /**
179
         * Returns the line number of white list violation.
180
         * @return the line number
181
         */
182
        public int getLine() {
183
            return line;
184
        }
185
    }
186
187
    //<editor-fold defaultstate="collapsed" desc="Private implementation">
188
    private void fireIndexChange(final URL root) {
189
        final WhiteListIndexEvent event = new WhiteListIndexEvent(this, root);
190
        for (WhiteListIndexListener l : listeners) {
191
            l.indexChanged(event);
192
        }
193
    }
194
195
196
    private static final class WhiteListIndexAccessorImpl extends WhiteListIndexAccessor {
197
        @Override
198
        public void refresh(@NonNull URL root) {
199
            WhiteListIndex.getDefault().fireIndexChange(root);
200
        }
201
202
        @Override
203
        @NonNull
204
        public Problem createProblem(
205
                @NonNull final Result result,
206
                @NonNull final FileObject root,
207
                @NonNull final String key,
208
                int line) {
209
            return new Problem(result, root, key, line);
210
        }
211
    }
212
    //</editor-fold>
213
}
(-)a/whitelist/src/org/netbeans/api/whitelist/index/WhiteListIndexEvent.java (+73 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 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 2011 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.whitelist.index;
43
44
import java.net.URL;
45
import java.util.EventObject;
46
import org.netbeans.api.annotations.common.NonNull;
47
import org.openide.util.Parameters;
48
49
/**
50
 * WhiteListIndexEvent is used to notify interested parties about
51
 * changes in persistent index of white list violations.
52
 * @author Tomas Zezula
53
 * @since 1.2
54
 */
55
public class WhiteListIndexEvent extends EventObject {
56
57
    private final URL root;
58
59
    WhiteListIndexEvent(@NonNull final Object source, @NonNull final URL root) {
60
        super(source);
61
        Parameters.notNull("root", root);   //NOI18N
62
        this.root = root;
63
    }
64
65
    /**
66
     * Returns a source root for which the index was changed.
67
     * @return the {@link URL} of the source root.
68
     */
69
    @NonNull
70
    public URL getRoot() {
71
        return root;
72
    }
73
}
(-)a/whitelist/src/org/netbeans/api/whitelist/index/WhiteListIndexListener.java (+58 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 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 2011 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.whitelist.index;
43
44
import java.util.EventListener;
45
import org.netbeans.api.annotations.common.NonNull;
46
47
/**
48
 * The listener interface for receiving {@link WhiteListIndex} events.
49
 * @author Tomas Zezula
50
 * @since 1.2
51
 */
52
public interface WhiteListIndexListener extends EventListener {
53
    /**
54
     * Invoked when the index for a source root changed
55
     * @param event the event providing the change details
56
     */
57
    void indexChanged (@NonNull WhiteListIndexEvent event);
58
}
(-)a/whitelist/src/org/netbeans/api/whitelist/support/WhiteListSupport.java (+208 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 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 2011 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.whitelist.support;
43
44
import com.sun.source.tree.ClassTree;
45
import com.sun.source.tree.CompilationUnitTree;
46
import com.sun.source.tree.IdentifierTree;
47
import com.sun.source.tree.MemberSelectTree;
48
import com.sun.source.tree.MethodInvocationTree;
49
import com.sun.source.tree.MethodTree;
50
import com.sun.source.tree.NewClassTree;
51
import com.sun.source.tree.Tree;
52
import com.sun.source.util.TreePathScanner;
53
import com.sun.source.util.Trees;
54
import java.util.ArrayDeque;
55
import java.util.HashMap;
56
import java.util.Map;
57
import java.util.concurrent.Callable;
58
import javax.lang.model.element.Element;
59
import javax.lang.model.element.ElementKind;
60
import org.netbeans.api.annotations.common.CheckForNull;
61
import org.netbeans.api.annotations.common.NonNull;
62
import org.netbeans.api.annotations.common.NullAllowed;
63
import org.netbeans.api.java.source.ElementHandle;
64
import org.netbeans.api.whitelist.WhiteListQuery;
65
import org.netbeans.api.whitelist.WhiteListQuery.Result;
66
import org.netbeans.api.whitelist.WhiteListQuery.WhiteList;
67
import org.openide.util.Exceptions;
68
import org.openide.util.Parameters;
69
70
/**
71
 * White list supporting methods.
72
 * @author Tomas Zezula
73
 * @since 1.2
74
 */
75
public final class WhiteListSupport {
76
77
    private WhiteListSupport() {}
78
79
    /**
80
     * Utility method to check the given {@link CompilationUnitTree} for white list violations.
81
     * @param unit the {@link CompilationUnitTree} to be analyzed
82
     * @param whitelist the {@link WhiteList} to use to check the violations
83
     * @param trees the {@link Trees} service
84
     * @param cancel the cancel request. If the {@link Callable} returns true the check is canceled
85
     * and null is returned.
86
     * @return a {@link Map} of {@link Tree}s with attached white list violations or null when the
87
     * scan was canceled.
88
     */
89
    @CheckForNull
90
    public static Map<? extends Tree, ? extends WhiteListQuery.Result> getWhiteListViolations(
91
            @NonNull final CompilationUnitTree unit,
92
            @NonNull final WhiteListQuery.WhiteList whitelist,
93
            @NonNull final Trees trees,
94
            @NullAllowed final Callable<Boolean> cancel) {
95
        Parameters.notNull("tree", unit);           //NOI18N
96
        Parameters.notNull("whitelist", whitelist); //NOI18N
97
        Parameters.notNull("trees", trees);         //NOI18N
98
        final Map<Tree,WhiteListQuery.Result> result = new HashMap<Tree, Result>();
99
        final WhiteListScanner scanner = new WhiteListScanner(trees, whitelist, cancel);
100
        try {
101
            scanner.scan(unit, result);
102
            return result;
103
        } catch (WhiteListScanner.Cancel ce) {
104
            return null;
105
        }
106
    }
107
108
    //<editor-fold defaultstate="collapsed" desc="Private implementation">
109
    private static class WhiteListScanner extends TreePathScanner<Void, Map<Tree,WhiteListQuery.Result>> {
110
111
        private final Trees trees;
112
        private final Callable<Boolean> cancel;
113
        private final WhiteList whiteList;
114
        private final ArrayDeque<MethodInvocationTree> methodInvocation;
115
116
        WhiteListScanner(
117
            final Trees trees,
118
            final WhiteList whiteList,
119
            final Callable<Boolean> cancel) {
120
            this.trees = trees;
121
            this.whiteList = whiteList;
122
            this.cancel = cancel;
123
            methodInvocation = new ArrayDeque<MethodInvocationTree>();
124
        }
125
126
        @Override
127
        public Void visitMethod(MethodTree node, Map<Tree,WhiteListQuery.Result> p) {
128
            checkCancel();
129
            return super.visitMethod(node, p);
130
        }
131
132
        @Override
133
        public Void visitClass(ClassTree node, Map<Tree,WhiteListQuery.Result> p) {
134
            checkCancel();
135
            return super.visitClass(node, p);
136
        }
137
138
        @Override
139
        public Void visitIdentifier(IdentifierTree node, Map<Tree,WhiteListQuery.Result> p) {
140
            handleNode(node,p);
141
            return super.visitIdentifier(node, p);
142
        }
143
144
        @Override
145
        public Void visitMemberSelect(MemberSelectTree node, Map<Tree,WhiteListQuery.Result> p) {
146
            handleNode(node,p);
147
            return super.visitMemberSelect(node, p);
148
        }
149
150
        @Override
151
        public Void visitNewClass(NewClassTree node, Map<Tree,WhiteListQuery.Result> p) {
152
            final Element e = trees.getElement(getCurrentPath());
153
            final WhiteListQuery.Result res;
154
            if (e != null && !(res=whiteList.check(ElementHandle.create(e),WhiteListQuery.Operation.USAGE)).isAllowed()) {
155
                p.put(node,res);
156
            }
157
            scan(node.getTypeArguments(), p);
158
            scan(node.getArguments(), p);
159
            scan(node.getClassBody(), p);
160
            return null;
161
        }
162
163
        @Override
164
        public Void visitMethodInvocation(MethodInvocationTree node, Map<Tree,WhiteListQuery.Result> p) {
165
            methodInvocation.offerFirst(node);
166
            super.visitMethodInvocation(node, p);
167
            methodInvocation.removeFirst();
168
            return null;
169
        }
170
171
        private void handleNode(
172
                final Tree node,
173
                final Map<Tree,WhiteListQuery.Result> p) {
174
            final Element e = trees.getElement(getCurrentPath());
175
            if (e == null) {
176
                return;
177
            }
178
            final ElementKind k = e.getKind();
179
            Tree toReport =  null;
180
            if (k.isClass() || k.isInterface()) {
181
                toReport=node;
182
            } else if ((k == ElementKind.METHOD || k == ElementKind.CONSTRUCTOR) &&
183
                    !methodInvocation.isEmpty()) {
184
                toReport=methodInvocation.peekFirst();
185
            }
186
            final WhiteListQuery.Result res;
187
            if (toReport != null &&
188
                !(res=whiteList.check(ElementHandle.create(e),WhiteListQuery.Operation.USAGE)).isAllowed()) {
189
                    p.put(toReport,res);
190
            }
191
        }
192
193
        private void checkCancel() {
194
            try {
195
                if (cancel != null && cancel.call() == Boolean.TRUE) {
196
                    throw new Cancel();
197
                }
198
            } catch (Exception ex) {
199
                Exceptions.printStackTrace(ex);
200
            }
201
        }
202
203
        static final class Cancel extends RuntimeException {
204
        }
205
    }
206
    //</editor-fold>
207
208
}
(-)a/whitelist/src/org/netbeans/modules/whitelist/index/WhiteListIndexAccessor.java (+85 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 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 2011 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.whitelist.index;
43
44
import java.net.URL;
45
import org.netbeans.api.annotations.common.NonNull;
46
import org.netbeans.api.whitelist.WhiteListQuery;
47
import org.netbeans.api.whitelist.index.WhiteListIndex;
48
import org.openide.filesystems.FileObject;
49
import org.openide.util.Exceptions;
50
import org.openide.util.Parameters;
51
52
/**
53
 *
54
 * @author Tomas Zezula
55
 */
56
public abstract class WhiteListIndexAccessor {
57
58
    private static volatile WhiteListIndexAccessor instance;
59
60
    @NonNull
61
    public static synchronized WhiteListIndexAccessor getInstance() {
62
        if (instance == null) {
63
            try {
64
                Class.forName(WhiteListIndex.class.getName(), true, WhiteListIndexAccessor.class.getClassLoader());
65
                assert instance != null;
66
            } catch (ClassNotFoundException ex) {
67
                Exceptions.printStackTrace(ex);
68
            }
69
        }
70
        return instance;
71
72
    }
73
74
    public static void setInstance(@NonNull final WhiteListIndexAccessor _instance) {
75
        Parameters.notNull("_instance", _instance); //NOI18N
76
        instance = _instance;
77
    }
78
79
    public abstract void refresh(@NonNull URL root);
80
    public abstract WhiteListIndex.Problem createProblem(
81
            @NonNull WhiteListQuery.Result result,
82
            @NonNull FileObject root,
83
            @NonNull String key,
84
            int line);
85
}
(-)a/java.editor/src/org/netbeans/modules/java/editor/whitelist/WhiteListIndexerPlugin.java (-21 / +74 lines)
Lines 39-67 Link Here
39
 *
39
 *
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
41
 */
41
 */
42
package org.netbeans.modules.java.editor.whitelist;
42
package org.netbeans.modules.whitelist.index;
43
43
44
import com.sun.source.tree.CompilationUnitTree;
44
import com.sun.source.tree.CompilationUnitTree;
45
import com.sun.source.tree.LineMap;
45
import com.sun.source.tree.LineMap;
46
import com.sun.source.tree.Tree;
46
import com.sun.source.util.SourcePositions;
47
import com.sun.source.util.SourcePositions;
47
import com.sun.source.util.Trees;
48
import com.sun.source.util.Trees;
48
import java.io.File;
49
import java.io.File;
49
import java.io.IOException;
50
import java.io.IOException;
50
import java.net.URL;
51
import java.net.URL;
51
import java.util.LinkedList;
52
import java.util.ArrayList;
53
import java.util.Collection;
52
import java.util.List;
54
import java.util.List;
53
import java.util.Map;
55
import java.util.Map;
54
import java.util.concurrent.ConcurrentHashMap;
56
import java.util.concurrent.ConcurrentHashMap;
55
import java.util.concurrent.atomic.AtomicBoolean;
56
import org.netbeans.api.annotations.common.CheckForNull;
57
import org.netbeans.api.annotations.common.CheckForNull;
57
import org.netbeans.api.annotations.common.NonNull;
58
import org.netbeans.api.annotations.common.NonNull;
59
import org.netbeans.api.annotations.common.NullAllowed;
58
import org.netbeans.api.editor.mimelookup.MimeRegistration;
60
import org.netbeans.api.editor.mimelookup.MimeRegistration;
59
import org.netbeans.api.whitelist.WhiteListQuery;
61
import org.netbeans.api.whitelist.WhiteListQuery;
60
import org.netbeans.modules.java.preprocessorbridge.spi.JavaIndexerPlugin;
62
import org.netbeans.modules.java.preprocessorbridge.spi.JavaIndexerPlugin;
61
import org.netbeans.modules.parsing.lucene.support.DocumentIndex;
63
import org.netbeans.modules.parsing.lucene.support.DocumentIndex;
64
import org.netbeans.modules.parsing.lucene.support.Index;
62
import org.netbeans.modules.parsing.lucene.support.IndexDocument;
65
import org.netbeans.modules.parsing.lucene.support.IndexDocument;
63
import org.netbeans.modules.parsing.lucene.support.IndexManager;
66
import org.netbeans.modules.parsing.lucene.support.IndexManager;
67
import org.netbeans.modules.parsing.lucene.support.Queries.QueryKind;
64
import org.netbeans.modules.parsing.spi.indexing.Indexable;
68
import org.netbeans.modules.parsing.spi.indexing.Indexable;
69
import org.netbeans.api.whitelist.index.WhiteListIndex;
70
import org.netbeans.api.whitelist.support.WhiteListSupport;
65
import org.openide.filesystems.FileObject;
71
import org.openide.filesystems.FileObject;
66
import org.openide.filesystems.FileUtil;
72
import org.openide.filesystems.FileUtil;
67
import org.openide.filesystems.URLMapper;
73
import org.openide.filesystems.URLMapper;
Lines 75-82 Link Here
75
public class WhiteListIndexerPlugin implements JavaIndexerPlugin {
81
public class WhiteListIndexerPlugin implements JavaIndexerPlugin {
76
82
77
    private static final String WHITE_LIST_INDEX = "whitelist"; //NOI18N
83
    private static final String WHITE_LIST_INDEX = "whitelist"; //NOI18N
78
    static final String MSG = "msg";    //NOI18N
84
    private static final String MSG = "msg";    //NOI18N
79
    static final String LINE = "line";  //NOI18N
85
    private static final String NAME = "name";  //NOI18N
86
    private static final String LINE = "line";  //NOI18N
80
    private static Map<URL,File> roots2whiteListDirs = new ConcurrentHashMap<URL, File>();
87
    private static Map<URL,File> roots2whiteListDirs = new ConcurrentHashMap<URL, File>();
81
88
82
    private final URL root;
89
    private final URL root;
Lines 104-123 Link Here
104
            @NonNull final Lookup services) {
111
            @NonNull final Lookup services) {
105
        final Trees trees = services.lookup(Trees.class);
112
        final Trees trees = services.lookup(Trees.class);
106
        assert trees != null;
113
        assert trees != null;
107
        final WhiteListScanner scanner = new WhiteListScanner(
114
        final Map<? extends Tree, ? extends WhiteListQuery.Result> problems = WhiteListSupport.getWhiteListViolations(toProcess, whiteList, trees, null);
108
                trees,
115
        assert problems != null;
109
                whiteList,
110
                new AtomicBoolean());
111
        final List<WhiteListScanner.Problem> problems = new LinkedList<WhiteListScanner.Problem>();
112
        scanner.scan(toProcess,problems);
113
        final LineMap lm = toProcess.getLineMap();
116
        final LineMap lm = toProcess.getLineMap();
114
        final SourcePositions sp = trees.getSourcePositions();
117
        final SourcePositions sp = trees.getSourcePositions();
115
        for (WhiteListScanner.Problem p : problems) {
118
        for (Map.Entry<? extends Tree, ? extends WhiteListQuery.Result> p : problems.entrySet()) {
116
            final int start = (int) sp.getStartPosition(toProcess, p.tree);
119
            final int start = (int) sp.getStartPosition(toProcess, p.getKey());
117
            int ln;
120
            int ln;
118
            if (start>=0 && (ln=(int)lm.getLineNumber(start))>=0) {
121
            if (start>=0 && (ln=(int)lm.getLineNumber(start))>=0) {
119
                final IndexDocument doc = IndexManager.createDocument(indexable.getRelativePath());
122
                final IndexDocument doc = IndexManager.createDocument(indexable.getRelativePath());
120
                doc.addPair(MSG, p.description, false, true);
123
                doc.addPair(MSG, p.getValue().getViolatedRuleDescription(), false, true);
121
                doc.addPair(LINE, Integer.toString(ln), false, true);
124
                doc.addPair(LINE, Integer.toString(ln), false, true);
122
                index.addDocument(doc);
125
                index.addDocument(doc);
123
            }
126
            }
Lines 134-143 Link Here
134
        try {
137
        try {
135
            index.store(true);
138
            index.store(true);
136
            roots2whiteListDirs.put(root, whiteListDir);
139
            roots2whiteListDirs.put(root, whiteListDir);
137
            final WhiteListTaskProvider tp = WhiteListTaskProvider.getInstance();
140
            WhiteListIndexAccessor.getInstance().refresh(root);
138
            if (tp != null) {
139
                tp.refresh(root);
140
            }
141
        } catch (IOException ex) {
141
        } catch (IOException ex) {
142
            Exceptions.printStackTrace(ex);
142
            Exceptions.printStackTrace(ex);
143
        } finally {
143
        } finally {
Lines 150-157 Link Here
150
    }
150
    }
151
151
152
    @CheckForNull
152
    @CheckForNull
153
    static File getWhiteListDir(@NonNull final URL root) {
153
    private static DocumentIndex getIndex(@NonNull final FileObject root) {
154
        return roots2whiteListDirs.get(root);
154
        try {
155
            final File whiteListFolder = roots2whiteListDirs.get(root.getURL());
156
            if (whiteListFolder != null) {
157
                final DocumentIndex index = IndexManager.createDocumentIndex(whiteListFolder);
158
                return index.getStatus() == Index.Status.VALID ? index : null;
159
            }
160
        } catch (IOException ioe) {
161
            Exceptions.printStackTrace(ioe);
162
        }
163
        return null;
164
    }
165
166
    @NonNull
167
    public static Collection<? extends WhiteListIndex.Problem> getWhiteListViolations(
168
            @NonNull final FileObject root,
169
            @NullAllowed final FileObject resource) {
170
        final List<WhiteListIndex.Problem> result = new ArrayList<WhiteListIndex.Problem>();
171
        try {
172
            IndexManager.readAccess(new IndexManager.Action<Void>() {
173
                @Override
174
                public Void run() throws IOException, InterruptedException {
175
                    final DocumentIndex index = getIndex(root);
176
                    if (index != null) {
177
                        try {
178
                            for (IndexDocument doc : index.findByPrimaryKey(
179
                                    resource == null ? "" : FileUtil.getRelativePath(root,resource),    //NOI18N
180
                                    QueryKind.PREFIX)) {
181
                                try {
182
                                    final String key = doc.getPrimaryKey();
183
                                    String wlName = doc.getValue(NAME);
184
                                    if (wlName == null) {
185
                                        wlName = "";    //NOI18N
186
                                    }
187
                                    final String wlDesc = doc.getValue(MSG);
188
                                    final int line = Integer.parseInt(doc.getValue(LINE));
189
                                    final WhiteListQuery.Result wr = new WhiteListQuery.Result(false, wlName, wlDesc);
190
                                    result.add(WhiteListIndexAccessor.getInstance().createProblem(wr, root, key, line));
191
                                } catch (ArithmeticException ae) {
192
                                    Exceptions.printStackTrace(ae);
193
                                }
194
                            }
195
                        } finally {
196
                            index.close();
197
                        }
198
                    }
199
                    return null;
200
                }
201
            });
202
        } catch (IOException e) {
203
            Exceptions.printStackTrace(e);
204
        } catch (InterruptedException e) {
205
            Exceptions.printStackTrace(e);
206
        }
207
        return result;
155
    }
208
    }
156
209
157
    @MimeRegistration(mimeType="text/x-java",service=JavaIndexerPlugin.Factory.class)
210
    @MimeRegistration(mimeType="text/x-java",service=JavaIndexerPlugin.Factory.class)
Lines 159-165 Link Here
159
        @Override
212
        @Override
160
        public JavaIndexerPlugin create(final URL root, final FileObject cacheFolder) {
213
        public JavaIndexerPlugin create(final URL root, final FileObject cacheFolder) {
161
            try {
214
            try {
162
                File whiteListDir = getWhiteListDir(root);
215
                File whiteListDir = roots2whiteListDirs.get(root);
163
                if (whiteListDir == null) {
216
                if (whiteListDir == null) {
164
                    //First time
217
                    //First time
165
                    final FileObject whiteListFolder = FileUtil.createFolder(cacheFolder, WHITE_LIST_INDEX);
218
                    final FileObject whiteListFolder = FileUtil.createFolder(cacheFolder, WHITE_LIST_INDEX);

Return to bug 202063