|
41 | 41 | (defn expand-wildcard
|
42 | 42 | "Expands a wildcard path entry to its matching .jar files (JDK 1.6+).
|
43 | 43 | If not expanding, returns the path entry as a single-element vector."
|
44 |
| - [#^String path] |
| 44 | + [^String path] |
45 | 45 | (let [f (File. path)]
|
46 | 46 | (if (= (.getName f) "*")
|
47 | 47 | (.. f getParentFile (list jar-filter))
|
|
55 | 55 | (.replace path ".class" ""))
|
56 | 56 | (.replace File/separator ".")))
|
57 | 57 |
|
58 |
| -(def path-class-files nil) |
59 | 58 | (defmulti path-class-files
|
60 | 59 | "Returns a list of classes found on the specified path location
|
61 | 60 | (jar or directory), each comprised of a map with the following keys:
|
62 | 61 | :name Java class or Clojure namespace name
|
63 | 62 | :loc Classpath entry (directory or jar) on which the class is located
|
64 | 63 | :file Path of the class file, relative to :loc"
|
65 |
| - (fn [#^File f _] |
66 |
| - (cond (.isDirectory f) :dir |
67 |
| - (jar? f) :jar |
| 64 | + (fn [^File f _] |
| 65 | + (cond (.isDirectory f) :dir |
| 66 | + (jar? f) :jar |
68 | 67 | (class-file? (.getName f)) :class)))
|
69 | 68 |
|
70 |
| -(defmethod path-class-files :default |
71 |
| - [& _] []) |
| 69 | +(defmethod path-class-files :default [& _] []) |
72 | 70 |
|
73 | 71 | (defmethod path-class-files :jar
|
74 | 72 | ;; Build class info for all jar entry class files.
|
75 |
| - [#^File f #^File loc] |
| 73 | + [^File f ^File loc] |
76 | 74 | (let [lp (.getPath loc)]
|
77 | 75 | (try
|
78 |
| - (map class-or-ns-name |
79 |
| - (filter class-file? |
80 |
| - (map #(.getName #^JarEntry %) |
81 |
| - (enumeration-seq (.entries (JarFile. f)))))) |
| 76 | + (into () |
| 77 | + (comp |
| 78 | + (map #(.getName ^JarEntry %)) |
| 79 | + (filter class-file?) |
| 80 | + (map class-or-ns-name)) |
| 81 | + (enumeration-seq (.entries (JarFile. f)))) |
82 | 82 | (catch Exception e [])))) ; fail gracefully if jar is unreadable
|
83 | 83 |
|
84 | 84 | (defmethod path-class-files :dir
|
85 | 85 | ;; Dispatch directories and files (excluding jars) recursively.
|
86 |
| - [#^File d #^File loc] |
87 |
| - (let [fs (.listFiles d (proxy [FilenameFilter] [] |
88 |
| - (accept [d n] (not (jar? (file n))))))] |
89 |
| - (reduce concat (for [f fs] (path-class-files f loc))))) |
| 86 | + [^File d ^File loc] |
| 87 | + (let [fs (.listFiles d (reify FilenameFilter |
| 88 | + (accept [_ dir name] |
| 89 | + (-> name file jar? not))))] |
| 90 | + (into () (mapcat #(path-class-files % loc)) fs))) |
90 | 91 |
|
91 | 92 | (defmethod path-class-files :class
|
92 | 93 | ;; Build class info using file path relative to parent classpath entry
|
93 | 94 | ;; location. Make sure it decends; a class can't be on classpath directly.
|
94 |
| - [#^File f #^File loc] |
| 95 | + [^File f ^File loc] |
95 | 96 | (let [fp (str f), lp (str loc)
|
96 | 97 | loc-pattern (re-pattern (Pattern/quote (str "^" loc)))]
|
97 | 98 | (if (re-find loc-pattern fp) ; must be descendent of loc
|
98 | 99 | (let [fpr (.substring fp (inc (count lp)))]
|
99 | 100 | [(class-or-ns-name fpr)])
|
100 | 101 | [])))
|
101 | 102 |
|
102 |
| -(defn scan-paths |
103 |
| - "Takes one or more classpath strings, scans each classpath entry location, and |
104 |
| - returns a list of all class file paths found, each relative to its parent |
105 |
| - directory or jar on the classpath." |
106 |
| - ([cp] |
107 |
| - (if cp |
108 |
| - (let [entries (enumeration-seq |
109 |
| - (StringTokenizer. cp File/pathSeparator)) |
110 |
| - locs (mapcat expand-wildcard entries)] |
111 |
| - (mapcat #(path-class-files % %) locs)) |
112 |
| - ()))) |
113 |
| - |
114 |
| -(defn- get-available-classes |
115 |
| - [] |
116 |
| - (->> (mapcat scan-paths (concat (map #(System/getProperty %) ["sun.boot.class.path" |
117 |
| - "java.ext.dirs" |
118 |
| - "java.class.path"]) |
119 |
| - (map #(.getName %) (cp/classpath-jarfiles)))) |
120 |
| - (remove clojure-fn-file?) |
121 |
| - (map symbol))) |
| 103 | +(defn path-entries-seq |
| 104 | + "Split a string on the 'path separator', i.e. ':'. Used for splitting multiple |
| 105 | + classpath entries." |
| 106 | + [path-str] |
| 107 | + (enumeration-seq |
| 108 | + (StringTokenizer. path-str File/pathSeparator))) |
| 109 | + |
| 110 | +(defn all-classpath-entries [] |
| 111 | + (into (map #(System/getProperty %) ["sun.boot.class.path" |
| 112 | + "java.ext.dirs" |
| 113 | + "java.class.path"]) |
| 114 | + (map #(.getName %) (cp/classpath-jarfiles)))) |
| 115 | + |
| 116 | +(defn- get-available-classes [] |
| 117 | + (into () |
| 118 | + (comp (mapcat path-entries-seq) |
| 119 | + (mapcat expand-wildcard) |
| 120 | + (mapcat #(path-class-files % %)) |
| 121 | + (remove clojure-fn-file?) |
| 122 | + (distinct) |
| 123 | + (map symbol)) |
| 124 | + (all-classpath-entries))) |
122 | 125 |
|
123 | 126 | (def available-classes
|
124 | 127 | (get-available-classes))
|
|
0 commit comments