Changeset 4221
- Timestamp:
- Apr 14, 2008, 2:40:57 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/config/dist/web.xml
r4187 r4221 167 167 <load-on-startup>1</load-on-startup> 168 168 </servlet> 169 169 <servlet-mapping> 170 <servlet-name>ExtensionsServlet</servlet-name> 171 <url-pattern>*.servlet</url-pattern> 172 </servlet-mapping> 173 170 174 <!-- The CompileAll servlet used to compile all JSP pages --> 171 175 <!-- EXPERIMENTAL!! --> -
trunk/doc/src/docbook/developerdoc/extensions.xml
r4208 r4221 709 709 </para> 710 710 711 <note> 712 <para> 713 Unfortunately, the custom JSP page can't use classes that 714 are located in the extension's JAR file. The reason is that the 715 JAR file is not known to Tomcat and Tomcat will not look there to 716 try to find classes. The current workaround is to place classes need 717 by JSP pages in a separate JAR file that is then installed into 718 the <filename>WEB-INF/lib</filename> folder. This requires a restart 719 of Tomcat. 720 </para> 721 </note> 722 711 723 <sect2 id="extensions_developer.resources.scripts"> 712 724 <title>Javascript and stylesheets</title> … … 1107 1119 </sect1> 1108 1120 1121 <sect1 id="extensions_developer.servlets"> 1122 <title>Custom servlets</title> 1123 <para> 1124 It is possible for an extension to include servlets without having 1125 to register those servlets in Tomcat's <filename>WEB-INF/web.xml</filename> 1126 file. The extension needs to be in a JAR file as usual. The servlet class 1127 should be located in the JAR file following regular Java conventions. 1128 Eg. The class <classname>my.domain.ServletClass</classname> should 1129 be located at <filename>my/domain/ServletClass.class</filename>. You 1130 also need to create a second XML file that contains the servlet 1131 definitions at <filename>META-INF/servlets.xml</filename>. The format for 1132 defining servlets in this file is very similar to how servlets are 1133 defined in the <filename>web.xml</filename> file. Here is an example: 1134 </para> 1135 1136 <programlisting language="xml"> 1137 <![CDATA[ 1138 <?xml version="1.0" encoding="UTF-8" ?> 1139 <servlets xmlns="http://base.thep.lu.se/servlets.xsd"> 1140 <servlet> 1141 <servlet-name>HelloWorld</servlet-name> 1142 <servlet-class>net.sf.basedb.examples.extensions.HelloWorldServlet</servlet-class> 1143 <init-param> 1144 <param-name>template</param-name> 1145 <param-value>Hello {user}! Welcome to the Servlet world!</param-value> 1146 </init-param> 1147 </servlet> 1148 </servlets> 1149 ]]> 1150 </programlisting> 1151 1152 <para> 1153 The <sgmltag class="starttag">servlets</sgmltag> tag is the root tag and is 1154 needed to set up the namespace and schema validation. This may contain 1155 any number of <sgmltag class="starttag">servlet</sgmltag> tags, each one 1156 defining a single servlet. 1157 </para> 1158 1159 <para> 1160 The <sgmltag class="starttag">servlet-name</sgmltag> tag contains the name 1161 of the servlet. This is a required tag and must be unique among the servlets 1162 defined by this extension. Other extensions may use the same name without any 1163 problems. 1164 </para> 1165 1166 <para> 1167 The <sgmltag class="starttag">servlet-class</sgmltag> tag contains the name 1168 of implementing class. This is required and the class must implement 1169 the <interfacename>Servlet</interfacename> interface and have a public, 1170 no-argument constructor. We recommend that servlet implementations instead 1171 extends the <classname>HttpServlet</classname> class. This will make the 1172 servlet programming easier. 1173 </para> 1174 1175 <para> 1176 A servlet may have any number <sgmltag class="starttag">init-param</sgmltag> 1177 tags, containing initialisation parameters for the servlet. Here is the 1178 code for the servlet references in the above example. 1179 </para> 1180 1181 <programlisting language="java"> 1182 <![CDATA[ 1183 public class HelloWorldServlet 1184 extends HttpServlet 1185 { 1186 private String template; 1187 public HelloWorldServlet() 1188 {} 1189 1190 @Override 1191 public void init() 1192 throws ServletException 1193 { 1194 ServletConfig cfg = getServletConfig(); 1195 template = cfg.getInitParameter("template"); 1196 if (template == null) template = "Hello {user}."; 1197 } 1198 1199 @Override 1200 protected void doGet(HttpServletRequest request, HttpServletResponse response) 1201 throws ServletException, IOException 1202 { 1203 final SessionControl sc = Base.getExistingSessionControl(request, true); 1204 final DbControl dc = sc.newDbControl(); 1205 try 1206 { 1207 User current = User.getById(dc, sc.getLoggedInUserId()); 1208 PrintWriter out = response.getWriter(); 1209 out.print(template.replace("{user}", current.getName())); 1210 } 1211 finally 1212 { 1213 if (dc != null) dc.close(); 1214 } 1215 } 1216 @Override 1217 protected void doPost(HttpServletRequest req, HttpServletResponse resp) 1218 throws ServletException, IOException 1219 { 1220 doGet(req, resp); 1221 } 1222 } 1223 ]]> 1224 </programlisting> 1225 1226 <para> 1227 Invoking the servlet is done with a URL that is constructed like: 1228 <filename>$HOME$/[servlet-name].servlet</filename>, where <code>$HOME$</code> 1229 is the home directory of the extension. 1230 </para> 1231 1232 <programlisting language="xml"> 1233 <![CDATA[ 1234 <extension 1235 id="net.sf.basedb.clients.web.menu.extensions.helloservletworld" 1236 extends="net.sf.basedb.clients.web.menu.extensions" 1237 > 1238 <index>5</index> 1239 <about> 1240 <name>Hello Servlet world</name> 1241 <description> 1242 This example uses a custom Servlet page to display the 1243 "Hello world" message instead of a javascript popup. 1244 </description> 1245 </about> 1246 <action-factory> 1247 <factory-class> 1248 net.sf.basedb.clients.web.extensions.menu.FixedMenuItemFactory 1249 </factory-class> 1250 <parameters> 1251 <title>Hello Servlet world!</title> 1252 <tooltip>Opens a Servlet generated page with the message</tooltip> 1253 <onClick> 1254 Main.openPopup('$HOME$/HelloWorld.servlet?ID=' + getSessionId(), 'HelloServletWorld', 400, 300) 1255 </onClick> 1256 <icon>~/images/servlet.png</icon> 1257 </parameters> 1258 </action-factory> 1259 </extension> 1260 ]]> 1261 </programlisting> 1262 1263 <note> 1264 <para> 1265 To keep things as simple as possible, a new instance of the servlet 1266 class is created for each request. If the servlet needs complex or 1267 expensive initialisation, that should be externalised to other 1268 classes that the servlet can use. 1269 </para> 1270 </note> 1271 1272 </sect1> 1273 1109 1274 </chapter> -
trunk/src/clients/web/net/sf/basedb/clients/web/Base.java
r4071 r4221 117 117 throws BaseException 118 118 { 119 return getSessionControl(pageContext.getRequest(), create); 120 } 121 122 /** 123 Get a new or existing <code>SessionControl</code> object 124 given a <code>ServletRequest</code> instance. This method will get 125 the <code>ID</code> parameter from the page URL and 126 try to retrieve the corresponding object from the 127 BASE {@link Application}. If no {@link SessionControl} 128 object exists, a new one will be created if the <code>create</code> 129 parameter is TRUE. 130 131 @param request The Servlet <code>request</code> variable 132 @param create If a new <code>SessionControl</code> should be created or not 133 @return A <code>SessionControl</code> object 134 @throws BaseException If there is an error 135 @since 2.7 136 */ 137 public static final SessionControl getSessionControl(ServletRequest request, boolean create) 138 { 119 139 SessionControl sc = null; 120 String id = pageContext.getRequest().getParameter("ID");121 if (id == null && pageContext.getRequest().getAttribute("ID") instanceof String)122 { 123 id = (String) pageContext.getRequest().getAttribute("ID");124 } 125 String remoteId = pageContext.getRequest().getRemoteAddr();140 String id = request.getParameter("ID"); 141 if (id == null && request.getAttribute("ID") instanceof String) 142 { 143 id = (String)request.getAttribute("ID"); 144 } 145 String remoteId = request.getRemoteAddr(); 126 146 try 127 147 { … … 138 158 return sc == null && create ? Application.newSessionControl("net.sf.basedb.clients.web", remoteId, id) : sc; 139 159 } 140 160 141 161 /** 142 162 Get an existing {@link SessionControl} object … … 157 177 throws NotLoggedInException, BaseException 158 178 { 159 SessionControl sc = getSessionControl(pageContext, false); 179 return getExistingSessionControl(pageContext.getRequest(), checkLoggedIn); 180 } 181 182 /** 183 Get an existing {@link SessionControl} object 184 given a <code>ServletRequest</code> object and optionally check that a user is logged in. 185 This method will get the <code>ID</code> parameter from the page URL and 186 try to retrieve the corresponding object from the 187 {@link Application} and check that a user is logged in if 188 the <code>checkLoggedIn</code> parameter is TRUE. 189 190 @param request The Servlet <code>request</code> variable 191 @param checkLoggedIn If the method should check if a user is logged in or not 192 @return A <code>SessionControl</code> object 193 @throws NotLoggedInException If a <code>SessionControl</code> object isn't found 194 or no user is logged in 195 @throws BaseException If there is another error 196 @since 2.7 197 */ 198 public static final SessionControl getExistingSessionControl(ServletRequest request, boolean checkLoggedIn) 199 throws NotLoggedInException, BaseException 200 { 201 SessionControl sc = getSessionControl(request, false); 160 202 if (sc == null || (checkLoggedIn && !sc.isLoggedIn())) 161 203 { … … 164 206 return sc; 165 207 } 166 208 209 167 210 /** 168 211 Get an existing {@link SessionControl} object given … … 192 235 throws PermissionDeniedException, NotLoggedInException, BaseException 193 236 { 194 SessionControl sc = getExistingSessionControl(pageContext, true); 237 return getExistingSessionControl(pageContext.getRequest(), permission, itemType); 238 } 239 240 /** 241 Get an existing {@link SessionControl} object given 242 a <code>ServletRequest</code> and check for generic (role-based) 243 permission to an item type. 244 245 This method will get the <code>ID</code> parameter from the page URL and 246 try to retrieve the corresponding object from the {@link Application}. 247 Then it checks that a user is logged in and that the logged in user has the 248 specified permission for item type. If {@link Permission#DENIED} is specified, 249 this method checks that the logged in user haven't been denied acces to 250 those items. 251 252 @param request The Servlet <code>request</code> variable 253 @param permission The permission to check for, use one of the codes 254 defined by the {@link Permission} class 255 @param itemType The code for the item type to check for the permission, 256 use one of the values defined by the {@link Item} class 257 @return A <code>SessionControl</code> object 258 @throws PermissionDeniedException If the logged in user doesn't have the 259 requested permission 260 @throws NotLoggedInException If no user is logged in or a <code>SessionControl</code> 261 object not is found 262 @throws BaseException If there is another error 263 @since 2.7 264 */ 265 public static final SessionControl getExistingSessionControl(ServletRequest request, 266 Permission permission, Item itemType) 267 throws PermissionDeniedException, NotLoggedInException, BaseException 268 { 269 SessionControl sc = getExistingSessionControl(request, true); 195 270 boolean hasPermission = sc.hasPermission(permission, itemType); 196 271 boolean checkDenied = permission == Permission.DENIED; … … 200 275 } 201 276 return sc; 202 } 203 277 } 278 204 279 /** 205 280 Same as: <code>getAndSetCurrentContext(sc, itemType, "", pageContext, defaultContext, false)</code>. 206 281 @see #getAndSetCurrentContext(SessionControl, Item, String, PageContext, ItemContext, boolean) 207 282 */ 208 public static ItemContext getAndSetCurrentContext(SessionControl sc, Item itemType, PageContext pageContext, ItemContext defaultContext) 283 public static ItemContext getAndSetCurrentContext(SessionControl sc, Item itemType, 284 PageContext pageContext, ItemContext defaultContext) 209 285 { 210 286 return getAndSetCurrentContext(sc, itemType, "", pageContext, defaultContext, false); … … 215 291 @see #getAndSetCurrentContext(SessionControl, Item, String, PageContext, ItemContext, boolean) 216 292 */ 217 public static ItemContext getAndSetCurrentContext(SessionControl sc, Item itemType, PageContext pageContext, ItemContext defaultContext, boolean resetTemporary) 293 public static ItemContext getAndSetCurrentContext(SessionControl sc, Item itemType, 294 PageContext pageContext, ItemContext defaultContext, boolean resetTemporary) 218 295 { 219 296 return getAndSetCurrentContext(sc, itemType, "", pageContext, defaultContext, resetTemporary); … … 224 301 @see #getAndSetCurrentContext(SessionControl, Item, String, PageContext, ItemContext, boolean) 225 302 */ 226 public static ItemContext getAndSetCurrentContext(SessionControl sc, Item itemType, String subContext, PageContext pageContext, ItemContext defaultContext) 227 { 228 return getAndSetCurrentContext(sc, itemType, subContext, pageContext, defaultContext, false); 303 public static ItemContext getAndSetCurrentContext(SessionControl sc, Item itemType, 304 String subContext, PageContext pageContext, ItemContext defaultContext) 305 { 306 return getAndSetCurrentContext(sc, itemType, subContext, pageContext, 307 defaultContext, false); 308 } 309 310 /** 311 @see #getAndSetCurrentContext(SessionControl, Item, String, ServletRequest, ItemContext, boolean) 312 */ 313 public static ItemContext getAndSetCurrentContext(SessionControl sc, Item itemType, 314 String subContext, PageContext pageContext, ItemContext defaultContext, boolean resetTemporary) 315 { 316 ServletRequest request = pageContext == null ? null : pageContext.getRequest(); 317 return getAndSetCurrentContext(sc, itemType, subContext, request, 318 defaultContext, resetTemporary); 229 319 } 230 320 … … 241 331 242 332 <li>The following settings are only updated if they are available in the 243 pageContext object'srequest parameters:333 request parameters: 244 334 245 335 <table> … … 343 433 @param itemType The type of item to get the context for 344 434 @param subContext The name of the subcontext 345 @param pageContext A <code>PageContext</code> object to get request346 information from, or null if the curren context shouldn't be updated435 @param request A <code>ServletRequest</code> object to get request 436 information from, or null if the current context shouldn't be updated 347 437 @param defaultContext A default context to copy information from if a current context 348 438 doesn't exist … … 350 440 example the 'exclude' filter which is only used in popup windows 351 441 @return an updated {@link net.sf.basedb.core.ItemContext} object. 442 @since 2.7 352 443 */ 353 444 @SuppressWarnings("unchecked") 354 public static ItemContext getAndSetCurrentContext(SessionControl sc, Item itemType, String subContext, PageContext pageContext, ItemContext defaultContext, boolean resetTemporary) 445 public static ItemContext getAndSetCurrentContext(SessionControl sc, Item itemType, 446 String subContext, ServletRequest request, ItemContext defaultContext, boolean resetTemporary) 355 447 { 356 448 ItemContext cc = sc.getCurrentContext(itemType, subContext, defaultContext); … … 395 487 cc.setObject("defaultColumns", defaultContext.getObject("defaultColumns")); 396 488 } 397 if (pageContext != null) 398 { 399 ServletRequest request = pageContext.getRequest(); 489 if (request != null) 490 { 400 491 401 492 // If the filter has changed we must return to the first page -
trunk/src/clients/web/net/sf/basedb/clients/web/extensions/ExtensionsControl.java
r4207 r4221 25 25 import java.io.File; 26 26 import java.util.Collections; 27 import java.util.EnumSet; 27 28 import java.util.Iterator; 28 29 import java.util.Set; 29 30 import java.util.TimerTask; 30 31 32 import javax.servlet.ServletContext; 31 33 import javax.servlet.jsp.PageContext; 32 34 … … 90 92 private static Settings settings; 91 93 94 // The Servlet Context provided by the web server 95 private static ServletContext servletContext; 96 92 97 // Automatic check for new/updated/deleted extensions 93 98 private static TimerTask autoInstallTask; … … 103 108 {@link ExtensionsServlet} when the web server starts up. 104 109 */ 105 public static synchronized void init(ExtensionsDirectory directory) 110 public static synchronized void init(ExtensionsDirectory directory, 111 ServletContext servletContext) 106 112 { 107 113 if (initialised) return; … … 118 124 119 125 // Install extensions 120 lastScanResults = extensionsDir.installAndUpdateExtensions(registry, false, false); 126 lastScanResults = extensionsDir.installAndUpdateExtensions(registry, 127 servletContext, false, false); 121 128 initAutoInstaller(); 122 129 initialised = true; … … 161 168 web client application is needed. 162 169 163 @param dc The DbControl to use for database access and permission checks 170 @param dc The DbControl to use for database access and 171 permission checks, or null to only get read permission 164 172 @return An extensions control instance 165 173 */ 166 174 public static ExtensionsControl get(DbControl dc) 167 175 { 168 SessionControl sc = dc.getSessionControl(); 169 Client c = Client.getById(dc, sc.getClientId()); 170 return new ExtensionsControl(c.getPermissions()); 176 Set<Permission> permissions = null; 177 if (dc != null) 178 { 179 SessionControl sc = dc.getSessionControl(); 180 Client c = Client.getById(dc, sc.getClientId()); 181 permissions = c.getPermissions(); 182 } 183 else 184 { 185 permissions = EnumSet.of(Permission.READ); 186 } 187 return new ExtensionsControl(permissions); 171 188 } 172 189 … … 259 276 checkPermission(Permission.WRITE, "extensions"); 260 277 lastScanResults = 261 extensionsDir.installAndUpdateExtensions(registry, true, forceUpdate);278 extensionsDir.installAndUpdateExtensions(registry, servletContext, true, forceUpdate); 262 279 return lastScanResults; 263 280 } … … 508 525 log.debug("Checking for new/updated/deleted extensions"); 509 526 int autoInstall = settings.getAutoInstall(); 510 lastScanResults = extensionsDir.installAndUpdateExtensions(registry, false, false); 527 lastScanResults = extensionsDir.installAndUpdateExtensions(registry, 528 servletContext, false, false); 511 529 nextAutoScan = autoInstall > 0 ? 512 530 System.currentTimeMillis() + autoInstall * 1000L : 0; -
trunk/src/clients/web/net/sf/basedb/clients/web/extensions/ExtensionsDirectory.java
r4207 r4221 36 36 import java.util.TreeMap; 37 37 import java.util.regex.Pattern; 38 39 import javax.servlet.ServletContext; 38 40 39 41 import net.sf.basedb.util.RegexpFileFilter; … … 239 241 @return The result of the scan 240 242 */ 241 publicsynchronized ScanResults installAndUpdateExtensions(Registry registry,242 boolean manualScan, boolean forceUpdate)243 synchronized ScanResults installAndUpdateExtensions(Registry registry, 244 ServletContext servletContext, boolean manualScan, boolean forceUpdate) 243 245 { 244 246 log.info("Begin scan for new/updated/deleted extensions"); … … 276 278 extractResources(forceUpdate, results); 277 279 278 // 5. Register new and updated extensions with the registry 280 // 5. Load servlets 281 loadServlets(servletContext, forceUpdate, results); 282 283 // 6. Register new and updated extensions with the registry 279 284 registerExtensions(registry, forceUpdate, results); 280 285 } … … 538 543 539 544 /** 545 Load servlet definitions from JAR files. Servlets should be 546 defined in META-INF/servlets.xml. 547 */ 548 private void loadServlets(ServletContext servletContext, boolean forceUpdate, ScanResults results) 549 { 550 for (ExtensionsFile extFile : installedFiles.values()) 551 { 552 // Do not load servlets from files with an error 553 if (extFile.hasError()) continue; 554 555 try 556 { 557 if (forceUpdate || extFile.isModified()) 558 { 559 int numServlets = extFile.loadServlets(servletContext); 560 if (numServlets > 0) 561 { 562 results.addMessage(extFile, 563 numServlets + " servlets defined successfully."); 564 } 565 } 566 } 567 catch (Throwable ex) 568 { 569 extFile.setError(true); 570 results.addErrorMessage(extFile, "Could not load servlets: " + ex.getMessage()); 571 log.error("Could not load servlets from " + extFile.getName(), ex); 572 } 573 } 574 } 575 576 577 /** 540 578 Register extensions with the registry. Unless forceUpdate is TRUE only 541 579 new and modified extensions are registered. Extensions files that has -
trunk/src/clients/web/net/sf/basedb/clients/web/extensions/ExtensionsFile.java
r4202 r4221 32 32 import java.util.ArrayList; 33 33 import java.util.Collections; 34 import java.util.HashMap; 34 35 import java.util.Iterator; 35 36 import java.util.List; 37 import java.util.Map; 36 38 import java.util.regex.Matcher; 37 39 import java.util.regex.Pattern; … … 39 41 import java.util.zip.ZipFile; 40 42 import java.util.zip.ZipInputStream; 43 44 import javax.servlet.ServletContext; 41 45 42 46 import net.sf.basedb.core.plugin.About; … … 77 81 private About about; 78 82 private boolean hasError; 83 84 private Map<String, ServletWrapper> servlets; 79 85 80 86 /** … … 423 429 return about; 424 430 } 431 432 433 434 /** 435 Load servlet definitions from a JAR file. 436 */ 437 int loadServlets(ServletContext context) 438 { 439 if (!isJar) return 0; 440 log.info("Loading servlets from JAR file: " + file.getName()); 441 InputStream in = null; 442 ZipFile zipFile = null; 443 int numServlets = 0; 444 try 445 { 446 zipFile = new ZipFile(file); 447 ZipEntry zipEntry = zipFile.getEntry("META-INF/servlets.xml"); 448 if (zipEntry == null) 449 { 450 log.info("META-INF/servlets.xml not found in file: " + file.getName()); 451 return 0; 452 } 453 454 if (servlets == null) servlets = new HashMap<String, ServletWrapper>(); 455 servlets.clear(); 456 in = zipFile.getInputStream(zipEntry); 457 458 ClassLoader jarLoader = JarClassLoader.getInstance(file.getAbsolutePath(), true); 459 460 ServletLoader servletLoader = new ServletLoader(); 461 servletLoader.loadXmlFile(in, file.getName(), jarLoader, true); 462 for (ServletWrapper wrapper : servletLoader.getServlets()) 463 { 464 wrapper.setServletContext(context); 465 servlets.put(wrapper.getServletName(), wrapper); 466 numServlets++; 467 } 468 } 469 catch (Exception ex) 470 { 471 log.error("Error loading servlets from JAR file: " + file, ex); 472 throw new RuntimeException("Error loading servlets from '" + file + "': " + 473 ex.getMessage(), ex); 474 } 475 finally 476 { 477 try 478 { 479 if (in != null) in.close(); 480 if (zipFile != null) zipFile.close(); 481 } 482 catch (IOException ex) 483 {} 484 } 485 log.info(numServlets + " servlets loaded from JAR file: " + file.getName()); 486 return numServlets; 487 } 488 425 489 426 490 /** … … 637 701 } 638 702 703 /** 704 Get a servlet that has been defined in this JAR file. 705 @param servletName The name of the servlet, specified by the 706 <servlet-name> tag in the XML file. 707 @return A wrapper that can be used to invoke the servlet, 708 or null if not servlet with the given name exists 709 */ 710 public ServletWrapper getServlet(String servletName) 711 { 712 return servlets == null ? null : servlets.get(servletName); 713 } 639 714 640 715 } -
trunk/src/clients/web/net/sf/basedb/clients/web/servlet/ExtensionsServlet.java
r4198 r4221 24 24 25 25 import java.io.File; 26 import java.io.IOException; 27 import java.util.regex.Matcher; 28 import java.util.regex.Pattern; 26 29 27 30 import javax.servlet.ServletConfig; … … 29 32 import javax.servlet.ServletException; 30 33 import javax.servlet.http.HttpServlet; 34 import javax.servlet.http.HttpServletRequest; 35 import javax.servlet.http.HttpServletResponse; 31 36 32 37 import net.sf.basedb.clients.web.extensions.ExtensionsControl; 33 38 import net.sf.basedb.clients.web.extensions.ExtensionsDirectory; 39 import net.sf.basedb.clients.web.extensions.ExtensionsFile; 40 import net.sf.basedb.clients.web.extensions.ServletWrapper; 34 41 35 42 /** … … 38 45 <code><load-on-startup>1</load-on-startup></code> 39 46 option in the web.xml file. When the servlet is loaded it will initialise the 40 {@link ExtensionsControl} class. This servlet is not used to handle 41 any requests. 47 {@link ExtensionsControl} class. 48 <p> 49 50 This servlet is also acting as a proxy for requests to extension defined 51 servlets. Such servlets are defined in <code>META-INF/servlets.xml</code> 52 in the extension JAR file. A request to a servlet must have the following 53 URL pattern: 54 <code>/extensions/[jar-name]/[servlet-name].servlet</code> 42 55 43 56 @author nicklas … … 66 79 ExtensionsDirectory extensions = new ExtensionsDirectory( 67 80 extensionsDir, resourcesDir, rootUrl, rootUrl + ExtensionsControl.RESOURCES_URL); 68 ExtensionsControl.init(extensions );81 ExtensionsControl.init(extensions, context); 69 82 } 70 83 84 /** 85 Path to servlet must match: /extensions/[jar-file-name]/[servlet-name].servlet 86 group(1) = JAR name, group(2) = Servlet name 87 */ 88 private static final Pattern PATH_MATCH = 89 Pattern.compile(ExtensionsControl.RESOURCES_URL + "/([^/]+)/(.+)\\.servlet"); 90 91 @Override 92 protected void doGet(HttpServletRequest request, HttpServletResponse response) 93 throws ServletException, IOException 94 { 95 96 String servletPath = request.getServletPath(); 97 Matcher m = PATH_MATCH.matcher(servletPath); 98 if (!m.matches()) 99 { 100 response.sendError(HttpServletResponse.SC_NOT_FOUND, servletPath); 101 return; 102 } 103 104 String jarName = m.group(1); 105 String servletName = m.group(2); 106 ExtensionsControl ec = ExtensionsControl.get(null); 107 ExtensionsFile file = ec.getFile(jarName); 108 if (file == null) 109 { 110 response.sendError(HttpServletResponse.SC_NOT_FOUND, servletPath); 111 return; 112 } 113 else if (!file.isJar()) 114 { 115 response.sendError(HttpServletResponse.SC_BAD_REQUEST, servletPath + " is not a JAR file."); 116 return; 117 } 118 119 ServletWrapper wrapper = file.getServlet(servletName); 120 if (wrapper == null) 121 { 122 response.sendError(HttpServletResponse.SC_NOT_FOUND, servletPath); 123 return; 124 } 125 wrapper.service(request, response); 126 } 127 128 @Override 129 protected void doPost(HttpServletRequest req, HttpServletResponse resp) 130 throws ServletException, IOException 131 { 132 doGet(req, resp); 133 } 134 71 135 }
Note: See TracChangeset
for help on using the changeset viewer.