Repository navigation
Expand file tree
/
Copy pathClassTree.java
More file actions
198 lines (165 loc) · 7.16 KB
/
Copy pathClassTree.java
File metadata and controls
198 lines (165 loc) · 7.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/*
* Copyright (c) 2010, ReportMill Software. All rights reserved.
*/
package javakit.resolver;
import snap.util.*;
import snap.web.*;
import java.util.*;
/**
* Represents a tree of packages/classes.
*/
public abstract class ClassTree {
/**
* A record to hold package or class entry.
*/
public record ClassTreeNode(String fullName, boolean isPackage, String simpleName) { }
/**
* Returns whether given package name is known.
*/
public abstract boolean isKnownPackageName(String packageName);
/**
* Returns ClassTreeNode array for classes and child packages for given node.
*/
public abstract List<ClassTreeNode> getClassTreeNodesForPackageName(String packageName);
/**
* Creates a class tree for given class paths.
*/
public static ClassTree getClassTreeForClassPaths(String[] classPaths)
{
// Get class trees for base modules
List<String> moduleNames = List.of("java.base", "java.prefs", "java.desktop");
List<ClassTreeForSite> moduleClassTrees = ListUtils.map(moduleNames, ClassTree::getClassTreeForModuleName);
List<ClassTreeForSite> classTreeList = new ArrayList<>(moduleClassTrees);
// Add class trees for class paths
List<ClassTreeForSite> classPathSites = ArrayUtils.mapNonNullToList(classPaths, ClassTree::getClassTreeForClassPath);
classTreeList.addAll(classPathSites);
// Return class tree for list
return new ClassTreeForSites(classTreeList);
}
/**
* Returns the ClassTree for module name.
*/
static ClassTreeForSite getClassTreeForModuleName(String moduleName)
{
if (moduleName.equals("java.base") || moduleName.equals("java.desktop"))
return new ClassTreeForModuleFile(moduleName);
WebURL moduleUrl = WebURL.getUrl("jrt:/" + moduleName); assert moduleUrl != null;
return new ClassTreeForSite(moduleUrl.getSite());
}
/**
* Returns a ClassTree for given class path.
*/
private static ClassTreeForSite getClassTreeForClassPath(String classPath)
{
// Get URL for class path
WebURL classPathURL = WebURL.getUrl(classPath);
if (classPathURL == null) {
System.err.println("ClassTree.getClassFileSitesForResolver: Can't resolve class path entry: " + classPath);
return null;
}
// Get site for class path entry and add to sites
WebSite classPathSite = classPathURL.getAsSite();
return new ClassTreeForSite(classPathSite);
}
/**
* This class represents a class tree for a website.
*/
static class ClassTreeForSite extends ClassTree {
// The web site
private WebSite _site;
/**
* Constructor.
*/
public ClassTreeForSite(WebSite aSite) { _site = aSite; }
@Override
public boolean isKnownPackageName(String packageName)
{
if (packageName.isEmpty()) return true;
String filePath = '/' + packageName.replace(".", "/");
return isKnownPackageFilePath(filePath);
}
@Override
public List<ClassTreeNode> getClassTreeNodesForPackageName(String packageName)
{
String filePath = '/' + packageName.replace(".", "/");
List<ClassTreeNode> classTreeNodes = new ArrayList<>();
findClassTreeNodesForPackageFilePath(filePath, classTreeNodes);
return classTreeNodes;
}
// Returns whether given package file path is known
boolean isKnownPackageFilePath(String packageFilePath)
{
WebFile file = _site.getFileForPath(packageFilePath);
return file != null && file.isDir() && file.getPath().equals(packageFilePath);
}
// Finds ClassTreeNode for classes and child packages for given package file path
void findClassTreeNodesForPackageFilePath(String packageFilePath, List<ClassTreeNode> classTreeNodes)
{
WebFile packageFile = _site.getFileForPath(packageFilePath);
if (packageFile == null)
return;
// Iterate over files and Find child classes and packages for each
ClassTreeUtils.findChildNodesForDirFile(packageFile, classTreeNodes);
}
@Override
public String toString() { return getClass().getSimpleName() + ": " + _site.getUrlAddress(); }
}
/**
* A class tree for a list of class tree sites.
*/
static class ClassTreeForSites extends ClassTree {
// The list of class path sites
private List<ClassTreeForSite> _classPathSites;
public ClassTreeForSites(List<ClassTreeForSite> classPathSites)
{
super();
_classPathSites = classPathSites;
}
@Override
public boolean isKnownPackageName(String packageName)
{
if (packageName.isEmpty()) return true;
String filePath = '/' + packageName.replace(".", "/");
return ListUtils.hasMatch(_classPathSites, classTreeSite -> classTreeSite.isKnownPackageFilePath(filePath));
}
@Override
public List<javakit.resolver.ClassTree.ClassTreeNode> getClassTreeNodesForPackageName(String packageName)
{
String filePath = '/' + packageName.replace(".", "/");
// Create nodes list - if root package, add primitives
List<javakit.resolver.ClassTree.ClassTreeNode> classTreeNodes = new ArrayList<>();
if (packageName.isEmpty()) {
List<Class<?>> primitives = List.of(boolean.class, char.class, byte.class, short.class, int.class, long.class, float.class, double.class, void.class);
List<ClassTreeNode> primitiveNodes = ListUtils.map(primitives, cls -> ClassTreeUtils.createClassTreeNode(cls.getName(), false));
classTreeNodes.addAll(primitiveNodes);
}
_classPathSites.forEach(site -> site.findClassTreeNodesForPackageFilePath(filePath, classTreeNodes));
return classTreeNodes;
}
@Override
public String toString() { return getClass().getSimpleName() + ": " + _classPathSites; }
}
/**
* A class tree for a module that has a provided contents file.
*/
static class ClassTreeForModuleFile extends ClassTreeForSite {
// Map of class nodes for class path
private Map<String,List<ClassTreeNode>> _classPathNodes;
public ClassTreeForModuleFile(String moduleName)
{
super(null);
_classPathNodes = ClassTreeUtils.readClassNodesForModuleName(moduleName);
}
// Returns whether given package file path is known
@Override
boolean isKnownPackageFilePath(String packageFilePath) { return _classPathNodes.containsKey(packageFilePath); }
// Finds ClassTreeNode for classes and child packages for given package file path
@Override
void findClassTreeNodesForPackageFilePath(String packageFilePath, List<ClassTreeNode> classTreeNodes)
{
List<ClassTreeNode> nodesForPath = _classPathNodes.get(packageFilePath);
if (nodesForPath != null)
classTreeNodes.addAll(nodesForPath);
}
}
}