| 1 | ;;+----------------------------------------------------------------------------- | 
|---|
| 2 | ;;+  Isidorus | 
|---|
| 3 | ;;+  (c) 2008-2010 Marc Kuester, Christoph Ludwig, Lukas Georgieff | 
|---|
| 4 | ;;+ | 
|---|
| 5 | ;;+  Isidorus is freely distributable under the LLGPL license. | 
|---|
| 6 | ;;+  You can find a detailed description in trunk/docs/LLGPL-LICENSE.txt and | 
|---|
| 7 | ;;+  trunk/docs/LGPL-LICENSE.txt. | 
|---|
| 8 | ;;+----------------------------------------------------------------------------- | 
|---|
| 9 |  | 
|---|
| 10 |  | 
|---|
| 11 | (defpackage :filter-functions | 
|---|
| 12 | (:use :base-tools :constants :tm-sparql) | 
|---|
| 13 | (:import-from :cl progn handler-case let condition)) | 
|---|
| 14 |  | 
|---|
| 15 |  | 
|---|
| 16 | (defun filter-functions::normalize-value (value) | 
|---|
| 17 | "Returns the normalized value, i.e. if a literal | 
|---|
| 18 | is passed as '12'^^xsd:integer 12 is returned." | 
|---|
| 19 | (cond ((not (stringp value)) | 
|---|
| 20 | value) | 
|---|
| 21 | ((or (base-tools:string-starts-with value "'") | 
|---|
| 22 | (base-tools:string-starts-with value "\"")) | 
|---|
| 23 | (let* ((literal-result (tm-sparql::get-literal value)) | 
|---|
| 24 | (literal-value | 
|---|
| 25 | (cond ((or (base-tools:string-starts-with | 
|---|
| 26 | (getf literal-result :literal) "\"\"\"") | 
|---|
| 27 | (base-tools:string-starts-with | 
|---|
| 28 | (getf literal-result :literal) "'''")) | 
|---|
| 29 | (subseq (getf literal-result :literal) 3 | 
|---|
| 30 | (- (length (getf literal-result :literal)) 3))) | 
|---|
| 31 | (t | 
|---|
| 32 | (subseq (getf literal-result :literal) 1 | 
|---|
| 33 | (- (length (getf literal-result :literal)) 1))))) | 
|---|
| 34 | (given-datatype | 
|---|
| 35 | (when (base-tools:string-starts-with | 
|---|
| 36 | (getf literal-result :next-string) "^^") | 
|---|
| 37 | (subseq (getf literal-result :next-string) 2)))) | 
|---|
| 38 | (tm-sparql::cast-literal literal-value given-datatype))) | 
|---|
| 39 | (t | 
|---|
| 40 | value))) | 
|---|
| 41 |  | 
|---|
| 42 |  | 
|---|
| 43 | (defun filter-functions::not(x) | 
|---|
| 44 | (not (filter-functions::normalize-value x))) | 
|---|
| 45 |  | 
|---|
| 46 |  | 
|---|
| 47 | (defun filter-functions::one+(x) | 
|---|
| 48 | (1+ (filter-functions::normalize-value x))) | 
|---|
| 49 |  | 
|---|
| 50 |  | 
|---|
| 51 | (defun filter-functions::one-(x) | 
|---|
| 52 | (1- (filter-functions::normalize-value x))) | 
|---|
| 53 |  | 
|---|
| 54 |  | 
|---|
| 55 | (defun filter-functions::+(x y) | 
|---|
| 56 | (+ (filter-functions::normalize-value x) | 
|---|
| 57 | (filter-functions::normalize-value y))) | 
|---|
| 58 |  | 
|---|
| 59 |  | 
|---|
| 60 | (defun filter-functions::-(x y) | 
|---|
| 61 | (- (filter-functions::normalize-value x) | 
|---|
| 62 | (filter-functions::normalize-value y))) | 
|---|
| 63 |  | 
|---|
| 64 |  | 
|---|
| 65 | (defun filter-functions::*(x y) | 
|---|
| 66 | (* (filter-functions::normalize-value x) | 
|---|
| 67 | (filter-functions::normalize-value y))) | 
|---|
| 68 |  | 
|---|
| 69 |  | 
|---|
| 70 | (defun filter-functions::/(x y) | 
|---|
| 71 | (/ (filter-functions::normalize-value x) | 
|---|
| 72 | (filter-functions::normalize-value y))) | 
|---|
| 73 |  | 
|---|
| 74 |  | 
|---|
| 75 | (defun filter-functions::or(x y) | 
|---|
| 76 | (or (filter-functions::normalize-value x) | 
|---|
| 77 | (filter-functions::normalize-value y))) | 
|---|
| 78 |  | 
|---|
| 79 |  | 
|---|
| 80 | (defun filter-functions::and(x y) | 
|---|
| 81 | (and (filter-functions::normalize-value x) | 
|---|
| 82 | (filter-functions::normalize-value y))) | 
|---|
| 83 |  | 
|---|
| 84 |  | 
|---|
| 85 | (defun filter-functions::=(x y) | 
|---|
| 86 | (let ((local-x (filter-functions::normalize-value x)) | 
|---|
| 87 | (local-y (filter-functions::normalize-value y))) | 
|---|
| 88 | (cond ((and (stringp local-x) (stringp local-y)) | 
|---|
| 89 | (string= local-x local-y)) | 
|---|
| 90 | ((and (numberp local-x)( numberp local-y)) | 
|---|
| 91 | (= local-x local-y)) | 
|---|
| 92 | (t | 
|---|
| 93 | (eql local-x local-y))))) | 
|---|
| 94 |  | 
|---|
| 95 |  | 
|---|
| 96 | (defun filter-functions::!=(x y) | 
|---|
| 97 | (filter-functions::not | 
|---|
| 98 | (filter-functions::= x y))) | 
|---|
| 99 |  | 
|---|
| 100 |  | 
|---|
| 101 | (defun filter-functions::<(x y) | 
|---|
| 102 | (let ((local-x (filter-functions::normalize-value x)) | 
|---|
| 103 | (local-y (filter-functions::normalize-value y))) | 
|---|
| 104 | (cond ((and (numberp local-x) (numberp local-y)) | 
|---|
| 105 | (< local-x local-y)) | 
|---|
| 106 | ((and (stringp local-x) (stringp local-y)) | 
|---|
| 107 | (string< local-x local-y)) | 
|---|
| 108 | ((and (typep local-x 'Boolean) (typep local-y 'Boolean)) | 
|---|
| 109 | (and (not local-x) local-y)) | 
|---|
| 110 | (t | 
|---|
| 111 | nil)))) | 
|---|
| 112 |  | 
|---|
| 113 |  | 
|---|
| 114 | (defun filter-functions::>(x y) | 
|---|
| 115 | (filter-functions::not | 
|---|
| 116 | (filter-functions::< x y))) | 
|---|
| 117 |  | 
|---|
| 118 |  | 
|---|
| 119 | (defun filter-functions::<=(x y) | 
|---|
| 120 | (filter-functions::or | 
|---|
| 121 | (filter-functions::< x y) | 
|---|
| 122 | (filter-functions::= x y))) | 
|---|
| 123 |  | 
|---|
| 124 |  | 
|---|
| 125 | (defun filter-functions::>=(x y) | 
|---|
| 126 | (filter-functions::or | 
|---|
| 127 | (filter-functions::> x y) | 
|---|
| 128 | (filter-functions::= x y))) | 
|---|
| 129 |  | 
|---|
| 130 |  | 
|---|
| 131 | (defun filter-functions::regex(str pattern &optional flags) | 
|---|
| 132 | (let* ((local-str (filter-functions::normalize-value str)) | 
|---|
| 133 | (local-flags (filter-functions::normalize-value flags)) | 
|---|
| 134 | (case-insensitive (when (find #\i local-flags) t)) | 
|---|
| 135 | (multi-line (when (find #\m local-flags) t)) | 
|---|
| 136 | (single-line (when (find #\s local-flags) t)) | 
|---|
| 137 | (local-pattern | 
|---|
| 138 | (if (find #\x local-flags) | 
|---|
| 139 | (base-tools:string-replace | 
|---|
| 140 | (base-tools:string-replace | 
|---|
| 141 | (base-tools:string-replace | 
|---|
| 142 | (base-tools:string-replace | 
|---|
| 143 | (filter-functions::normalize-value pattern) | 
|---|
| 144 | (string #\newline) "") | 
|---|
| 145 | (string #\tab) "") (string #\cr) "") " " "") | 
|---|
| 146 | (filter-functions::normalize-value pattern))) | 
|---|
| 147 | (scanner | 
|---|
| 148 | (ppcre:create-scanner local-pattern | 
|---|
| 149 | :case-insensitive-mode case-insensitive | 
|---|
| 150 | :multi-line-mode multi-line | 
|---|
| 151 | :single-line-mode single-line))) | 
|---|
| 152 | (when (ppcre:scan scanner local-str) | 
|---|
| 153 | t))) | 
|---|
| 154 |  | 
|---|
| 155 |  | 
|---|
| 156 | (defun filter-functions::write-to-symbol (name-string) | 
|---|
| 157 | (common-lisp:intern (common-lisp:string-upcase name-string))) | 
|---|
| 158 |  | 
|---|
| 159 |  | 
|---|
| 160 | (defun filter-functions::bound(x) | 
|---|
| 161 | (boundp (filter-functions::write-to-symbol x))) | 
|---|
| 162 |  | 
|---|
| 163 |  | 
|---|
| 164 | (defun filter-functions::isLITERAL(x) | 
|---|
| 165 | (or (numberp x) | 
|---|
| 166 | (not (and (base-tools:string-starts-with x "<") | 
|---|
| 167 | (base-tools:string-ends-with x ">") | 
|---|
| 168 | (base-tools:absolute-uri-p x))))) | 
|---|
| 169 |  | 
|---|
| 170 |  | 
|---|
| 171 | (defun filter-functions::datatype(x) | 
|---|
| 172 | (let ((type-suffix | 
|---|
| 173 | (when (and (stringp x) | 
|---|
| 174 | (or (base-tools:string-starts-with x "'") | 
|---|
| 175 | (base-tools:string-starts-with x "\""))) | 
|---|
| 176 | (let* ((result (base-tools:get-literal x)) | 
|---|
| 177 | (literal-datatype | 
|---|
| 178 | (when (base-tools:string-starts-with | 
|---|
| 179 | (getf result :next-string) "^^") | 
|---|
| 180 | (subseq (getf result :next-string) 2)))) | 
|---|
| 181 | literal-datatype)))) | 
|---|
| 182 | (cond (type-suffix type-suffix) | 
|---|
| 183 | ((integerp x) constants::*xml-integer*) | 
|---|
| 184 | ((floatp x) constants::*xml-decimal*) | 
|---|
| 185 | ((typep x 'double-float) constants::*xml-double*) | 
|---|
| 186 | ((stringp x) constants::*xml-string*) | 
|---|
| 187 | (t (type-of x))))) | 
|---|
| 188 |  | 
|---|
| 189 |  | 
|---|
| 190 | (defun filter-functions::str(x) | 
|---|
| 191 | (write-to-string x)) | 
|---|