1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.maven.jxr.pacman;
20
21 import java.io.IOException;
22 import java.nio.file.Path;
23 import java.util.Collection;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.Map;
27 import java.util.Set;
28
29 import org.codehaus.plexus.util.DirectoryScanner;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34 * Given a list of directories, parse them out and store them as rendered
35 * packages, classes, imports, etc.
36 */
37 public class PackageManager {
38 private static final Logger LOGGER = LoggerFactory.getLogger(PackageManager.class);
39
40 private final FileManager fileManager;
41
42 private Set<Path> directories = new HashSet<>();
43
44 /**
45 * All the packages that have been parsed
46 */
47 private Map<String, PackageType> packages = new HashMap<>();
48
49 /**
50 * The default Java package.
51 */
52 private PackageType defaultPackage = new PackageType();
53
54 /**
55 * The list of exclude patterns to use.
56 */
57 private String[] excludes = null;
58
59 /**
60 * The list of include patterns to use.
61 */
62 private String[] includes = {"**/*.java"};
63
64 public PackageManager(FileManager fileManager) {
65 this.fileManager = fileManager;
66 }
67
68 /**
69 * Given the name of a package (Ex: org.apache.maven.util) obtain it from
70 * the package manager.
71 *
72 * @param name name of package
73 * @return package type if found or default package type
74 */
75 public PackageType getPackageType(String name) {
76 // return the default package if the name is null.
77 if (name == null) {
78 return defaultPackage;
79 }
80
81 return this.packages.get(name);
82 }
83
84 /**
85 * Add a package to this package manager.
86 *
87 * @param packageType package type to add
88 */
89 public void addPackageType(PackageType packageType) {
90 this.packages.put(packageType.getName(), packageType);
91 }
92
93 /**
94 * Gets all of the packages in this package manager.
95 *
96 * @return package types
97 */
98 public Collection<PackageType> getPackageTypes() {
99 return packages.values();
100 }
101
102 /**
103 * Parse out all the directories on which this depends.
104 */
105 private void parse(Path baseDir) {
106 // Go through each directory and get the java source
107 // files for this dir.
108 LOGGER.debug("Scanning " + baseDir);
109 DirectoryScanner directoryScanner = new DirectoryScanner();
110 directoryScanner.setBasedir(baseDir.toFile());
111 directoryScanner.setExcludes(excludes);
112 directoryScanner.setIncludes(includes);
113 directoryScanner.scan();
114
115 for (String file : directoryScanner.getIncludedFiles()) {
116 LOGGER.debug("parsing... " + file);
117
118 // now parse out this file to get the packages/classname/etc
119 try {
120 Path fileName = baseDir.resolve(file);
121 JavaFile jfi = fileManager.getFile(fileName);
122
123 // now that we have this parsed out blend its information
124 // with the current package structure
125 PackageType jp = this.getPackageType(jfi.getPackageType().getName());
126
127 if (jp == null) {
128 this.addPackageType(jfi.getPackageType());
129 jp = jfi.getPackageType();
130 }
131
132 // Add the current file's class(es) to this global package.
133 if (jfi.getClassTypes() != null && !jfi.getClassTypes().isEmpty()) {
134 for (ClassType ct : jfi.getClassTypes()) {
135 jp.addClassType(ct);
136 }
137 }
138
139 } catch (IOException e) {
140 e.printStackTrace();
141 }
142 }
143 }
144
145 public void process(Path directory) {
146 if (this.directories.add(directory)) {
147 this.parse(directory);
148 }
149 }
150
151 /**
152 * Dump the package information to STDOUT. FOR DEBUG ONLY
153 */
154 public void dump() {
155
156 LOGGER.debug("Dumping out PackageManager structure");
157
158 for (PackageType current : getPackageTypes()) {
159 LOGGER.debug(current.getName());
160
161 // get the classes under the package and print those too.
162 for (ClassType currentClass : current.getClassTypes()) {
163 LOGGER.debug('\t' + currentClass.getName());
164 }
165 }
166 }
167
168 public void setExcludes(String[] excludes) {
169 this.excludes = excludes;
170 }
171
172 public void setIncludes(String[] includes) {
173 this.includes = includes;
174 }
175 }