So, my solution for this is actually quite simple:

(ns com.xdance.tapestry.serviceregistry

  (:import (org.apache.tapestry5.ioc ObjectLocator)))


(def ^:dynamic ^ObjectLocator *tapestry-registry-ref* (promise))


(defn init-registry [^ObjectLocator registry]

  "Must be called during service initialization to set up Tapestry registry
object"

  (deliver *tapestry-registry-ref* registry))


(defmacro with-tapestry-services [service-bindings & body]

  "Apply service bindings to body"

  (let [service-binding-pairs (partition-all 2 service-bindings)

        service-binding-exprs (map #(vector (first %1) `(.getService (deref
*tapestry-registry*) ~(second %1))) service-binding-pairs)

        service-binding-final (vec (reduce concat service-binding-exprs))]

    `(let ~service-binding-final ~@body)))


The only thing I need to do is to bind init-registry function to Tapestry
service interface and call it during startup phase. There might be better
approaches probably.

On Thu, Dec 18, 2014 at 6:49 PM, Ilya Obshadko <ilya.obsha...@gmail.com>
wrote:

> Thanks Howard, that's making a lot of sense.
>
> However my initial though was about injecting Clojure globals
> (specifically, one global containing service registry) during the call to
> "require" IFn. I still couldn't find any ways to manipulate initial Clojure
> environment, although there are obvious workarounds (for example I could
> have a specific function inside Clojure namespace that could be used to
> inject necessary objects using mutable globals). I'm still looking for more
> concise and accurate way to do that.
>
> On Thu, Dec 18, 2014 at 7:35 AM, Howard Lewis Ship <hls...@gmail.com>
> wrote:
>
>> Actually, Clojure interop with Java is very good, so a Clojure function
>> could be passed a Java object:
>>
>> (defn frobnicate-the-request
>>   [^Request request]
>>   (.setAttribute request "xyzzyx" (compute-the-magic-name)))
>>
>> The ^Request part is a type hint, it allows the Clojure compiler to
>> generate proper bytecode to access the methods of the request without
>> using
>> reflection.
>>
>> You quickly get used to the leading dot (which itself is sugar syntax over
>> the more primitive interop special form).
>>
>> Now, in terms of Clojure interop ... the library I put together ago on a
>> whim was about efficiently exposing Clojure functions bundled together as
>> an arbitrary Java interface.
>>
>> If you pass the Registry to a Clojure function, it will be quite capable
>> of
>> pulling out whatever it needs.
>>
>> A lot of the capabilities of Clojure are very familiar to Tapestry users:
>> thread bound values (inside Clojure vars) for example.
>>
>> My primary thought about integrating Clojure would be to allow a Tapestry
>> app to jump into Clojure to work with the Datomic APIs natively, rather
>> than the Java API to Datomic, which is decidedly second class.
>>
>> On Tue, Dec 16, 2014 at 5:24 AM, Thiago H de Paula Figueiredo <
>> thiag...@gmail.com> wrote:
>> >
>> > On Mon, 15 Dec 2014 18:29:22 -0200, Ilya Obshadko <
>> ilya.obsha...@gmail.com>
>> > wrote:
>> >
>> >
>> >  How are Java objects usually passed to Clojure code? The recommended
>> way?
>> >>>
>> >>
>> >> Java objects are passed to Clojure functions in exactly the same way
>> they
>> >> are passed to Java method (because internally Clojure function is just
>> an
>> >> implementation of IFn interface, and function call is invoke(...) on
>> its
>> >> instance).
>> >>
>> >
>> > Now I was the one who hasn't made a clear question. :) I'm not asking
>> > about how Clojure passes function arguments. I meant when you call
>> Clojure
>> > code from Java code, how do you pass a Java object so it can be used
>> inside
>> > Clojure code?
>> >
>> >  But I don't want to pass services to Clojure functions, I'd like to
>> >> inject them into Clojure namespace when clojure.core/require is
>> executed.
>> >>
>> >
>> > Got it. I have no idea how to do that given my almost no knowledge of
>> > Clojure. But I guess there's some way of doing that.
>> >
>> >
>> > --
>> > Thiago H. de Paula Figueiredo
>> > Tapestry, Java and Hibernate consultant and developer
>> > http://machina.com.br
>> >
>> > ---------------------------------------------------------------------
>> > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>> > For additional commands, e-mail: users-h...@tapestry.apache.org
>> >
>> >
>>
>> --
>> Howard M. Lewis Ship
>>
>> Creator of Apache Tapestry
>>
>> The source for Tapestry training, mentoring and support. Contact me to
>> learn how I can get you up and productive in Tapestry fast!
>>
>> (971) 678-5210
>> http://howardlewisship.com
>> @hlship
>>
>
>
>
> --
> Ilya Obshadko
>
>


-- 
Ilya Obshadko

Reply via email to