On Tue, Dec 2, 2008 at 1:53 AM, Stuart Sierra
<[EMAIL PROTECTED]> wrote:
>
> On Nov 28, 7:41 am, lpetit <[EMAIL PROTECTED]> wrote:
>> The "fix import" action could try to resolve an unknown symbol by
>> first searching the symbol in one of the classpath available
>> namespaces, and then search for java classes in the classpath.
>> It could then add an import/require command for each found resolution
>> (and if several resolutions found, ad all, letting the user solve
>> manually the conflict).
>>
>> This could be provided as an IDE action, and also, I think, as a
>> clojure function that could work directly on files.
>
> JDEE <http://jdee.sourceforge.net/> does this, for Java source code.

This is far from complete and should be expanded but I got this from a
few hours of hacking:

(import '(java.util.jar JarFile JarEntry)
        '(java.io File IOException))

(defn find-all
  "(for [x coll :when (test-fn item (key-fn x))] x)"
  ([item coll test-fn key-fn]
     (filter #(test-fn item (key-fn %)) coll))
  ([item coll test-fn]
     (find-all item coll test-fn #'identity))
  ([item coll]
     (find-all item coll #'= #'identity)))

(defn find-reg-in-seq
  ([reg coll key]
     (find-all reg coll #'re-find key))
  ([reg coll]
     (find-reg-in-seq reg coll #'identity)))

(defn dir-or-jar->seq
  [path-entity]
  (cond (instance? File path-entity)
        (if (.isDirectory #^File path-entity)
          (file-seq path-entity)
          (throw (IOException. "Cannot search within a file.")))
        (instance? JarFile path-entity)
        (enumeration-seq (.entries #^JarFile path-entity))
        true
        (throw (UnsupportedOperationException.
                (str "Cannot handle " (class path-entity))))))

(defn find-re-in-path-entity [reg path-entity]
  (find-reg-in-seq reg
                   (dir-or-jar->seq path-entity)
                   #(.getName %)))

(defn find-class-in-path-entity [class-name path-entity]
  (find-re-in-path-entity (re-pattern (str #"[^A-Za-z0-9$]" class-name
".class$"))
                          path-entity))

(def *rt-jar* (.toString
               (File.
                (File. (.getProperty System "java.home") "lib") "rt.jar")))

(defn find-java-class-in-classpath [class-name]
  (let [cpath (cons *rt-jar* (.split (.getProperty System "java.class.path")
                                     (.getProperty System "path.separator")))]
   (mapcat #'identity
           (filter #(not (nil? %))
                   (for [#^String path cpath]
                     (find-class-in-path-entity class-name
                                                (if (.endsWith path ".jar")
                                                  (JarFile. path)
                                                  (File. path))))))))

(defn find-java-class [class-name]
  (map (fn [o] (let [#^String s (.toString #^Object o)
                     l (.length s)]
                 (.. s (substring 0 (- l 6)) (replace "/" "."))))
       (find-java-class-in-classpath class-name)))

;;; *eof*

It looks inside all jar files and at all .class files inside
directories in the classpath and rt.jar -- the java runtime library
and returns the list of classes that exist on the classpath.

I haven't written it inside a namespace etc.  It's saved in a file
named "stuff.clj" because I couldnt' think of a good name.

user> (load "stuff")
nil
user> (find-java-class "List")
("com.sun.xml.internal.bind.v2.schemagen.xmlschema.List"
"java.awt.List" "java.util.List")
user> (find-java-class "URL")
("java.net.URL")
user> (find-java-class "NonExistent")
("com.sun.corba.se.impl.protocol.NonExistent")
user> (find-java-class "NonExistentClass")
nil

;; I never expected there'd be a class named "NonExistent" ;-)

The above code is released under public domain so anyone may do what
they wish with it.

Cheers
Vijay

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to