• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
3  * Copyright (C) 2011, 2013-2018 The JavaParser Team.
4  *
5  * This file is part of JavaParser.
6  *
7  * JavaParser can be used either under the terms of
8  * a) the GNU Lesser General Public License as published by
9  *     the Free Software Foundation, either version 3 of the License, or
10  *     (at your option) any later version.
11  * b) the terms of the Apache License
12  *
13  * You should have received a copy of both licenses in LICENCE.LGPL and
14  * LICENCE.APACHE. Please refer to those files for details.
15  *
16  * JavaParser is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU Lesser General Public License for more details.
20  */
21 
22 package com.github.javaparser.symbolsolver.utils;
23 
24 import com.github.javaparser.JavaParser;
25 import com.github.javaparser.ParseProblemException;
26 import com.github.javaparser.ast.CompilationUnit;
27 import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
28 import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
29 import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
30 import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
31 import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
32 import com.github.javaparser.utils.Log;
33 
34 import java.io.FileNotFoundException;
35 import java.io.IOException;
36 import java.nio.file.*;
37 import java.nio.file.attribute.BasicFileAttributes;
38 import java.util.HashSet;
39 import java.util.Optional;
40 import java.util.Set;
41 
42 import static com.github.javaparser.utils.Utils.assertNotNull;
43 import static java.nio.file.FileVisitResult.*;
44 
45 /**
46  * Utility class to add all jars and roots of java files of the provided path to a TypeSolver instance.
47  * It traverses the file directory tree and adds all files ending in either .java or .jar.
48  */
49 public class SymbolSolverQuickSetup {
50 
51     public interface DirFilter {
filter(Path path)52         boolean filter(Path path);
53     }
54 
55     private final Path root;
56     private CombinedTypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(false));
57     private DirFilter dirFilter = path -> false;
58 
SymbolSolverQuickSetup(Path root)59     public SymbolSolverQuickSetup(Path root) {
60         assertNotNull(root);
61         if (!Files.isDirectory(root)) {
62             throw new IllegalArgumentException("Only directories are allowed as root path!");
63         }
64         this.root = root.normalize();
65         Log.info("New symbol source root at \"%s\"", this.root);
66     }
67 
SymbolSolverQuickSetup(Path root, DirFilter dirFilter)68     public SymbolSolverQuickSetup(Path root, DirFilter dirFilter) {
69         this(root);
70         this.dirFilter = dirFilter;
71     }
72 
walk()73     public TypeSolver walk() throws IOException {
74         Files.walkFileTree(root, new JavaSymbolSolverWalker());
75         Files.walkFileTree(root, new JarVisitor());
76         return typeSolver;
77     }
78 
tryToWalk()79     public Optional<TypeSolver> tryToWalk() {
80         try {
81             return Optional.of(walk());
82         } catch (IOException e) {
83             Log.error(e, "Unable to walk root " + root);
84             return Optional.empty();
85         }
86     }
87 
getTypeSolver()88     public TypeSolver getTypeSolver() {
89         return typeSolver;
90     }
91 
92     /**
93      * The path that was passed in the constructor.
94      */
getRoot()95     public Path getRoot() {
96         return root;
97     }
98 
99     /**
100      * Walks the directory and adds the roots of the java files to the TypeSolver
101      */
102     private class JavaSymbolSolverWalker extends SimpleFileVisitor<Path> {
103 
104         private final Set<Path> roots = new HashSet<>();
105 
106         @Override
visitFile(Path file, BasicFileAttributes attr)107         public FileVisitResult visitFile(Path file, BasicFileAttributes attr) throws FileNotFoundException {
108             if (attr.isRegularFile()) {
109                 PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**.java");
110                 if (matcher.matches(file)) {
111                     try {
112                         Optional<Path> root = JavaParser.parse(file.toFile()).getStorage()
113                                 .map(CompilationUnit.Storage::getSourceRoot);
114                         if (root.isPresent()) {
115                             typeSolver.add(new JavaParserTypeSolver(root.get().toFile()));
116                             if (roots.add(root.get())) {
117                                 Log.trace("Added dir " + root.get() + " to the TypeSolver");
118                                 return SKIP_SIBLINGS;
119                             }
120                         }
121                     } catch (ParseProblemException e) {
122                         Log.error(e, "Unable to parse file " + file);
123                     }
124                 }
125             }
126             return CONTINUE;
127         }
128 
129         @Override
preVisitDirectory(Path dir, BasicFileAttributes attrs)130         public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
131             if (Files.isHidden(dir) || dirFilter.filter(dir) || roots.stream().anyMatch(dir::startsWith)) {
132                 return SKIP_SUBTREE;
133             }
134             return CONTINUE;
135         }
136     }
137 
138     private class JarVisitor extends SimpleFileVisitor<Path> {
139 
140         @Override
visitFile(Path file, BasicFileAttributes attr)141         public FileVisitResult visitFile(Path file, BasicFileAttributes attr) throws IOException {
142             if (attr.isRegularFile()) {
143                 PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**.jar");
144                 if (matcher.matches(file)) {
145                     typeSolver.add(new JarTypeSolver(file.toString()));
146                 }
147             }
148             return CONTINUE;
149         }
150     }
151 }
152 
153