Mercurial > lasercutter
comparison src/clojure/contrib/java_utils.clj @ 10:ef7dbbd6452c
added clojure source goodness
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 06:25:44 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
9:35cf337adfcf | 10:ef7dbbd6452c |
---|---|
1 ; Copyright (c) Stuart Halloway & Contributors, April 2009. All rights reserved. | |
2 ; The use and distribution terms for this software are covered by the | |
3 ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) | |
4 ; which can be found in the file epl-v10.html at the root of this distribution. | |
5 ; By using this software in any fashion, you are agreeing to be bound by | |
6 ; the terms of this license. | |
7 ; You must not remove this notice, or any other, from this software. | |
8 | |
9 ;; | |
10 ;; CHANGELOG | |
11 ;; | |
12 ;; Most functions deprecated in 1.2. Some already exist in c.c.io, and | |
13 ;; some replaced by c.c.reflections | |
14 | |
15 (ns | |
16 ^{:author "Stuart Halloway, Stephen C. Gilardi, Shawn Hoover, Perry Trolard, Stuart Sierra", | |
17 :doc "A set of utilties for dealing with Java stuff like files and properties. | |
18 | |
19 Design goals: | |
20 | |
21 (1) Ease-of-use. These APIs should be convenient. Performance is secondary. | |
22 | |
23 (2) Duck typing. I hate having to think about the difference between | |
24 a string that names a file, and a File. Ditto for a ton of other | |
25 wrapper classes in the Java world (URL, InternetAddress). With these | |
26 APIs you should be able to think about domain equivalence, not type | |
27 equivalence. | |
28 | |
29 (3) No bossiness. I am not marking any of these functions as private | |
30 the docstrings will tell you the intended usage but do what works for you. | |
31 | |
32 Feedback welcome! | |
33 | |
34 If something in this module violates the principle of least surprise, please | |
35 let me (Stu) and the Clojure community know via the mailing list. | |
36 Contributors: | |
37 | |
38 Stuart Halloway | |
39 Stephen C. Gilardi | |
40 Shawn Hoover | |
41 Perry Trolard | |
42 Stuart Sierra | |
43 "} | |
44 clojure.contrib.java-utils | |
45 (:import [java.io File FileOutputStream] | |
46 [java.util Properties] | |
47 [java.net URI URL])) | |
48 | |
49 (defmulti relative-path-string | |
50 "Interpret a String or java.io.File as a relative path string. | |
51 Building block for clojure.contrib.java-utils/file." | |
52 {:deprecated "1.2"} | |
53 class) | |
54 | |
55 (defmethod relative-path-string String [^String s] | |
56 (relative-path-string (File. s))) | |
57 | |
58 (defmethod relative-path-string File [^File f] | |
59 (if (.isAbsolute f) | |
60 (throw (IllegalArgumentException. (str f " is not a relative path"))) | |
61 (.getPath f))) | |
62 | |
63 (defmulti ^File as-file | |
64 "Interpret a String or a java.io.File as a File. Building block | |
65 for clojure.contrib.java-utils/file, which you should prefer | |
66 in most cases." | |
67 {:deprecated "1.2"} | |
68 class) | |
69 (defmethod as-file String [^String s] (File. s)) | |
70 (defmethod as-file File [f] f) | |
71 | |
72 (defn ^File file | |
73 "Returns a java.io.File from string or file args." | |
74 {:deprecated "1.2"} | |
75 ([arg] | |
76 (as-file arg)) | |
77 ([parent child] | |
78 (File. ^File (as-file parent) ^String (relative-path-string child))) | |
79 ([parent child & more] | |
80 (reduce file (file parent child) more))) | |
81 | |
82 (defn as-str | |
83 "Like clojure.core/str, but if an argument is a keyword or symbol, | |
84 its name will be used instead of its literal representation. | |
85 | |
86 Example: | |
87 (str :foo :bar) ;;=> \":foo:bar\" | |
88 (as-str :foo :bar) ;;=> \"foobar\" | |
89 | |
90 Note that this does not apply to keywords or symbols nested within | |
91 data structures; they will be rendered as with str. | |
92 | |
93 Example: | |
94 (str {:foo :bar}) ;;=> \"{:foo :bar}\" | |
95 (as-str {:foo :bar}) ;;=> \"{:foo :bar}\" " | |
96 {:deprecated "1.2"} | |
97 ([] "") | |
98 ([x] (if (instance? clojure.lang.Named x) | |
99 (name x) | |
100 (str x))) | |
101 ([x & ys] | |
102 ((fn [^StringBuilder sb more] | |
103 (if more | |
104 (recur (. sb (append (as-str (first more)))) (next more)) | |
105 (str sb))) | |
106 (new StringBuilder ^String (as-str x)) ys))) | |
107 | |
108 (defn get-system-property | |
109 "Get a system property." | |
110 ([stringable] | |
111 (System/getProperty (as-str stringable))) | |
112 ([stringable default] | |
113 (System/getProperty (as-str stringable) default))) | |
114 | |
115 (defn set-system-properties | |
116 "Set some system properties. Nil clears a property." | |
117 [settings] | |
118 (doseq [[name val] settings] | |
119 (if val | |
120 (System/setProperty (as-str name) (as-str val)) | |
121 (System/clearProperty (as-str name))))) | |
122 | |
123 (defmacro with-system-properties | |
124 "setting => property-name value | |
125 | |
126 Sets the system properties to the supplied values, executes the body, and | |
127 sets the properties back to their original values. Values of nil are | |
128 translated to a clearing of the property." | |
129 [settings & body] | |
130 `(let [settings# ~settings | |
131 current# (reduce (fn [coll# k#] | |
132 (assoc coll# k# (get-system-property k#))) | |
133 {} | |
134 (keys settings#))] | |
135 (set-system-properties settings#) | |
136 (try | |
137 ~@body | |
138 (finally | |
139 (set-system-properties current#))))) | |
140 | |
141 | |
142 ; Not there is no corresponding props->map. Just destructure! | |
143 (defn ^Properties as-properties | |
144 "Convert any seq of pairs to a java.utils.Properties instance. | |
145 Uses as-str to convert both keys and values into strings." | |
146 {:tag Properties} | |
147 [m] | |
148 (let [p (Properties.)] | |
149 (doseq [[k v] m] | |
150 (.setProperty p (as-str k) (as-str v))) | |
151 p)) | |
152 | |
153 (defn read-properties | |
154 "Read properties from file-able." | |
155 [file-able] | |
156 (with-open [f (java.io.FileInputStream. (file file-able))] | |
157 (doto (Properties.) | |
158 (.load f)))) | |
159 | |
160 (defn write-properties | |
161 "Write properties to file-able." | |
162 {:tag Properties} | |
163 ([m file-able] (write-properties m file-able nil)) | |
164 ([m file-able comments] | |
165 (with-open [^FileOutputStream f (FileOutputStream. (file file-able))] | |
166 (doto (as-properties m) | |
167 (.store f ^String comments))))) | |
168 | |
169 (defn delete-file | |
170 "Delete file f. Raise an exception if it fails unless silently is true." | |
171 {:deprecated "1.2"} | |
172 [f & [silently]] | |
173 (or (.delete (file f)) | |
174 silently | |
175 (throw (java.io.IOException. (str "Couldn't delete " f))))) | |
176 | |
177 (defn delete-file-recursively | |
178 "Delete file f. If it's a directory, recursively delete all its contents. | |
179 Raise an exception if any deletion fails unless silently is true." | |
180 {:deprecated "1.2"} | |
181 [f & [silently]] | |
182 (let [f (file f)] | |
183 (if (.isDirectory f) | |
184 (doseq [child (.listFiles f)] | |
185 (delete-file-recursively child silently))) | |
186 (delete-file f silently))) | |
187 | |
188 (defmulti | |
189 ^{:deprecated "1.2" | |
190 :doc "Coerces argument (URL, URI, or String) to a java.net.URL." | |
191 :arglists '([arg])} | |
192 as-url type) | |
193 | |
194 (defmethod as-url URL [x] x) | |
195 | |
196 (defmethod as-url URI [^URI x] (.toURL x)) | |
197 | |
198 (defmethod as-url String [^String x] (URL. x)) | |
199 | |
200 (defmethod as-url File [^File x] (.toURL x)) | |
201 | |
202 (defn wall-hack-method | |
203 "Calls a private or protected method. | |
204 params is a vector of class which correspond to the arguments to the method | |
205 obj is nil for static methods, the instance object otherwise | |
206 the method name is given as a symbol or a keyword (something Named)" | |
207 {:deprecated "1.2"} | |
208 [class-name method-name params obj & args] | |
209 (-> class-name (.getDeclaredMethod (name method-name) (into-array Class params)) | |
210 (doto (.setAccessible true)) | |
211 (.invoke obj (into-array Object args)))) | |
212 | |
213 (defn wall-hack-field | |
214 "Access to private or protected field." | |
215 {:deprecated "1.2"} | |
216 [class-name field-name obj] | |
217 (-> class-name (.getDeclaredField (name field-name)) | |
218 (doto (.setAccessible true)) | |
219 (.get obj))) |