diff --git a/src/cryogen_core/classpath_able_io/jar.clj b/src/cryogen_core/classpath_able_io/jar.clj index 95883f7..d35a5b9 100644 --- a/src/cryogen_core/classpath_able_io/jar.clj +++ b/src/cryogen_core/classpath_able_io/jar.clj @@ -12,6 +12,7 @@ [cryogen-core.classpath-able-io.type :as type] [cryogen-core.classpath-able-io.fs :as fs]) (:import [java.net URI] + [java.util.jar JarFile JarEntry] [java.nio.file Paths Files FileSystems])) (defn is-from-classpath-jar? @@ -48,14 +49,69 @@ (FileSystems/newFileSystem (filesystem-uri resource-uri) {})))) (defn path-if-exists ;:- JavaPath - [resource-path ;:- VirtualPath + [& path-elements ;:- VirtualPath ] (try - (let [resource-uri (.toURI (io/resource resource-path))] + (let [resource-uri (.toURI (io/resource (st/join "/" path-elements)))] (when (is-from-classpath-jar? resource-uri) (init-file-system resource-uri)) ;; TODO: hier steckt auch eine "from-fs-cp" funktionalität drinne (when (Files/exists (Paths/get resource-uri) fs/no-link-option) (Paths/get resource-uri))) (catch Exception e - nil))) \ No newline at end of file + nil))) + +(defn filter-and-remove-for-dir + [path-to-filter-for + elements-list] + (let [norm-path-to-filter-for (str path-to-filter-for "/")] + (map + #(subs % (count norm-path-to-filter-for)) + (filter + (fn [element] (and (st/starts-with? element norm-path-to-filter-for) + (not (= element norm-path-to-filter-for)))) + elements-list)))) + +(defn jar-file-for-resource + [resource] + (JarFile. + (.toFile + (Paths/get + (URI. + (.getSchemeSpecificPart + (filesystem-uri (:java-uri resource)))))))) + +(defn list-entries-for-dir ;:- [VirtualPath] + [resource ;:- Resource + ] + (filter-and-remove-for-dir + (:virtual-path resource) + (map #(.getName ^JarEntry %) + (enumeration-seq + (.entries + (jar-file-for-resource resource)))))) + +(defn get-resources;:- [Resource] + [base-path ;:- VirtualPath + paths ;:- [VirtualPath] + ] + (loop [paths paths + result []] + (if (not (empty? paths)) + (do + (let [path-to-work-with (first paths) + resource-to-work-with (create-resource + (path-if-exists base-path path-to-work-with) + path-to-work-with) + result (into result + [resource-to-work-with])] + (cond + (nil? resource-to-work-with) [] + (type/is-file? resource-to-work-with) + (recur (drop 1 paths) result) + :else + (recur (into (drop 1 paths) + (map #(str path-to-work-with "/" %) + (list-entries-for-dir resource-to-work-with))) + result)))) + result))) diff --git a/test/cryogen_core/classpath_able_io/jar_test.clj b/test/cryogen_core/classpath_able_io/jar_test.clj index 9f4a783..94f0c6d 100644 --- a/test/cryogen_core/classpath_able_io/jar_test.clj +++ b/test/cryogen_core/classpath_able_io/jar_test.clj @@ -25,3 +25,10 @@ (is (= nil (sut/path-if-exists "not-existing"))) + +(deftest test-get-resources + (is + (= [{:virtual-path "dummy" :source-type :filesystem :resource-type :dir} + {:virtual-path "dummy/dummy_from_jar" :source-type :filesystem :resource-type :file}] + (map ftt/filter-object + (sut/get-resources "" ["dummy"])))))