1 4 package gnu.kawa.servlet; 5 6 import gnu.expr.*; 7 import gnu.mapping.*; 8 import gnu.text.*; 9 import java.io.*; 10 import java.net.*; 11 import java.util.*; 12 import javax.servlet.*; 13 import javax.servlet.http.*; 14 15 27 public class KawaPageServlet extends KawaServlet 28 { 29 private ServletContext context; 30 31 public void init(ServletConfig config) 32 throws ServletException 33 { 34 super.init(config); 35 context = config.getServletContext(); 36 } 37 38 public void run(CallContext ccontext) throws Throwable 39 { 40 ServletCallContext ctx = (ServletCallContext) ccontext; 41 HttpServletRequest request = ctx.request; 42 HttpServletResponse response = ctx.response; 43 44 boolean saveClass = request.getParameter("qexo-save-class") != null; 45 String path = request.getServletPath(); 46 Object mod = getModule(ctx, path, saveClass, response); 47 48 if (mod instanceof ModuleBody) 49 ((ModuleBody) mod).run(ctx); 50 } 51 52 private static final String MODULE_MAP_ATTRIBUTE = "gnu.kawa.module-map"; 53 54 private Object getModule(ServletCallContext ctx, String path, boolean saveClass, HttpServletResponse response) 55 throws Exception 56 { 57 Hashtable mmap 58 = (Hashtable) context.getAttribute(MODULE_MAP_ATTRIBUTE); 59 if (mmap == null) 60 { 61 mmap = new Hashtable(); 62 context.setAttribute(MODULE_MAP_ATTRIBUTE, mmap); 63 } 64 ModuleContext mcontext 65 = (ModuleContext) context.getAttribute("gnu.kawa.module-context"); 66 if (mcontext == null) 67 mcontext = ModuleContext.getContext(); 68 ModuleInfo minfo = (ModuleInfo) mmap.get(path); 69 long now = System.currentTimeMillis(); 70 ModuleManager mmanager = mcontext.getManager(); 71 72 if (minfo != null 74 && now - minfo.lastCheckedTime < mmanager.lastModifiedCacheTime) 75 return mcontext.findInstance(minfo); 76 77 URL url = context.getResource(path); 78 String upath = path; 79 if (url == null) 80 { 81 String xpath = path; 82 for (;;) 83 { 84 int sl = xpath.lastIndexOf('/'); 85 if (sl < 0) 86 { 87 ctx.response.reset(); 88 ctx.response.sendError(HttpServletResponse.SC_NOT_FOUND, path); 89 return null; 90 } 91 xpath = xpath.substring(0, sl); 92 upath = xpath + "/+default+"; 93 url = context.getResource(upath); 94 if (url != null) 95 break; 96 } 97 } 98 99 if (url == null) 100 { 101 ctx.response.reset(); 102 ctx.response.sendError(HttpServletResponse.SC_NOT_FOUND, path); 103 return null; 104 } 105 106 URLConnection connection = url.openConnection(); 107 String urlString = url.toExternalForm(); 108 long lastModified = connection.getLastModified(); 109 if (minfo != null 110 && minfo.lastModifiedTime == lastModified 111 && urlString.equals(minfo.sourceAbsPath)) 112 { 113 minfo.lastCheckedTime = now; 114 return mcontext.findInstance(minfo); 115 } 116 117 minfo = mmanager.findWithURL(url); 118 minfo.lastModifiedTime = lastModified; 119 minfo.lastCheckedTime = now; 120 mmap.put(path, minfo); 121 122 InputStream resourceStream = connection.getInputStream(); 123 124 Language language 125 = Language.getInstanceFromFilenameExtension(path); 126 if (language == null) 127 language = Language.detect(resourceStream); 128 if (language == null) 129 { 130 if (path != upath) 131 { 132 ctx.response.reset(); 133 ctx.response.sendError(HttpServletResponse.SC_NOT_FOUND, path); 134 return null; 135 } 136 String contentType = context.getMimeType(path); 137 response.setContentType(contentType); 138 ServletOutputStream out = response.getOutputStream(); 139 byte[] buffer = new byte[4*1024]; 140 for (;;) 141 { 142 int n = resourceStream.read(buffer); 143 if (n < 0) 144 break; 145 out.write(buffer, 0, n); 146 } 147 resourceStream.close(); 148 return null; 149 } 150 InPort port = new InPort(resourceStream, 151 path.substring(path.lastIndexOf('/')+1)); 152 Language.setDefaultLanguage(language); 153 SourceMessages messages = new SourceMessages(); 154 Compilation comp; 155 try 156 { 157 comp = language.parse(port, messages, Language.PARSE_IMMEDIATE); 158 int dot = path.indexOf('.'); 159 if (dot < 0) 160 dot = path.length(); 161 String name = path.substring(path.lastIndexOf('/')+1, dot); 162 comp.getModule().setName(name); 163 language.resolve(comp); 164 } 165 catch (SyntaxException ex) 166 { 167 if (ex.getMessages() != messages) 168 throw ex; 169 comp = null; } 172 173 Class cl = null; 174 if (! messages.seenErrors()) 175 { 176 ModuleExp mexp = comp.getModule(); 177 comp.addMainClass(mexp); 178 comp.walkModule(mexp); 179 comp.setState(Compilation.WALKED); 180 cl = ModuleExp.evalToClass(comp, url); 181 } 182 183 if (messages.seenErrors()) 189 { 190 ctx.response.reset(); 191 ServletOutputStream out = ctx.response.getOutputStream(); 192 out.print(messages.toString(20)); 193 return null; 194 } 195 196 minfo.moduleClass = cl; 197 minfo.className = cl.getName(); 198 199 if (saveClass) 200 comp.outputClass(context.getRealPath("WEB-INF/classes")+'/'); 201 202 return mcontext.findInstance(minfo); 203 } 204 } 205 206 | Popular Tags |