Simple caldav4j example in java and clojure

I was trying to access a caldav calendar through java and clojure to build a small application. But it wasn’t too easy.

caldav4j seemed to be very confusing and not so well maintained. There is no quick start guide and you are directed to have a look at the unit tests. But they are a compilation of interconnected classes and their hierarchies including a lot of deprecated classes being used – pretty confusing for a newcomer.

I had also problems using the alternative ical4j and it’s caldav connector. After some debugging it seemed incompatible with zimbra because of some strange filter constraints.

This might all be due to the fact that caldav is a complex protocol and I accepted to dig deeper into caldav4j.

Enough of the yacking, I traced down the necessary wire to build a basic example and hope it’ll help others looking for a quick start.

Java: https://github.com/dedeibel/list-events-caldav4j-example

Clojure: https://github.com/dedeibel/list-events-caldav4j-example-clojure

I tested it with zimbra. For google calendar a little more work might be required. The key might be in the GoogleCalDavDialect.java class.

 
Java:
 

    HttpClient httpClient = new HttpClient();
    // I tried it with zimbra - but I had no luck using google calendar
    httpClient.getHostConfiguration().setHost("CALDAVHOST", 443, "https");
    String username = "username";
    UsernamePasswordCredentials httpCredentials = new UsernamePasswordCredentials(username, "secret");
    httpClient.getState().setCredentials(AuthScope.ANY, httpCredentials);
    httpClient.getParams().setAuthenticationPreemptive(true);
    // Need a proxy?
    //httpClient.getHostConfiguration().setProxy("phost", 8080);

    CalDAVCollection collection = new CalDAVCollection(
        "/dav/"+ username +"/Calendar",
        (HostConfiguration) httpClient.getHostConfiguration().clone(),
        new CalDAV4JMethodFactory(),
        CalDAVConstants.PROC_ID_DEFAULT
        );

    GenerateQuery gq=new GenerateQuery();
    // TODO you might want to adjust the date
    gq.setFilter("VEVENT [20131001T000000Z;20131010T000000Z] : STATUS!=CANCELLED");
    // Get the raw caldav query
    // System.out.println("Query: "+ gq.prettyPrint());
    CalendarQuery calendarQuery = gq.generate();
    List<Calendar>calendars = collection.queryCalendars(httpClient, calendarQuery);

    for (Calendar calendar : calendars) {
      ComponentList componentList = calendar.getComponents().getComponents(Component.VEVENT);
      Iterator<VEvent> eventIterator = componentList.iterator();
      while (eventIterator.hasNext()) {
        VEvent ve = eventIterator.next();
        System.out.println("Event: "+ ve.toString());
        System.out.println("\n\n");
      }
    }

 
Clojure:
 

defn- create-query []
  (let [gq (GenerateQuery.)]
    ; Date Format yyyyMMdd
    (.setFilter gq "VEVENT [20131001T000000Z;20131010T000000Z] : STATUS!=CANCELLED")
    (.generate gq)))

(defn -main []
  (let [http-client (initialize-http-client)
        collection-path (:collection-path configuration)
        host-configuration (.clone (.getHostConfiguration http-client))
        method-factory (CalDAV4JMethodFactory.)
        collection (CalDAVCollection. collection-path host-configuration method-factory CalDAVConstants/PROC_ID_DEFAULT)
        calendars (.queryCalendars collection http-client (create-query))
        ]
    (doseq [cal calendars
            event (-> cal (.getComponents) (.getComponents Component/VEVENT))]
      (println "Event: " event)
      (println "\n\n"))))

Clojure core.logic cheatsheets

I am currently having a look at clojure core.logic and was missing some kind of reference documentation. There are a lot of examples and tutorials but I never had an overview about what’s available.

In a google groups discussion the idea of a reference documentation like clojure cheat sheets came up. https://groups.google.com/forum/#!topic/clojure/ScJa_o4lP2k

So I decided to create one, view it directly: cheatsheet on github

Have a look at the github project: https://github.com/dedeibel/clojure-core-logic-cheatsheets

Thanks to the original author of the cheatsheet generator Michael Fogus and Andy Fingerhut.

Thanks goes to xavriley who created a cool version of clojuredocs for core.logic which is where the cheatsheet entries link to.

Created a shortcut cheat sheet for the clojure foreplay vim plugin

In Meikel Brandmeyer’s post „On the state of VimClojure“ he mentioned the alternative „foreplay“ to his vimclojure repl solution which is using ng-server.

I tried the plugin and liked it. It has a more robust feel and very easy setup – none required to be precise. You can simply start your nrepl using lein repl and the plugin automagically talks to it.

There are quite some useful shortcuts you should know, therefore I created a foreplay-cheat-sheet (PDF) which might be helpful at the beginning.

Maybe the more often required commands should be on top, but I guess you’ll learn those quite fast anyway.

I created it manually from the foreplay vim documentation, so the content is actually from Tim Pope. The office document is available here foreplay-cheat-sheet.odt

hth

Clojure store persistent data structures gotcha – load-file size limit

In clojure – the data structure and their default representation are suited as readable and portable format to persist data. But there is a small pitfall in using it.

Data Structure example:

{
  :request-time 2636,
  :status 200,
  :headers
  {
    "server" "Server",
    "content-encoding" "gzip",
  }
}

Be aware that this function is intended to load code only. If your data structures or a string in them grow bigger than around 65,535 it crashes.

Exception similar to:

java.lang.ClassFormatError: Unknown constant tag 49 in class file parse$eval13

Please use read-string instead.

Example: (read-string (slurp "data.clj"))

Source: Rich Hickey on google groups Google Groups

Clojure Game Of Life App on Heroku

A while ago I created a heroku account to try it out. They allow you to host clojure web apps in the cloud. One worker is for free and there are also quite more languages supported.

In order to practice some clojure I implemented game of life and packaged it into a lib. Here does leiningen help you a lot, it is the maven of the clojure world and also creates maven compatible jar files.

My app was originally printing out the game of life world to the CLI but now outputs it as text/plain.

I won’t repeat the steps to setup heroku since they are explained very well on heroku: http://devcenter.heroku.com/articles/clojure

The result can be accessed here: http://gentle-journey-9851.herokuapp.com/

The state is globally shared through all requests. So don’t be surprised if there are some generations missing.

The code and library is available on github. The game of life source code is included in the jar, in case some is interested. I might have a different post about this later.

https://github.com/dedeibel/herokus_game_of_clojure_life

To start the app:

Prerequisites: leiningen

To run locally, simple run

$ lein run -m herokutest.web 5000

or

$ foreman start

And visit http://localhost:5000

(ns herokutest.web
  (:use [game_of_life.cell :only (new_cell)])
  (:use [game_of_life.world_printer :only (to_string)])
  (:use [game_of_life.world_builder :only (from_string)])
  (:use [game_of_life.game :only (next_generation)])
  (:use ring.adapter.jetty)
)

(def twentyfour_and_more
"xx
,xx
,
,
,
,                                   x x  xxx
,                                   x x    x
,                                   xxx  xxx
,                                     x  x
,                                     x  xxx
,                                                                                                   xx  
,                                                                                                  x  x
,                                                                                                 x    x
,                                                                                                x      x
,                                                                                                x      x
,                                                                                                 x    x
,                                                                                                  x  x
,                                                                                                   xx"
)

(def counter (atom 0))
(def world (atom (from_string twentyfour_and_more new_cell)))

(defn app [req]
  (let [current @world]
    (swap! counter inc)
    (swap! world next_generation)
    {:status 200
     :headers {"Content-Type" "text/plain"}
     :body 
       (str "Game Of Life (Step " @counter "):\n" (to_string current))
    }
  )
)

(defn -main [port]
  (run-jetty app {:port (Integer. port)}))

clojure lein gives error „Exception in thread „main“ java.lang.RuntimeException: java.lang.NoSuchMethodError: clojure.lang.KeywordLookupSite …“

For all of you searching for this problem when running lein (1.6) and clojure (1.3). You have to add the clojure directory to your classpath. Simple as that. :-\

$ lein help
Exception in thread "main" java.lang.RuntimeException: java.lang.NoSuchMethodError: clojure.lang.KeywordLookupSite.(ILclojure/lang/Keyword;)V
at clojure.lang.Util.runtimeException(Util.java:165)
at clojure.lang.Compiler.eval(Compiler.java:6476)
at clojure.lang.Compiler.eval(Compiler.java:6431)
at clojure.core$eval.invoke(core.clj:2795)
at clojure.main$eval_opt.invoke(main.clj:296)
at clojure.main$initialize.invoke(main.clj:315)
at clojure.main$script_opt.invoke(main.clj:339)
at clojure.main$main.doInvoke(main.clj:426)
at clojure.lang.RestFn.invoke(RestFn.java:457)
at clojure.lang.Var.invoke(Var.java:413)
at clojure.lang.AFn.applyToHelper(AFn.java:172)
at clojure.lang.Var.applyTo(Var.java:518)
at clojure.main.main(main.java:37)
Caused by: java.lang.NoSuchMethodError: clojure.lang.KeywordLookupSite.(ILclojure/lang/Keyword;)V
at leiningen.util.paths$native_arch_path.(paths.clj:32)
at leiningen.util.paths__init.load(Unknown Source)
at leiningen.util.paths__init.(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at clojure.lang.RT.loadClassForName(RT.java:2030)
at clojure.lang.RT.load(RT.java:417)
at clojure.lang.RT.load(RT.java:398)
at clojure.core$load$fn__4610.invoke(core.clj:5386)
at clojure.core$load.doInvoke(core.clj:5385)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5200)
at clojure.core$load_lib.doInvoke(core.clj:5237)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:602)
at clojure.core$load_libs.doInvoke(core.clj:5271)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:602)
at clojure.core$require.doInvoke(core.clj:5352)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at leiningen.core$loading__4414__auto__.invoke(core.clj:1)
at leiningen.core__init.load(Unknown Source)
at leiningen.core__init.(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at clojure.lang.RT.loadClassForName(RT.java:2030)
at clojure.lang.RT.load(RT.java:417)
at clojure.lang.RT.load(RT.java:398)
at clojure.core$load$fn__4610.invoke(core.clj:5386)
at clojure.core$load.doInvoke(core.clj:5385)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5200)
at clojure.core$load_lib.doInvoke(core.clj:5237)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:602)
at clojure.core$load_libs.doInvoke(core.clj:5271)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:604)
at clojure.core$use.doInvoke(core.clj:5363)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at user$eval1.invoke(NO_SOURCE_FILE:1)
at clojure.lang.Compiler.eval(Compiler.java:6465)
... 11 more

Setting the paths:


echo "export CLOJURE_HOME=$HOME/Opt/clojure
export CLASSPATH=$CLASSPATH:$CLOJURE_HOME" >> $HOME/.profile

lein works, tadaaa:

$ lein help
Leiningen is a tool for working with Clojure projects.

Several tasks are available:
classpath Print the classpath of the current project.

Clojure example from „The Joy Of Clojure“ parallelized

I am currently reading „The Joy Of Clojure“ by Michael Fogus and Chris Houser – a great book to see the „why“ behind the clojure way. You should have had a look into clojure before and be willing to read a lot of docs besides the book.

In the book there is a simple example program to display a nice graphic, created by applying xor to the pixel coordinates and using them as grayscale color value. The chapter is „Using the REPL to experiment“.
While reading this part, I thought it would be nice to have that algorithm for parallel processing and experimented a little bit.

The following listing is the result, it modified the original and uses simple threading and the „locking“ macro. It is also interesting to see what happens if you leave out the synchronizing between setting the color and drawing the pixel, as you can see in the screenshots. I hope the original author is okay with using his examples.

Simply paste it to your REPL and try it out.

(defn
  ^{:doc "Calculate the color for a coordinate x and y by applying the given
function. Offset and max values can be specified as input." }
  f-valueso [f xoffset xmax yoffset ymax]
  (for [x (range xoffset xmax) y (range yoffset ymax)
          :let [v (rem (f x y) 256)]]
    [x y (if (< v 0) (* -1 v) v)]
  )
)

(defn
  ^{:doc "Devides the given value in 'parts' equal parts. For
example 200 2 will become [[0 100] [100 200]]"}
  from-to-parts [value parts]
  (loop [
    steps (conj (vec (range 0 value (int (/ value parts)))) value)
    result []
    ]
    (if (seq (rest steps))
      (recur (rest steps) (conj result [(first steps) (second steps)]))
      result
    )
  )
)

; Initialize the frame
(def frame (java.awt.Frame.))
(.setVisible frame true)
(.setSize frame (java.awt.Dimension. 256 256))
(.setLocation frame 300 300)
; Graphics size is only as big as the frame was at getGraphics times
; (that had cost me some time ...)
(def gfx (.getGraphics frame))

(defn clear
  ([g] (.clearRect g 0 0 256 256))
  ([g x y] (.clearRect g 0 0 x y))
)

(defn
  ^{:doc "Draw the picture in a specified area using the color function."}
  draw-part [gfx f xoffset xmax yoffset ymax]
  (doseq [[x y v] (f-valueso f xoffset xmax yoffset ymax)]
;    (Thread/sleep 1) Uncomment this if it draws too fast
    (locking gfx
      (.setColor gfx (java.awt.Color. v v v))
      (.fillRect gfx x y 1 1)
    )
  )
)

(defn
    ^{:doc "Draw a picture to 'gfx' that is created by using the
given color function. Use 'n' threads to create the picture from
0 to x/y max"}
  draw-valuesp [f xmax ymax n]
  (clear gfx)
  (.setSize frame (java.awt.Dimension. xmax ymax))
  (def gfx (.getGraphics frame))
  (clear gfx xmax ymax)
  (doseq [
    [xoffset xmax] (from-to-parts xmax n)
    [yoffset ymax] (from-to-parts ymax n)
  ]
    (.start (Thread. 
      #(draw-part gfx f xoffset xmax yoffset ymax)
    ))
  )
)

(draw-valuesp bit-xor 256 256 3)

The result:

Multithreaded version during processing:

Result without synchronization:

I am aware that there is not much concurrency in the problem and it is not the greatest example to show the power of clojure’s capabilities. But that wasn’t the point of it.