Skip to content
Browse files

Making web/start support a subset of ring-server's opts [IMMUTANT-241]

Breaking change is that :reload option is renamed :auto-reload?, but
that was pretty broken anyway since it hard-coded the :reload-paths
option to the project's "src" dir. We now add all directories on the
CP, by default.

Also, we detect "development mode" either by LEIN_NO_DEV being unset
(you might set it prior to starting Immutant) or the presence of :dev
as an active profile in the deployed project. Both :auto-reload? and
:stacktraces? default to true in development mode, false otherwise.
  • Loading branch information...
1 parent a5eaf14 commit 58ae4ae722e742aa231f4b8eac8bffa3f3c4d070 @jcrossley3 jcrossley3 committed Mar 11, 2013
View
6 modules/web/pom.xml
@@ -44,6 +44,12 @@
</dependency>
<dependency>
+ <groupId>org.tcrawley</groupId>
+ <artifactId>dynapath</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
<groupId>ring</groupId>
<artifactId>ring-servlet</artifactId>
<version>${version.ring}</version>
View
87 modules/web/src/main/clojure/immutant/web.clj
@@ -18,13 +18,12 @@
(ns immutant.web
"Associate one or more Ring handlers with your application, mounted
at unique context paths"
- (:require [immutant.registry :as registry]
- [clojure.tools.logging :as log]
+ (:require [clojure.tools.logging :as log]
[immutant.util :as util]
- [ring.middleware.reload :as ring]
- [ring.util.codec :as codec]
- [ring.util.response :as response])
+ [ring.util.codec :as codec]
+ [ring.util.response :as response])
(:use [immutant.web.internal :exclude [current-servlet-request]])
+ (:use [immutant.web.middleware :only [add-middleware]])
(:import javax.servlet.http.HttpServletRequest))
(declare stop)
@@ -36,50 +35,46 @@
[]
immutant.web.internal/current-servlet-request)
-(def
- ^{:arglists '([handler & {:keys [reload init destroy]}]
- [sub-context-path handler & {:keys [reload init destroy]}])
- :doc "Registers a Ring handler that will be called when requests
+(defn start
+ "Registers a Ring handler that will be called when requests
are received on the given sub-context-path. If no sub-context-path
is given, \"/\" is assumed.
- The following options are supported [default]:
- :reload monitors the app's src/ dir for changes [false]
- :init a function called after handler is initialized [nil]
- :destroy a function called after handler is stopped [nil]"}
- start
- (fn [& args]
- (util/if-in-immutant
- (let [[sub-context-path args] (if (string? (first args))
- [(first args) (next args)]
- ["/" args])
- [handler & {:keys [reload init destroy]}] args
- handler (if reload
- (ring/wrap-reload
- handler
- {:dirs [(util/app-relative "src")]})
- handler)
- sub-context-path (normalize-subcontext-path sub-context-path)
- servlet-name (servlet-name sub-context-path)]
- (if-let [existing-info (get-servlet-info servlet-name)]
- (do
- (log/info "Updating ring handler at sub-context path:" sub-context-path)
- (store-servlet-info!
- servlet-name
- (assoc existing-info :handler handler)))
- (do
- (log/info "Registering ring handler at sub-context path:" sub-context-path)
- (store-servlet-info!
- servlet-name
- {:wrapper (install-servlet "org.immutant.web.servlet.RingServlet"
- sub-context-path)
- :sub-context sub-context-path
- :handler handler
- :destroy destroy})
- (util/at-exit #(stop sub-context-path))
- (and init (init))))
- nil)
- (log/warn "web/start called outside of Immutant, ignoring"))))
+ The options are a subset of those for ring-server [default]:
+ :init function called after handler is initialized [nil]
+ :destroy function called after handler is stopped [nil]
+ :stacktraces? display stacktraces when exception is thrown [true in :dev]
+ :auto-reload? automatically reload source files [true in :dev]
+ :reload-paths seq of src-paths to reload on change [dirs on classpath]"
+ {:arglists '([handler] [handler options] [path handler options])}
+ [& args]
+ (util/if-in-immutant
+ (let [[sub-context-path args] (if (string? (first args))
+ [(first args) (next args)]
+ ["/" args])
+ [handler & {:keys [init destroy] :as opts}] args
+ handler (add-middleware handler opts)
+ sub-context-path (normalize-subcontext-path sub-context-path)
+ servlet-name (servlet-name sub-context-path)]
+ (if-let [existing-info (get-servlet-info servlet-name)]
+ (do
+ (log/debug "Updating ring handler at sub-context path:" sub-context-path)
+ (store-servlet-info!
+ servlet-name
+ (assoc existing-info :handler handler)))
+ (do
+ (log/info "Registering ring handler at sub-context path:" sub-context-path)
+ (store-servlet-info!
+ servlet-name
+ {:wrapper (install-servlet "org.immutant.web.servlet.RingServlet"
+ sub-context-path)
+ :sub-context sub-context-path
+ :handler handler
+ :destroy destroy})
+ (util/at-exit #(stop sub-context-path))
+ (and init (init))))
+ nil)
+ (log/warn "web/start called outside of Immutant, ignoring")))
(defn stop
View
62 modules/web/src/main/clojure/immutant/web/middleware.clj
@@ -0,0 +1,62 @@
+;; Copyright 2008-2013 Red Hat, Inc, and individual contributors.
+;;
+;; This is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU Lesser General Public License as
+;; published by the Free Software Foundation; either version 2.1 of
+;; the License, or (at your option) any later version.
+;;
+;; This software is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; Lesser General Public License for more details.
+;;
+;; You should have received a copy of the GNU Lesser General Public
+;; License along with this software; if not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+(ns ^{:no-doc true} immutant.web.middleware
+ (:use ring.middleware.stacktrace
+ ring.middleware.reload)
+ (:require [immutant.registry :as registry]
+ [clojure.java.io :as io]
+ dynapath.util))
+
+(def ^{:dynamic true} *dev*)
+
+(defn auto-reload?
+ "Automatically reload source files?"
+ [options]
+ (:auto-reload? options *dev*))
+
+(defn stacktraces?
+ "Show stacktraces?"
+ [options]
+ (:stacktraces? options *dev*))
+
+(defn reload-paths
+ "Default reload-paths to all directories in the classpath, whether
+ they exist at time of deployment or not"
+ [options]
+ (let [cp (map io/file (dynapath.util/all-classpath-urls))
+ dirs (map str (remove #(and (.exists %) (not (.isDirectory %))) cp))]
+ (:reload-paths options dirs)))
+
+(defn add-stacktraces [handler options]
+ (if (stacktraces? options)
+ (wrap-stacktrace handler)
+ handler))
+
+(defn add-auto-reload [handler options]
+ (if (auto-reload? options)
+ (wrap-reload handler {:dirs (reload-paths options)})
+ handler))
+
+(defn add-middleware
+ [handler options]
+ (let [project (registry/get :project)]
+ (binding [*dev* (not (or (System/getenv "LEIN_NO_DEV")
+ (->> project meta :active-profiles (not-any? #{:dev}))))]
+ (-> handler
+ (add-auto-reload options)
+ (add-stacktraces options)))))
View
1 modules/web/src/module/resources/module.xml
@@ -38,6 +38,7 @@
<resource-root path="ns-tracker.jar"/>
<resource-root path="tools.namespace.jar"/>
<resource-root path="java.classpath.jar"/>
+ <resource-root path="hiccup.jar"/>
</resources>
<dependencies>
View
6 namespaces/web/pom.xml
@@ -45,6 +45,12 @@
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.tcrawley</groupId>
+ <artifactId>dynapath</artifactId>
+ <version>${version.dynapath}</version>
+ </dependency>
+
</dependencies>
<build>

0 comments on commit 58ae4ae

Please sign in to comment.
Something went wrong with that request. Please try again.