| | 175 | |
|---|
| | 176 | /+ |
|---|
| | 177 | /* |
|---|
| | 178 | <p> |
|---|
| | 179 | all-in-one implementation |
|---|
| | 180 | </p><p> |
|---|
| | 181 | The tradeoff for one dll per application is a smaller total runtime footprint at the cost of |
|---|
| | 182 | more ram up-front and the inability to cache or unload pieces of the application. There may |
|---|
| | 183 | be situations where this mode is preferred, as it side-steps the limitations imposed by |
|---|
| | 184 | wielding so many libs at once. |
|---|
| | 185 | </p><p> |
|---|
| | 186 | Developers may find that all-in-one works best for deployment only, and that it may be too |
|---|
| | 187 | slow to recompile changes within even modestly sized applications. |
|---|
| | 188 | </p> |
|---|
| | 189 | |
|---|
| | 190 | TODO: needs compiler/generator support to work |
|---|
| | 191 | TODO: may best rely on 'build' to get the job done |
|---|
| | 192 | */ |
|---|
| | 193 | class DSPAllInOneServlet : Servlet{ |
|---|
| | 194 | Library lib; |
|---|
| | 195 | ServletHandle handle; |
|---|
| | 196 | |
|---|
| | 197 | private static Logger logger; |
|---|
| | 198 | |
|---|
| | 199 | static this (){ |
|---|
| | 200 | logger = Logger.getLogger ("dsp.servlets"); |
|---|
| | 201 | } |
|---|
| | 202 | |
|---|
| | 203 | public this(){ |
|---|
| | 204 | } |
|---|
| | 205 | |
|---|
| | 206 | public ~this(){ |
|---|
| | 207 | if(lib && lib.isLoaded) lib.unload(); |
|---|
| | 208 | } |
|---|
| | 209 | |
|---|
| | 210 | Library getLibrary(DSPServletContext context,FilePath path){ |
|---|
| | 211 | //TODO: make concurrent |
|---|
| | 212 | //TODO: add check for file existence |
|---|
| | 213 | //TODO: add check for library date and its validity vs the source file |
|---|
| | 214 | if(!lib){ |
|---|
| | 215 | RequestConfig cfg; |
|---|
| | 216 | |
|---|
| | 217 | // configuration |
|---|
| | 218 | |
|---|
| | 219 | cfg.pwd = context.getBasePath() ~ "\\"; |
|---|
| | 220 | cfg.pwd = cfg.pwd.replace("/","\\"); |
|---|
| | 221 | cfg.ext = path.getExtension(); |
|---|
| | 222 | |
|---|
| | 223 | //HACK: filepath leaves prefixed '/' character on |
|---|
| | 224 | cfg.name = path.getName()[1..$]; |
|---|
| | 225 | |
|---|
| | 226 | cfg.modulePath = path.getPath(); |
|---|
| | 227 | cfg.requestModule = cfg.modulePath ~ cfg.name; |
|---|
| | 228 | cfg.dspSourceFilename = cfg.pwd ~ cfg.name ~ "." ~ cfg.ext; |
|---|
| | 229 | |
|---|
| | 230 | cfg.tempDirectory = cfg.pwd ~ context.getConfiguration.get("temp-directory"); |
|---|
| | 231 | cfg.cacheDirectory = cfg.pwd ~ context.getConfiguration.get("cache-directory"); |
|---|
| | 232 | |
|---|
| | 233 | cfg.dSourceFilename = cfg.tempDirectory ~ cfg.name ~ ".d"; |
|---|
| | 234 | cfg.destServletFilename = cfg.cacheDirectory ~ cfg.name ~ ".dll"; |
|---|
| | 235 | |
|---|
| | 236 | cfg.runtimeDirectory = context.getConfiguration.get("runtime-directory"); |
|---|
| | 237 | |
|---|
| | 238 | // debug |
|---|
| | 239 | printf("%.*s\n",cfg.toString()); |
|---|
| | 240 | |
|---|
| | 241 | // build the servlet library |
|---|
| | 242 | ServletCompiler compiler = new ServletCompiler(); |
|---|
| | 243 | compiler.CompileServlet(cfg); |
|---|
| | 244 | |
|---|
| | 245 | // keep the library for later |
|---|
| | 246 | lib = new Library(cfg.destServletFilename); |
|---|
| | 247 | libs[path.toString()] = lib; |
|---|
| | 248 | } |
|---|
| | 249 | return lib; |
|---|
| | 250 | } |
|---|
| | 251 | |
|---|
| | 252 | void service (IServletRequest request, IServletResponse response){ |
|---|
| | 253 | FilePath path = new FilePath(request.getPathInfo); |
|---|
| | 254 | |
|---|
| | 255 | if(path.getExtension == "dsp"){ |
|---|
| | 256 | IDSPRequest dspRequest = cast(IDSPRequest)request; |
|---|
| | 257 | IDSPResponse dspResponse = cast(IDSPResponse)response; |
|---|
| | 258 | DSPServletContext context = cast(DSPServletContext)request.getContext(); |
|---|
| | 259 | |
|---|
| | 260 | assert(dspRequest); |
|---|
| | 261 | assert(dspResponse); |
|---|
| | 262 | assert(context); |
|---|
| | 263 | |
|---|
| | 264 | // bind to the needed dll on the fly |
|---|
| | 265 | |
|---|
| | 266 | Library lib = getLibrary(context,path); |
|---|
| | 267 | if(lib){ |
|---|
| | 268 | ServiceHandle handle = cast(ServiceHandle)lib.getSymbol("service"); |
|---|
| | 269 | |
|---|
| | 270 | // run the service handle |
|---|
| | 271 | if(handle){ |
|---|
| | 272 | handle(dspRequest,dspResponse); |
|---|
| | 273 | } |
|---|
| | 274 | else{ |
|---|
| | 275 | throw new DSPException("servlet library does not have a valid service handle"); |
|---|
| | 276 | } |
|---|
| | 277 | |
|---|
| | 278 | dspResponse.getWriter.put("<h2>This is a test for DSP servlets</h2>"); |
|---|
| | 279 | |
|---|
| | 280 | if(dspResponse.isExceptionSet){ |
|---|
| | 281 | throw new DSPException("servlet: " ~ dspResponse.getException()); |
|---|
| | 282 | } |
|---|
| | 283 | } |
|---|
| | 284 | else{ |
|---|
| | 285 | throw new DSPException("could not load library"); |
|---|
| | 286 | } |
|---|
| | 287 | } |
|---|
| | 288 | else{ |
|---|
| | 289 | //TODO: use configuration and handling rules |
|---|
| | 290 | //TODO: provide a directory listing if the file doesn't exist |
|---|
| | 291 | logger.info ("request for file: " ~ request.getUri.getPath ~ " (" ~ request.getPathInfo ~ ")"); |
|---|
| | 292 | response.copyFile (request.getContext, request.getPathInfo); |
|---|
| | 293 | } |
|---|
| | 294 | } |
|---|
| | 295 | |
|---|
| | 296 | void init (ServletConfig config) |
|---|
| | 297 | { |
|---|
| | 298 | //TODO: is this needed? |
|---|
| | 299 | } |
|---|
| | 300 | } |
|---|
| | 301 | +/ |
|---|