Anonymous avatar Anonymous committed 7c101a2

First sketch for new web 'framework'.

Comments (0)

Files changed (2)

             classpath='${build.classes}:${src}'
             classpathref='clojure.compiler.classpath'>
             <sysproperty key='clojure.compile.path' value='${build.classes}'/>
+            <arg value='net.ksojat.neman.cli'/>
             <arg value='net.ksojat.neman.core'/>
+            <arg value='net.ksojat.neman.jetty'/>
+            <arg value='net.ksojat.neman.json'/>
+            <arg value='net.ksojat.neman.web'/>
+            <arg value='net.ksojat.neman.xml'/>
         </java>
 
         <jar destfile='${build.jar}'>

src/net/ksojat/neman/web.clj

+;; Copyright (c) 2008 Krešimir Šojat. All rights reserved.  The use and
+;; distribution terms for this software are covered by the Common
+;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php)
+;; which can be found in the file CPL.TXT at the root of this
+;; distribution.  By using this software in any fashion, you are
+;; agreeing to be bound by the terms of this license.  You must not
+;; remove this notice, or any other, from this software.
+
+(ns net.ksojat.neman.web
+  (:refer-clojure :exclude [partial])
+  (:import
+    (javax.servlet.http HttpServletRequest HttpServletResponse Cookie)
+    (org.mortbay.jetty HttpConnection Handler Request Response)
+    (org.mortbay.jetty.handler AbstractHandler))
+  (:use net.ksojat.neman.core))
+
+(defmacro defexception [name]
+  `(gen-class :name ~name :extends Exception))
+
+(defexception net.ksojat.neman.web.InvalidRule)
+(defexception net.ksojat.neman.web.UnknownConvertor)
+;(gen-class :name net.ksojat.neman.web.InvalidRule :extends Exception)
+;(gen-class :name net.ksojat.neman.web.UnknownConvertor :ectends Exception)
+
+;(import
+;  '(net.ksojat.neman.web InvalidRule UnknownConvertor))
+
+;;
+;; URL path convertors.
+;;
+
+(defmulti convertor (fn [name] name))
+
+(defmethod convertor :default [name]
+  (throw
+    (Exception. (str "Unknown convertor for type: " (prn name)))))
+
+(defmethod convertor :kw [_]
+  {:regex    "([^\\\\]+)"
+   :from-url keyword
+   :to-url   name})
+
+(defmethod convertor :path [_]
+  {:regex    "(.+)"
+   :from-url (fn [v] (seq (.split v "/")))
+   :to-url   (fn [v] (apply str (interpose "/" v)))})
+
+(defmethod convertor :int [_]
+  {:regex    "([0-9]+)"
+   :from-url #(Integer/parseInt %)
+   :to-url   #(Integer/toString %)})
+
+(defmethod convertor :str [_]
+  {:regex    "([^\\\\]+)"
+   :from-url (fn [v] v)
+   :to-url   (fn [v] v)})
+
+(defmethod convertor :uuid [_]
+  {:regex    "([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12})"
+   :from-url uuid
+   :to-url   str})
+
+(defn convertor-regex [type]
+  (when type
+    (:regex (convertor type))))
+
+(defn from-url [type value]
+  (when type
+    (((convertor type) :from-url) value)))
+
+(defn to-url [type value]
+  (when type
+    (((convertor type) :to-url) value)))
+
+;;
+;; Views.
+;;
+
+(defmacro view [bindings & body]
+  (let [expand   (fn
+                   ([s]     [s [s [:convertor :str]]])
+                   ([s c]   [s [s [:convertor c]]])
+                   ([d s c] [d [s [:convertor c]]]))
+        bindings (map #(apply expand (if (vector? %) % (list %))) bindings)
+        vargs (map (fn [[_ v]] v) bindings)
+        fargs (map (fn [[f _]] f) bindings)]
+    `(with-meta
+       {:args '~(vec vargs)
+        :view (fn ~(vec fargs) ~@body)}
+       {::view true})))
+
+(defn view? [x]
+  (true? (::view (meta x))))
+
+(defn argument-names [view]
+  (filter #(not= % nil)
+    (map (fn [[k [t _]]] (if (= t :value) nil k)) (view :args))))
+
+(defn argument-types [view]
+  (filter #(not= % nil)
+    (map (fn [[_ [t x]]] (if (= t :convertor) x)) (view :args))))
+
+(defn call-view [view arguments]
+  (apply (view :view)
+    (map
+      (fn [[k [type x]]]
+        (if (= type :value)
+          x
+          (if (contains? arguments k)
+            (from-url x (arguments k))
+            (throw (Exception. "xxxx")))))
+      (view :args))))
+
+(defmacro defview [name bindings & body]
+  `(def ~name (view ~bindings ~@body)))
+
+(defn partial [view new-args] ; TODO
+  (let [update (fn [args [new-k _ :as new-row]]
+                 (map
+                   (fn [[old-k [type _] :as old-row]]
+                     (if (= new-k old-k)
+                       (if (= type :value) (throw (Exception. "kkk")) new-row)
+                       old-row))
+                   args))]
+    (loop [new-args (map (fn [[k v]] [k [:value v]]) new-args)
+           old-args (view :args)]
+      (if (seq new-args)
+        (let [x (update old-args (first new-args))]
+          (if (= x old-args)
+            (throw (Exception. "beep"))
+            (recur (rest new-args) x)))
+        (assoc view :args (vec old-args))))))
+
+(defn status [status-kw]
+  (kw-enum HttpServletResponse "SC" status-kw))
+
+(defn urlmapper [view-fn]
+  (proxy [AbstractHandler] []
+    (handle [target #^HttpServletRequest request #^HttpServletResponse response dispatch]
+      (view-fn))))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.