transport
46 | (response-seq response-timeout)
47 | tracking-seq)]
48 | (reset! latest-head [0 head])
49 | head)]
50 | ^{::transport transport ::timeout response-timeout}
51 | (fn this
52 | ([] (or (second @latest-head)
53 | (restart)))
54 | ([msg]
55 | (transport/send transport msg)
56 | (this)))))
57 |
58 | (defn- take-until
59 | "Like (take-while (complement f) coll), but includes the first item in coll that
60 | returns true for f."
61 | [f coll]
62 | (let [[head tail] (split-with (complement f) coll)]
63 | (concat head (take 1 tail))))
64 |
65 | (defn- delimited-transport-seq
66 | "Returns a function of one arument that performs described below.
67 | The following \"message\" is the argument of the function returned by this function.
68 |
69 | - Merge delimited-slots to the message
70 | - Sends a message via client
71 | - Filter only items related to the delimited-slots of client's response seq
72 | - Returns head of the seq that will terminate
73 | upon receipt of a :status, when :status is an element of termination-statuses"
74 | [client termination-statuses delimited-slots]
75 | (with-meta
76 | (comp (partial take-until (comp #(seq (clojure.set/intersection % termination-statuses))
77 | set
78 | :status))
79 | (let [keys (keys delimited-slots)]
80 | (partial filter #(= delimited-slots (select-keys % keys))))
81 | client
82 | #(merge % delimited-slots))
83 | (-> (meta client)
84 | (update-in [::termination-statuses] (fnil into #{}) termination-statuses)
85 | (update-in [::taking-until] merge delimited-slots))))
86 |
87 | (defn message
88 | "Sends a message via [client] with a fixed message :id added to it
89 | by `delimited-transport-seq`.
90 | Returns the head of the client's response seq, filtered to include only
91 | messages related to the message :id that will terminate upon receipt of a
92 | \"done\" :status."
93 | [client {:keys [id] :as msg :or {id (uuid)}}]
94 | (let [f (delimited-transport-seq client #{"done" :done} {:id id})]
95 | (f msg)))
96 |
97 | (defn new-session
98 | "Provokes the creation and retention of a new session, optionally as a clone
99 | of an existing retained session, the id of which must be provided as a :clone
100 | kwarg. Returns the new session's id."
101 | [client & {:keys [clone]}]
102 | (let [resp (first (message client (merge {:op "clone"} (when clone {:session clone}))))]
103 | (or (:new-session resp)
104 | (throw (InvalidOperationException. ;;; IllegalStateException.
105 | (str "Could not open new session; :clone response: " resp))))))
106 |
107 | (defn client-session
108 | "Returns a function of one argument. Accepts a message that is sent via the
109 | client provided with a fixed :session id added to it. Returns the
110 | head of the client's response seq, filtered to include only
111 | messages related to the :session id that will terminate when the session is
112 | closed."
113 | [client & {:keys [session clone]}]
114 | (let [session (or session (apply new-session client (when clone [:clone clone])))]
115 | (delimited-transport-seq client #{"session-closed"} {:session session})))
116 |
117 | (defn combine-responses
118 | "Combines the provided seq of response messages into a single response map.
119 |
120 | Certain message slots are combined in special ways:
121 |
122 | - only the last :ns is retained
123 | - :value is accumulated into an ordered collection
124 | - :status and :session are accumulated into a set
125 | - string values (associated with e.g. :out and :err) are concatenated"
126 | [responses]
127 | (reduce
128 | (fn [m [k v]]
129 | (case k
130 | (:id :ns) (assoc m k v)
131 | :value (update-in m [k] (fnil conj []) v)
132 | :status (update-in m [k] (fnil into #{}) v)
133 | :session (update-in m [k] (fnil conj #{}) v)
134 | (if (string? v)
135 | (update-in m [k] #(str % v))
136 | (assoc m k v))))
137 | {} (apply concat responses)))
138 |
139 | (defn code*
140 | "Returns a single string containing the pr-str'd representations
141 | of the given expressions."
142 | [& expressions]
143 | (apply str (map pr-str expressions)))
144 |
145 | (defmacro code
146 | "Expands into a string consisting of the macro's body's forms
147 | (literally, no interpolation/quasiquoting of locals or other
148 | references), suitable for use in an `\"eval\"` message, e.g.:
149 |
150 | {:op \"eval\", :code (code (+ 1 1) (slurp \"foo.txt\"))}"
151 | [& body]
152 | (apply code* body))
153 |
154 | (defn read-response-value
155 | "Returns the provided response message, replacing its :value string with
156 | the result of (read)ing it. Returns the message unchanged if the :value
157 | slot is empty or not a string."
158 | [{:keys [value] :as msg}]
159 | (if-not (string? value)
160 | msg
161 | (try
162 | (assoc msg :value (read-string value))
163 | (catch Exception e
164 | (throw (InvalidOperationException. (str "Could not read response value: " value) e)))))) ;DM: IllegalStateException
165 |
166 | (defn response-values
167 | "Given a seq of responses (as from response-seq or returned from any function returned
168 | by client or client-session), returns a seq of values read from :value slots found
169 | therein."
170 | [responses]
171 | (->> responses
172 | (map read-response-value)
173 | combine-responses
174 | :value))
175 |
176 | (defn- tls-connect
177 | [{:keys [port host transport-fn tls-keys-str tls-keys-file]}]
178 | (throw (NotImplementedException. "TLS connections not yet implemented. "))) ;;; (let [tls-context (tls/ssl-context-or-throw tls-keys-str tls-keys-file)]
179 | ;;; (transport-fn (tls/socket tls-context ^String host (int port) 10000)))
180 |
181 | (defn connect
182 | "Connects to a socket-based REPL at the given host (defaults to 127.0.0.1) and port,
183 | or using the supplied socket, returning the Transport (by default `nrepl.transport/bencode`)
184 | for that connection.
185 |
186 | Transports are most easily used with `client`, `client-session`, and
187 | `message`, depending on the semantics desired."
188 | [& {:keys [port host socket transport-fn tls-keys-str tls-keys-file]
189 | :or {transport-fn transport/bencode
190 | host "127.0.0.1"}
191 | :as opts}]
192 | {:pre [transport-fn]}
193 | (cond
194 | socket
195 | (throw (NotImplementedException. "unix sockets not yet implemented")) ;;; (transport-fn (socket/unix-client-socket socket))
196 |
197 | (or tls-keys-str tls-keys-file)
198 | (throw (NotImplementedException. "TLS connections not yet implemented")) ;;; (tls-connect (assoc opts :transport-fn transport-fn :host host))
199 |
200 | (and host port)
201 | (transport-fn (.Client (System.Net.Sockets.TcpClient. ^String host (int port)))) ;;; (transport-fn (java.net.Socket. ^String host (int port)))
202 |
203 | :else
204 | (throw (ArgumentException. "A host plus port or a socket must be supplied to connect.")))) ;;; IllegalArgumentException.
205 |
206 | (defn- ^System.Uri to-uri ;;; ^java.net.URI
207 | [x]
208 | {:post [(instance? System.Uri %)]} ;;; java.net.URI
209 | (if (string? x)
210 | (System.Uri. x) ;;; java.net.URI
211 | x))
212 |
213 | (defn- socket-info
214 | [x]
215 | (let [uri (to-uri x)
216 | port (.Port uri)] ;;; .getPort
217 | (merge {:host (.Host uri)} ;;; .getHost
218 | (when (pos? port)
219 | {:port port}))))
220 |
221 | (def ^{:private false} uri-scheme #(-> (to-uri %) .Scheme .ToLower)) ;;; .getScheme .toLowerCase
222 |
223 | (defmulti url-connect
224 | "Connects to an nREPL endpoint identified by the given URL/URI. Valid
225 | examples include:
226 |
227 | nrepl://192.168.0.12:7889
228 | telnet://localhost:5000
229 | http://your-app-name.heroku.com/repl
230 |
231 | This is a multimethod that dispatches on the scheme of the URI provided
232 | (which can be a string or java.net.URI). By default, implementations for
233 | nrepl (corresponding to using the default bencode transport) and
234 | telnet (using the `nrepl.transport/tty` transport) are
235 | registered. Alternative implementations may add support for other schemes,
236 | such as HTTP, HTTPS, JMX, existing message queues, etc."
237 | uri-scheme)
238 |
239 | ;; TODO: oh so ugly
240 | (defn- add-socket-connect-method!
241 | [protocol connect-defaults]
242 | (defmethod url-connect protocol
243 | [uri]
244 | (apply connect (mapcat identity
245 | (merge connect-defaults
246 | (socket-info uri))))))
247 |
248 | (add-socket-connect-method! "nrepl+edn" {:transport-fn transport/edn
249 | :port 7888})
250 | (add-socket-connect-method! "nrepl" {:transport-fn transport/bencode
251 | :port 7888})
252 | (add-socket-connect-method! "telnet" {:transport-fn transport/tty})
253 |
254 | (defmethod url-connect :default
255 | [uri]
256 | (throw (ArgumentException. ;;; IllegalArgumentException.
257 | (format "No nREPL support known for scheme %s, url %s" (uri-scheme uri) uri))))
258 |
259 | (def ^{:deprecated "0.5.0"} version
260 | "Use `nrepl.version/version` instead.
261 | Current version of nREPL.
262 | Map of :major, :minor, :incremental, :qualifier, and :version-string."
263 | version/version)
264 |
265 | (def ^{:deprecated "0.5.0"} version-string
266 | "Use `(:version-string nrepl.version/version)` instead.
267 | Current version of nREPL as a string.
268 | See also `version`."
269 | (:version-string version/version))
--------------------------------------------------------------------------------
/partial-nrepl-nrepl-port/src/main/clojure/cnrepl/middleware/interruptible_eval.clj:
--------------------------------------------------------------------------------
1 | (ns cnrepl.middleware.interruptible-eval
2 | "Supports the ability to evaluation code. The name of the middleware is
3 | slightly misleading, as interrupt is currently supported at a session level
4 | but the name is retained for backwards compatibility."
5 | {:author "Chas Emerick"}
6 | (:require
7 | clojure.main
8 | clojure.test
9 | [cnrepl.middleware :refer [set-descriptor!]] [cnrepl.debug :as debug]
10 | [cnrepl.middleware.caught :as caught]
11 | [cnrepl.middleware.print :as print]
12 | [cnrepl.misc :as misc :refer [response-for ]] ;;; with-session-classloader -- removed
13 | [cnrepl.transport :as t])
14 | (:import
15 | (clojure.lang Compiler+CompilerException LineNumberingTextReader) ;;;Compiler$CompilerException LineNumberingPushbackReader
16 | (System.IO StringReader TextWriter) ;;;(java.io FilterReader LineNumberReader StringReader Writer)
17 | (System.Threading ThreadInterruptedException))) ;;; (java.lang.reflect Field)
18 |
19 | (def ^:dynamic *msg*
20 | "The message currently being evaluated."
21 | nil)
22 |
23 | (defn- capture-thread-bindings
24 | "Capture thread bindings, excluding nrepl implementation vars."
25 | []
26 | (dissoc (get-thread-bindings) #'*msg*))
27 |
28 | (defn- set-line!
29 | [^LineNumberingTextReader reader line] ;;; ^LineNumberingPushbackReader
30 | (-> reader (.set_LineNumber line))) ;;; .setLineNumber
31 |
32 | (defn- set-column! ;;; It would be easier to make the column number settable. Why not, if rown
33 | [^LineNumberingTextReader reader column] ;;; ^LineNumberingPushbackReader
34 | (when-let [field (.GetField LineNumberingTextReader "_columnNumber" ;;; (->> LineNumberingPushbackReader
35 | (enum-or System.Reflection.BindingFlags/NonPublic ;;; (.getDeclaredFields)
36 | System.Reflection.BindingFlags/Instance))] ;;; (filter #(= "_columnNumber" (.getName ^Field %)))
37 | ;;; first)
38 | (.SetValue field reader column) ;;; (-> ^Field field
39 | ;;; (doto (.setAccessible true))
40 | )) ;;; (.set reader column))
41 |
42 | (defn- source-logging-pushback-reader
43 | [code line column]
44 | (let [reader (LineNumberingTextReader. (StringReader. code))] ;;; LineNumberingPushbackReader.
45 | (when line (set-line! reader (int line)))
46 | (when column (set-column! reader (int column)))
47 | reader))
48 |
49 | (defn- interrupted?
50 | "Returns true if the given throwable was ultimately caused by an interrupt."
51 | [^Exception e] ;;; ^Throwable SHOULD THESE BE ThreadAbortException? Only in 461?
52 | (or (instance? ThreadInterruptedException (clojure.main/root-cause e)) ;;; ThreadDeath
53 | (and (instance? Compiler+CompilerException e) ;;; Compiler$CompilerException
54 | (instance? ThreadInterruptedException (.InnerException e))))) ;;; ThreadDeath .getCause
55 |
56 | (defn evaluate
57 | "Evaluates a msg's code within the dynamic context of its session.
58 |
59 | Uses `clojure.main/repl` to drive the evaluation of :code (either a string
60 | or a seq of forms to be evaluated), which may also optionally specify a :ns
61 | (resolved via `find-ns`). The map MUST contain a Transport implementation
62 | in :transport; expression results and errors will be sent via that Transport.
63 |
64 | Note: we are doubling up on restoring of ctxcl in a `catch` block both here
65 | and within `misc/with-session-classloader`. Not too sure why this is needed,
66 | but it does seem to be a fix for https://github.com/nrepl/nrepl/issues/206"
67 | [{:keys [transport session eval ns code file line column out-limit]
68 | :as msg}]
69 | #_(debug/prn-thread "ie/evaluate: " code)
70 | (let [explicit-ns (and ns (-> ns symbol find-ns))
71 | original-ns (@session #'*ns*)
72 | maybe-restore-original-ns (if explicit-ns
73 | #(assoc % #'*ns* original-ns)
74 | identity)]
75 | (if (and ns (not explicit-ns))
76 | (t/send transport (response-for msg {:status #{:error :namespace-not-found :done}
77 | :ns ns}))
78 | (let [ ;;; no such thing for CLR: ctxcl (.getContextClassLoader (Thread/currentThread))
79 | ;; TODO: out-limit -> out-buffer-size | err-buffer-size
80 | ;; TODO: new options: out-quota | err-quota
81 | opts {::print/buffer-size (or out-limit (get (meta session) :out-limit))}
82 | out (print/replying-PrintWriter :out msg opts)
83 | err (print/replying-PrintWriter :err msg opts)]
84 | (try
85 | (clojure.main/repl
86 | :eval (let [eval-fn (if eval (find-var (symbol eval)) clojure.core/eval)]
87 | (fn [form]
88 | (eval-fn form))) ;;; (with-session-classloader session (eval-fn form))
89 | :init #(let [bindings
90 | (-> (get-thread-bindings)
91 | (into caught/default-bindings)
92 | (into print/default-bindings)
93 | (into @session)
94 | (into {#'*out* out
95 | #'*err* err
96 | ;; clojure.test captures *out* at load-time, so we need to make sure
97 | ;; runtime output of test status/results is redirected properly
98 | ;; TODO: is this something we need to consider in general, or is this
99 | ;; specific hack reasonable?
100 | #'clojure.test/*test-out* out})
101 | (cond-> explicit-ns (assoc #'*ns* explicit-ns)
102 | file (assoc #'*file* file)))]
103 | (pop-thread-bindings)
104 | (push-thread-bindings bindings))
105 | :read (if (string? code)
106 | (let [reader (source-logging-pushback-reader code line column)
107 | read-cond (or (-> msg :read-cond keyword)
108 | :allow)]
109 | #(try (read {:read-cond read-cond :eof %2} reader)
110 | (catch Exception e ;;; RuntimeException
111 | ;; If error happens during reading the string, we
112 | ;; don't want eval to start reading and executing the
113 | ;; rest of it. So we skip over the remaining text.
114 | (.ReadToEnd ^LineNumberingTextReader reader) ;;; (.skip ^LineNumberingPushbackReader reader Long/MAX_VALUE)
115 | (throw e))))
116 | (let [code (.GetEnumerator ^System.Collections.IEnumerable code)] ;;; .iterator ^Iterable
117 | #(or (and (.MoveNext code) (.Current code) ) %2))) ;;; (.hasNext code) (.next code)
118 | :prompt #(reset! session (maybe-restore-original-ns (capture-thread-bindings)))
119 | :need-prompt (constantly true)
120 | :print (fn [value]
121 | ;; *out* has :tag metadata; *err* does not
122 | (.Flush ^TextWriter *err*) ;;; .flush ^Writer
123 | (.Flush ^TextWriter *out*) ;;; .flush -- added type hint TODO -- not clear this is always true, based on a comment I made elsewhere
124 | (t/send transport (response-for msg {:ns (str (ns-name *ns*))
125 | :value value
126 | ::print/keys #{:value}})))
127 | :caught (fn [^Exception e] ;;; Throwable
128 | (when-not (interrupted? e)
129 | (let [resp {::caught/throwable e
130 | :status :eval-error
131 | :ex (str (class e))
132 | :root-ex (str (class (clojure.main/root-cause e)))}]
133 | (t/send transport (response-for msg resp))))))
134 | (finally
135 | ;;; (when (misc/java-8?)
136 | ;;; (.setContextClassLoader (Thread/currentThread) ctxcl))
137 | (.Flush ^TextWriter err) ;;; .flush -- added type hint
138 | (.Flush ^TextWriter out))))))) ;;; .flush -- added type hint
139 |
140 | (defn interruptible-eval
141 | "Evaluation middleware that supports interrupts. Returns a handler that supports
142 | \"eval\" and \"interrupt\" :op-erations that delegates to the given handler
143 | otherwise."
144 | [h & configuration]
145 | (fn [{:keys [op session id transport] :as msg}]
146 | (let [{:keys [exec] session-id :id} (meta session)]
147 | (case op
148 | "eval"
149 | (if-not (:code msg)
150 | (t/send transport (response-for msg :status #{:error :no-code :done}))
151 | (exec id
152 | #(binding [*msg* msg]
153 | (evaluate msg))
154 | #(t/send transport (response-for msg :status :done))))
155 | (h msg)))))
156 |
157 | (set-descriptor! #'interruptible-eval
158 | {:requires #{"clone" "close" #'caught/wrap-caught #'print/wrap-print}
159 | :expects #{}
160 | :handles {"eval"
161 | {:doc "Evaluates code. Note that unlike regular stream-based Clojure REPLs, nREPL's `\"eval\"` short-circuits on first read error and will not try to read and execute the remaining code in the message."
162 | :requires {"code" "The code to be evaluated."
163 | "session" "The ID of the session within which to evaluate the code."}
164 | :optional (merge caught/wrap-caught-optional-arguments
165 | print/wrap-print-optional-arguments
166 | {"id" "An opaque message ID that will be included in responses related to the evaluation, and which may be used to restrict the scope of a later \"interrupt\" operation."
167 | "eval" "A fully-qualified symbol naming a var whose function value will be used to evaluate [code], instead of `clojure.core/eval` (the default)."
168 | "ns" "The namespace in which to perform the evaluation. The supplied namespace must exist already (e.g. be loaded). If no namespace is specified the evaluation falls back to `*ns*` for the session in question."
169 | "file" "The path to the file containing [code]. `clojure.core/*file*` will be bound to this."
170 | "line" "The line number in [file] at which [code] starts."
171 | "column" "The column number in [file] at which [code] starts."
172 | "read-cond" "The options passed to the reader before the evaluation. Useful when middleware in a higher layer wants to process reader conditionals."})
173 | :returns {"ns" "*ns*, after successful evaluation of `code`."
174 | "value" "The result of evaluating `code`, often `read`able. This printing is provided by the `print` middleware. Superseded by `ex` and `root-ex` if an exception occurs during evaluation."
175 | "ex" "The type of exception thrown, if any. If present, then `:value` will be absent."
176 | "root-ex" "The type of the root exception thrown, if any. If present, then `:value` will be absent."}}}})
--------------------------------------------------------------------------------
/epl.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Eclipse Public License - Version 1.0
8 |
25 |
26 |
27 |
28 |
29 |
30 | Eclipse Public License - v 1.0
31 |
32 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
33 | PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR
34 | DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS
35 | AGREEMENT.
36 |
37 | 1. DEFINITIONS
38 |
39 | "Contribution" means:
40 |
41 | a) in the case of the initial Contributor, the initial
42 | code and documentation distributed under this Agreement, and
43 | b) in the case of each subsequent Contributor:
44 | i) changes to the Program, and
45 | ii) additions to the Program;
46 | where such changes and/or additions to the Program
47 | originate from and are distributed by that particular Contributor. A
48 | Contribution 'originates' from a Contributor if it was added to the
49 | Program by such Contributor itself or anyone acting on such
50 | Contributor's behalf. Contributions do not include additions to the
51 | Program which: (i) are separate modules of software distributed in
52 | conjunction with the Program under their own license agreement, and (ii)
53 | are not derivative works of the Program.
54 |
55 | "Contributor" means any person or entity that distributes
56 | the Program.
57 |
58 | "Licensed Patents" mean patent claims licensable by a
59 | Contributor which are necessarily infringed by the use or sale of its
60 | Contribution alone or when combined with the Program.
61 |
62 | "Program" means the Contributions distributed in accordance
63 | with this Agreement.
64 |
65 | "Recipient" means anyone who receives the Program under
66 | this Agreement, including all Contributors.
67 |
68 | 2. GRANT OF RIGHTS
69 |
70 | a) Subject to the terms of this Agreement, each
71 | Contributor hereby grants Recipient a non-exclusive, worldwide,
72 | royalty-free copyright license to reproduce, prepare derivative works
73 | of, publicly display, publicly perform, distribute and sublicense the
74 | Contribution of such Contributor, if any, and such derivative works, in
75 | source code and object code form.
76 |
77 | b) Subject to the terms of this Agreement, each
78 | Contributor hereby grants Recipient a non-exclusive, worldwide,
79 | royalty-free patent license under Licensed Patents to make, use, sell,
80 | offer to sell, import and otherwise transfer the Contribution of such
81 | Contributor, if any, in source code and object code form. This patent
82 | license shall apply to the combination of the Contribution and the
83 | Program if, at the time the Contribution is added by the Contributor,
84 | such addition of the Contribution causes such combination to be covered
85 | by the Licensed Patents. The patent license shall not apply to any other
86 | combinations which include the Contribution. No hardware per se is
87 | licensed hereunder.
88 |
89 | c) Recipient understands that although each Contributor
90 | grants the licenses to its Contributions set forth herein, no assurances
91 | are provided by any Contributor that the Program does not infringe the
92 | patent or other intellectual property rights of any other entity. Each
93 | Contributor disclaims any liability to Recipient for claims brought by
94 | any other entity based on infringement of intellectual property rights
95 | or otherwise. As a condition to exercising the rights and licenses
96 | granted hereunder, each Recipient hereby assumes sole responsibility to
97 | secure any other intellectual property rights needed, if any. For
98 | example, if a third party patent license is required to allow Recipient
99 | to distribute the Program, it is Recipient's responsibility to acquire
100 | that license before distributing the Program.
101 |
102 | d) Each Contributor represents that to its knowledge it
103 | has sufficient copyright rights in its Contribution, if any, to grant
104 | the copyright license set forth in this Agreement.
105 |
106 | 3. REQUIREMENTS
107 |
108 | A Contributor may choose to distribute the Program in object code
109 | form under its own license agreement, provided that:
110 |
111 | a) it complies with the terms and conditions of this
112 | Agreement; and
113 |
114 | b) its license agreement:
115 |
116 | i) effectively disclaims on behalf of all Contributors
117 | all warranties and conditions, express and implied, including warranties
118 | or conditions of title and non-infringement, and implied warranties or
119 | conditions of merchantability and fitness for a particular purpose;
120 |
121 | ii) effectively excludes on behalf of all Contributors
122 | all liability for damages, including direct, indirect, special,
123 | incidental and consequential damages, such as lost profits;
124 |
125 | iii) states that any provisions which differ from this
126 | Agreement are offered by that Contributor alone and not by any other
127 | party; and
128 |
129 | iv) states that source code for the Program is available
130 | from such Contributor, and informs licensees how to obtain it in a
131 | reasonable manner on or through a medium customarily used for software
132 | exchange.
133 |
134 | When the Program is made available in source code form:
135 |
136 | a) it must be made available under this Agreement; and
137 |
138 | b) a copy of this Agreement must be included with each
139 | copy of the Program.
140 |
141 | Contributors may not remove or alter any copyright notices contained
142 | within the Program.
143 |
144 | Each Contributor must identify itself as the originator of its
145 | Contribution, if any, in a manner that reasonably allows subsequent
146 | Recipients to identify the originator of the Contribution.
147 |
148 | 4. COMMERCIAL DISTRIBUTION
149 |
150 | Commercial distributors of software may accept certain
151 | responsibilities with respect to end users, business partners and the
152 | like. While this license is intended to facilitate the commercial use of
153 | the Program, the Contributor who includes the Program in a commercial
154 | product offering should do so in a manner which does not create
155 | potential liability for other Contributors. Therefore, if a Contributor
156 | includes the Program in a commercial product offering, such Contributor
157 | ("Commercial Contributor") hereby agrees to defend and
158 | indemnify every other Contributor ("Indemnified Contributor")
159 | against any losses, damages and costs (collectively "Losses")
160 | arising from claims, lawsuits and other legal actions brought by a third
161 | party against the Indemnified Contributor to the extent caused by the
162 | acts or omissions of such Commercial Contributor in connection with its
163 | distribution of the Program in a commercial product offering. The
164 | obligations in this section do not apply to any claims or Losses
165 | relating to any actual or alleged intellectual property infringement. In
166 | order to qualify, an Indemnified Contributor must: a) promptly notify
167 | the Commercial Contributor in writing of such claim, and b) allow the
168 | Commercial Contributor to control, and cooperate with the Commercial
169 | Contributor in, the defense and any related settlement negotiations. The
170 | Indemnified Contributor may participate in any such claim at its own
171 | expense.
172 |
173 | For example, a Contributor might include the Program in a commercial
174 | product offering, Product X. That Contributor is then a Commercial
175 | Contributor. If that Commercial Contributor then makes performance
176 | claims, or offers warranties related to Product X, those performance
177 | claims and warranties are such Commercial Contributor's responsibility
178 | alone. Under this section, the Commercial Contributor would have to
179 | defend claims against the other Contributors related to those
180 | performance claims and warranties, and if a court requires any other
181 | Contributor to pay any damages as a result, the Commercial Contributor
182 | must pay those damages.
183 |
184 | 5. NO WARRANTY
185 |
186 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
187 | PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
188 | OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,
189 | ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
190 | OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
191 | responsible for determining the appropriateness of using and
192 | distributing the Program and assumes all risks associated with its
193 | exercise of rights under this Agreement , including but not limited to
194 | the risks and costs of program errors, compliance with applicable laws,
195 | damage to or loss of data, programs or equipment, and unavailability or
196 | interruption of operations.
197 |
198 | 6. DISCLAIMER OF LIABILITY
199 |
200 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
201 | NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
202 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
203 | WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
204 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
205 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
206 | DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
207 | HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
208 |
209 | 7. GENERAL
210 |
211 | If any provision of this Agreement is invalid or unenforceable under
212 | applicable law, it shall not affect the validity or enforceability of
213 | the remainder of the terms of this Agreement, and without further action
214 | by the parties hereto, such provision shall be reformed to the minimum
215 | extent necessary to make such provision valid and enforceable.
216 |
217 | If Recipient institutes patent litigation against any entity
218 | (including a cross-claim or counterclaim in a lawsuit) alleging that the
219 | Program itself (excluding combinations of the Program with other
220 | software or hardware) infringes such Recipient's patent(s), then such
221 | Recipient's rights granted under Section 2(b) shall terminate as of the
222 | date such litigation is filed.
223 |
224 | All Recipient's rights under this Agreement shall terminate if it
225 | fails to comply with any of the material terms or conditions of this
226 | Agreement and does not cure such failure in a reasonable period of time
227 | after becoming aware of such noncompliance. If all Recipient's rights
228 | under this Agreement terminate, Recipient agrees to cease use and
229 | distribution of the Program as soon as reasonably practicable. However,
230 | Recipient's obligations under this Agreement and any licenses granted by
231 | Recipient relating to the Program shall continue and survive.
232 |
233 | Everyone is permitted to copy and distribute copies of this
234 | Agreement, but in order to avoid inconsistency the Agreement is
235 | copyrighted and may only be modified in the following manner. The
236 | Agreement Steward reserves the right to publish new versions (including
237 | revisions) of this Agreement from time to time. No one other than the
238 | Agreement Steward has the right to modify this Agreement. The Eclipse
239 | Foundation is the initial Agreement Steward. The Eclipse Foundation may
240 | assign the responsibility to serve as the Agreement Steward to a
241 | suitable separate entity. Each new version of the Agreement will be
242 | given a distinguishing version number. The Program (including
243 | Contributions) may always be distributed subject to the version of the
244 | Agreement under which it was received. In addition, after a new version
245 | of the Agreement is published, Contributor may elect to distribute the
246 | Program (including its Contributions) under the new version. Except as
247 | expressly stated in Sections 2(a) and 2(b) above, Recipient receives no
248 | rights or licenses to the intellectual property of any Contributor under
249 | this Agreement, whether expressly, by implication, estoppel or
250 | otherwise. All rights in the Program not expressly granted under this
251 | Agreement are reserved.
252 |
253 | This Agreement is governed by the laws of the State of New York and
254 | the intellectual property laws of the United States of America. No party
255 | to this Agreement will bring a legal action under this Agreement more
256 | than one year after the cause of action arose. Each party waives its
257 | rights to a jury trial in any resulting litigation.
258 |
259 |
260 |
261 |
--------------------------------------------------------------------------------