webmcp

annotate framework/bin/mcp.lua @ 219:db106eb273ea

Simplified autoloader in mcp.lua
author jbe
date Sun Feb 22 13:42:48 2015 +0100 (2015-02-22)
parents 15c9de7832cc
children e69251d4ba0e
rev   line source
jbe@203 1 #!/usr/bin/env moonbridge
jbe/bsw@0 2
jbe@203 3 WEBMCP_VERSION = "2.0.0_devel"
jbe@64 4
jbe@203 5 -- check if interactive mode
jbe@203 6 if listen then -- defined by moonbridge
jbe@203 7 WEBMCP_MODE = "listen"
jbe@203 8 else
jbe@203 9 WEBMCP_MODE = "interactive"
jbe@64 10 end
jbe@203 11
jbe@206 12 -- configuration names are provided as 4th, 5th, etc. argument
jbe@206 13 WEBMCP_CONFIG_NAMES = {select(4, ...)}
jbe@203 14
jbe@203 15 -- determine framework and bath path from command line arguments
jbe@203 16 -- or print usage synopsis (if applicable)
jbe@68 17 do
jbe@206 18 local arg1, arg2, arg3 = ...
jbe@203 19 local helpout
jbe@203 20 if
jbe@203 21 arg1 == "-h" or arg1 == "--help" or
jbe@206 22 arg2 == "-h" or arg2 == "--help" -- if first arg is provided by wrapper
jbe@203 23 then
jbe@203 24 helpout = io.stdout
jbe@203 25 elseif
jbe@217 26 #WEBMCP_CONFIG_NAMES < 1 or
jbe@206 27 (WEBMCP_MODE == "interactive") ~= (arg3 == "INTERACTIVE")
jbe@203 28 then
jbe@203 29 helpout = io.stderr
jbe@203 30 end
jbe@203 31 if helpout then
jbe@217 32 helpout:write("Usage: moonbridge -- <framework path>/bin/mcp.lua <framework path> <app base path> <app name> <config name> [<config name> ...]\n")
jbe@217 33 helpout:write(" or: lua -i <framework path>/bin/mcp.lua <framework path> <app base path> INTERACTIVE <config name> [<config name> ...]\n")
jbe@203 34 if helpout == io.stderr then
jbe@203 35 return 1
jbe@68 36 else
jbe@203 37 return 0
jbe@68 38 end
jbe@68 39 end
jbe@203 40 local function append_trailing_slash(str)
jbe@217 41 return string.gsub(str, "([^/])$", function(last) return last .. "/" end)
jbe@203 42 end
jbe@203 43 WEBMCP_FRAMEWORK_PATH = append_trailing_slash(arg1)
jbe@203 44 WEBMCP_BASE_PATH = append_trailing_slash(arg2)
jbe@206 45 if WEBMCP_MODE == "listen" then
jbe@206 46 WEBMCP_APP_NAME = arg3
jbe@206 47 end
jbe@68 48 end
jbe@1 49
jbe@203 50 -- setup search paths for libraries
jbe/bsw@0 51 do
jbe@217 52 if string.match(package.path, "^[^;]") then
jbe@217 53 package.path = ";" .. package.path
jbe@217 54 end
jbe@217 55 package.path = WEBMCP_FRAMEWORK_PATH .. "lib/?.lua" .. package.path
jbe/bsw@0 56 -- find out which file name extension shared libraries have
jbe/bsw@0 57 local slib_exts = {}
jbe/bsw@0 58 for ext in string.gmatch(package.cpath, "%?%.([A-Za-z0-9_-]+)") do
jbe@217 59 if not slib_exts[ext] then
jbe@217 60 slib_exts[#slib_exts+1] = ext
jbe@217 61 slib_exts[ext] = true
jbe@217 62 end
jbe/bsw@0 63 end
jbe/bsw@0 64 local paths = {}
jbe@217 65 for i, ext in ipairs(slib_exts) do
jbe@203 66 paths[#paths+1] = WEBMCP_FRAMEWORK_PATH .. "accelerator/?." .. ext
jbe/bsw@0 67 end
jbe@217 68 for i, ext in ipairs(slib_exts) do
jbe@203 69 paths[#paths+1] = WEBMCP_FRAMEWORK_PATH .. "lib/?." .. ext
jbe/bsw@0 70 end
jbe/bsw@0 71 paths[#paths+1] = package.cpath
jbe/bsw@0 72 package.cpath = table.concat(paths, ";")
jbe/bsw@0 73 end
jbe/bsw@0 74
jbe@203 75 -- autoloader system for WebMCP environment "$WEBMCP_FRAMEWORK_PATH/env/",
jbe@203 76 -- application environment extensions "$WEBMCP_BASE_PATH/env/"
jbe@203 77 -- and models "$WEBMCP_BASE_PATH/model/"
jbe/bsw@0 78 do
jbe/bsw@0 79 local weakkey_mt = { __mode = "k" }
jbe/bsw@0 80 local autoloader_category = setmetatable({}, weakkey_mt)
jbe/bsw@0 81 local autoloader_path = setmetatable({}, weakkey_mt)
jbe/bsw@0 82 local autoloader_mt = {}
jbe@219 83 local function install_autoloader(self, category, path_fragment)
jbe/bsw@0 84 autoloader_category[self] = category
jbe@219 85 autoloader_path[self] = path_fragment
jbe/bsw@0 86 setmetatable(self, autoloader_mt)
jbe/bsw@0 87 end
jbe/bsw@0 88 local function try_exec(filename)
jbe/bsw@0 89 local file = io.open(filename, "r")
jbe/bsw@0 90 if file then
jbe/bsw@0 91 local filedata = file:read("*a")
jbe/bsw@0 92 io.close(file)
jbe@68 93 local func, errmsg = load(filedata, "=" .. filename)
jbe/bsw@0 94 if func then
jbe/bsw@0 95 func()
jbe/bsw@0 96 return true
jbe/bsw@0 97 else
jbe/bsw@0 98 error(errmsg, 0)
jbe/bsw@0 99 end
jbe/bsw@0 100 else
jbe/bsw@0 101 return false
jbe/bsw@0 102 end
jbe/bsw@0 103 end
jbe/bsw@0 104 function autoloader_mt.__index(self, key)
jbe/bsw@0 105 local category, base_path, merge_base_path, file_key
jbe/bsw@0 106 local merge = false
jbe/bsw@0 107 if
jbe/bsw@0 108 string.find(key, "^[a-z_][A-Za-z0-9_]*$") and
jbe/bsw@0 109 not string.find(key, "^__")
jbe/bsw@0 110 then
jbe/bsw@0 111 category = "env"
jbe@203 112 base_path = WEBMCP_FRAMEWORK_PATH .. "env/"
jbe/bsw@0 113 merge = true
jbe@203 114 merge_base_path = WEBMCP_BASE_PATH .. "env/"
jbe/bsw@0 115 file_key = key
jbe/bsw@0 116 elseif string.find(key, "^[A-Z][A-Za-z0-9]*$") then
jbe/bsw@0 117 category = "model"
jbe@203 118 base_path = WEBMCP_BASE_PATH .. "model/"
jbe/bsw@0 119 local first = true
jbe/bsw@0 120 file_key = string.gsub(key, "[A-Z]",
jbe/bsw@0 121 function(c)
jbe/bsw@0 122 if first then
jbe/bsw@0 123 first = false
jbe/bsw@0 124 return string.lower(c)
jbe/bsw@0 125 else
jbe/bsw@0 126 return "_" .. string.lower(c)
jbe/bsw@0 127 end
jbe/bsw@0 128 end
jbe/bsw@0 129 )
jbe/bsw@0 130 else
jbe/bsw@0 131 return
jbe/bsw@0 132 end
jbe/bsw@0 133 local required_category = autoloader_category[self]
jbe/bsw@0 134 if required_category and required_category ~= category then return end
jbe@219 135 local path_fragment = autoloader_path[self]
jbe@219 136 local path = base_path .. path_fragment .. file_key
jbe@219 137 local merge_path
jbe/bsw@0 138 if merge then
jbe@219 139 merge_path = merge_base_path .. path_fragment .. file_key
jbe/bsw@0 140 end
jbe/bsw@0 141 local function try_dir(dirname)
jbe/bsw@0 142 local dir = io.open(dirname)
jbe/bsw@0 143 if dir then
jbe/bsw@0 144 io.close(dir)
jbe/bsw@0 145 local obj = {}
jbe@219 146 install_autoloader(obj, category, path_fragment .. file_key .. "/")
jbe/bsw@0 147 rawset(self, key, obj)
jbe@219 148 try_exec(path .. "/__init.lua")
jbe@219 149 if merge then try_exec(merge_path .. "/__init.lua") end
jbe/bsw@0 150 return true
jbe/bsw@0 151 else
jbe/bsw@0 152 return false
jbe/bsw@0 153 end
jbe/bsw@0 154 end
jbe@219 155 if merge and try_exec(merge_path .. ".lua") then
jbe@219 156 elseif merge and try_dir(merge_path .. "/") then
jbe@219 157 elseif try_exec(path .. ".lua") then
jbe@219 158 elseif try_dir(path .. "/") then
jbe/bsw@0 159 else end
jbe/bsw@0 160 return rawget(self, key)
jbe/bsw@0 161 end
jbe@219 162 install_autoloader(_G, nil, "")
jbe@203 163 try_exec(WEBMCP_FRAMEWORK_PATH .. "env/__init.lua")
jbe@203 164 try_exec(WEBMCP_BASE_PATH .. "env/__init.lua")
jbe/bsw@0 165 end
jbe/bsw@0 166
jbe@214 167 -- replace Moonbridge listen function
jbe@214 168 local moonbridge_listen = listen
jbe@214 169 local listeners
jbe@214 170 function listen(args)
jbe@214 171 listeners[#listeners+1] = args
jbe@214 172 end
jbe@214 173
jbe@203 174 -- prohibit (unintended) definition of new global variables
jbe@203 175 _ENV = setmetatable({}, {
jbe@203 176 __index = _G,
jbe@203 177 __newindex = function()
jbe@203 178 error("Setting of global variable prohibited")
jbe@203 179 end
jbe@203 180 })
jbe@203 181
jbe@214 182 -- execute configurations
jbe@206 183 for i, config_name in ipairs(WEBMCP_CONFIG_NAMES) do
jbe@206 184 execute.config(config_name)
jbe@215 185 execute.prefork_initializers()
jbe@206 186 end
jbe@206 187
jbe/bsw@0 188 -- interactive console mode
jbe@203 189 if WEBMCP_MODE == "interactive" then
jbe@215 190 execute.postfork_initializers()
jbe@203 191 trace.disable() -- avoids memory leakage (TODO: needs general solution for moonbridge?)
jbe/bsw@0 192 end
jbe/bsw@0 193
jbe@204 194 -- invoke moonbridge
jbe@206 195 if WEBMCP_MODE == "listen" then
jbe@207 196 local http = require("moonbridge_http")
jbe@211 197 for i, listener in ipairs(listeners) do
jbe@215 198 listener.prepare = execute.postfork_initializers
jbe@211 199 listener.connect = http.generate_handler(
jbe@215 200 request.handler,
jbe@215 201 request.get_http_options()
jbe@211 202 )
jbe@211 203 listener.finish = execute.finalizers
jbe@211 204 moonbridge_listen(listener)
jbe@204 205 end
jbe@204 206 end
jbe@204 207

Impressum / About Us