Main Page | Packages | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

WebServer.java

00001 /*
00002  * OpenMobileIS - a free Java(TM) Framework for mobile applications Java(TM)
00003  * Copyright (C) 2004-2005 Philippe Delrieu
00004  * All rights reserved.
00005  * Contact: openmobileis@e-care.fr
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00020  * USA
00021  *
00022  *  Author : Philippe Delrieu
00023  *  
00024  *  Modifications :
00025  *  2004 Creation P.Delrieu
00026  *  2004 Modified by Romain Beaugrand
00027  * 
00028  */
00029 
00030 package org.openmobileis.embedded.webserver;
00031 
00032 import java.io.DataInputStream;
00033 import java.io.File;
00034 import java.io.FileInputStream;
00035 import java.io.IOException;
00036 import java.io.InputStream;
00037 import java.net.MalformedURLException;
00038 import java.net.ServerSocket;
00039 import java.net.Socket;
00040 import java.net.URL;
00041 import java.util.Enumeration;
00042 import java.util.Hashtable;
00043 import java.util.Properties;
00044 import java.util.StringTokenizer;
00045 import java.util.Vector;
00046 
00047 import javax.servlet.RequestDispatcher;
00048 import javax.servlet.Servlet;
00049 import javax.servlet.ServletContext;
00050 import javax.servlet.ServletException;
00051 import javax.servlet.ServletRequest;
00052 import javax.servlet.ServletResponse;
00053 
00054 import org.openmobileis.common.context.ApplicationContextManager;
00055 import org.openmobileis.common.context.Plateform;
00056 import org.openmobileis.common.util.PropertiesManager;
00057 import org.openmobileis.common.util.file.FileUtilities;
00058 import org.openmobileis.common.util.log.LogManager;
00059 import org.openmobileis.common.util.log.LogServices;
00060 import org.openmobileis.embedded.util.SystemAPI;
00061 
00062 public class WebServer implements ServletContext, RequestDispatcher {
00063     
00064     private final static int DEFAULT_PORT = 8080;
00065     
00066     private ServerThreadPool connexionPool;
00067     
00068     protected PathTreeDictionary registry;
00069     // loaded servlets : ClassName -> servlet instance
00070     private Hashtable servlets = new Hashtable();
00071     
00072     private Hashtable attributes;
00073     
00074     boolean running = true;
00075     private ServerSocket serverSocket;
00076     protected String hostName;
00077     protected int port = DEFAULT_PORT;
00078     
00079     private static Properties webserverProps;
00080     
00081     // path for properties
00082     public static String servletFile = "";
00083     public static String installPath = "";
00084 
00085     
00087     
00088     public WebServer() {
00089         this(System.getProperty("user.dir"));
00090     }
00091     
00092     public WebServer(String pathToConfFile) {
00093         System.setProperty("user.dir", pathToConfFile);
00094         try {
00095             if (pathToConfFile != null) {
00096                 webserverProps = PropertiesManager.getManager().getPropertiesFromPath(pathToConfFile+File.separator+"WEB-INF"+File.separator+"conf"+java.io.File.separator+"properties"+java.io.File.separator+"webserver.properties");
00097             } else {
00098                 webserverProps = PropertiesManager.getManager().getPropertiesFromPath("properties"+java.io.File.separator+"webserver.properties");
00099             }
00100             
00101         } catch (Exception ex) {
00102             System.out.println("Unable to find webserver.properties !!\nexit(1)");
00103             System.exit(1);
00104         }
00105         String strPort = webserverProps.getProperty("port");
00106         if (strPort != null && strPort.length() > 0) {
00107             try {
00108                 this.port = Integer.parseInt(strPort);
00109             } catch (NumberFormatException ex) {
00110                 this.port = DEFAULT_PORT;
00111             }
00112         }
00113         
00114         WebServer.installPath = webserverProps.getProperty("installPath");
00115         servletFile = webserverProps.getProperty("servletFile");
00116         registry = new PathTreeDictionary();
00117         try {
00118             connexionPool = new ServerThreadPool();
00119         } catch (Exception ex) {
00120             LogManager.traceError(LogServices.WEBSERVICE,
00121                     "can not initialise server connexion pool");
00122             LogManager.traceError(0, ex);
00123         }
00124         attributes = new Hashtable();
00125     }
00126     
00128     // pattern, which can contain wildcards, and the class name of the Servlet
00129     // to launch when a matching URL comes in.  Patterns are checked for
00130     // matches in the order they were added, and only the first match is run.
00131     public void addServlet(String urlPat, String className) {
00132       addServlet(urlPat, className, (Hashtable) null);
00133     }
00134 
00135     public void addServlet(String urlPat, String className, Hashtable initParams) {
00136       // Check if we're allowed to make one of these.
00137       SecurityManager security = System.getSecurityManager();
00138       if (security != null) {
00139         int i = className.lastIndexOf('.');
00140         if (i != -1) {
00141           security.checkPackageAccess(className.substring(0, i));
00142           security.checkPackageDefinition(className.substring(0, i));
00143         }
00144       }
00145 
00146       // Make a new one.
00147       try {
00148         addServlet(urlPat, (Servlet) Class.forName(className).newInstance(), initParams);
00149         return;
00150       } catch (ClassNotFoundException e) {
00151         LogManager.traceError(0, e);
00152         LogManager.traceError(LogServices.WEBSERVICE, "Class not found: " + className);
00153       } catch (ClassCastException e) {
00154         LogManager.traceError(0, e);
00155         LogManager.traceError(LogServices.WEBSERVICE, "Class cast problem: " + e.getMessage());
00156       } catch (InstantiationException e) {
00157         LogManager.traceError(0, e);
00158         LogManager.traceError(LogServices.WEBSERVICE, "Instantiation problem: " + e.getMessage());
00159       } catch (IllegalAccessException e) {
00160         LogManager.traceError(0, e);
00161         LogManager.traceError(LogServices.WEBSERVICE, "Illegal class access: " + e.getMessage());
00162       } catch (Exception e) {
00163         LogManager.traceError(0, e);
00164         LogManager.traceError(LogServices.WEBSERVICE, "Unexpected problem creating servlet: " + e);
00165         LogManager.traceError(LogServices.WEBSERVICE, e);
00166       }
00167     }
00168 
00170     // which can contain wildcards, and the Servlet to
00171     // launch when a matching URL comes in.  Patterns are checked for
00172     // matches in the order they were added, and only the first match is run.
00173     public void addServlet(String urlPat, Servlet servlet) {
00174       addServlet(urlPat, servlet, (Hashtable) null);
00175     }
00176 
00177     public void addServlet(String urlPat, Servlet servlet, Hashtable initParams) {
00178       try {
00179         servlet.init(new ServeConfig((ServletContext) this, initParams, urlPat));
00180         registry.put(urlPat, servlet);
00181         servlets.put(servlet.getClass().getName(), urlPat);
00182       } catch (ServletException e) {
00183           LogManager.traceError(0, e);
00184           LogManager.traceError(LogServices.WEBSERVICE,
00185                   "Problem initializing servlet: " + e);
00186       }
00187     }
00188     
00189     public Object[] getServletByURLorClassName(String name) {
00190         Object[] servlet = new Object[2];
00191         servlet = registry.get(name);
00192         if (servlet[0] == null) {
00193             String servletUri = (String)servlets.get(name);
00194             if (servletUri != null && servletUri.trim().length() > 0) {
00195                 servlet = registry.get(servletUri);
00196             }
00197         }
00198         if (servlet[0] == null) {
00199             String newName = name;
00200             int index = newName.lastIndexOf('/');
00201             while (index != -1) {
00202                 newName = newName.substring(0, index);
00203                 servlet = registry.get(newName);
00204                 if (servlet[0] != null) {
00205                     break;
00206                 }
00207                 index = newName.lastIndexOf('/');
00208             }
00209         }
00210         return servlet;
00211     }
00212     
00213     // Run the server.  Returns only on errors.
00214     public void serve() throws IOException{
00215         // Load Servlets
00216         //this.loadServlets();
00217         
00218         // First of all, instantiate the LogManager to the console
00219         if (LogManager.getInstance() == null) {
00220                 LogManager.registerLogManager(null);
00221         }
00222         
00223         this.readServlets(servletFile);
00224         serverSocket = new ServerSocket(port, 1000);
00225         hostName = serverSocket.getInetAddress().getHostName();
00226         
00227         
00228         // start Web Browser
00229                 try {
00230             Plateform plateform = ApplicationContextManager.getManager().getApplicationContext().getPlateform();
00231             if (plateform.getOS().equals(Plateform.POCKETPCOS)) {
00232               if ((PropertiesManager.getManager().getProperty("org.openmobileis.embedded.execprog.browser")!=null) &&
00233                   (PropertiesManager.getManager().getProperty("org.openmobileis.embedded.execprog.browser.args")!=null))        {
00234                 System.loadLibrary("ExecDLL2002");
00235                       LogManager.traceInfo(0,"Start Pocket IE");
00236                 SystemAPI.execProgram(PropertiesManager.getManager().getProperty("org.openmobileis.embedded.execprog.browser")
00237                                                 , PropertiesManager.getManager().getProperty("org.openmobileis.embedded.execprog.browser.args")+"/"+Long.toString(System.currentTimeMillis())); //add long to avoid IE cache
00238               } else    {
00239                       LogManager.traceInfo(0,"Pocket IE not started on PocketPC no properties defined.");
00240               }
00241                         }
00242                 } catch (Throwable e) {
00243                         LogManager.traceError(0, e);
00244                         LogManager.traceError(LogServices.WEBSERVICE, "Can not launch ie with parameters : " + PropertiesManager.getManager().getProperty("execprog.browser")
00245                                         + " args : " + PropertiesManager.getManager().getProperty("execprog.browser.args"));
00246                 }
00247         
00248         try { // accept request from clients
00249             while (true) {
00250                 Socket socket = serverSocket.accept();
00251                 connexionPool.runServerConnexion(this, socket);
00252             } // end while
00253         } catch (IOException e) {
00254             LogManager.traceError(0, e);
00255             LogManager.traceError(LogServices.WEBSERVICE,
00256                     "IOEXception during servlet process Accept: " + e);
00257         } finally {
00258             try {
00259                 serverSocket.close();
00260             } catch (Exception e) {
00261                 LogManager.traceError(LogServices.WEBSERVICE, e);
00262             }
00263         }
00264     }
00265     
00267     public void destroyAllServlets() {
00268       Enumeration en = registry.elements();
00269       while (en.hasMoreElements()) {
00270         Servlet servlet = (Servlet) en.nextElement();
00271         servlet.destroy();
00272       }
00273       registry = new PathTreeDictionary();
00274       // invalidate all sessions?
00275     }
00276     
00277     /*
00278      * free all resources
00279      */
00280     public void freeResources() throws Exception {
00281         this.destroyAllServlets();
00282         connexionPool.freeResources();
00283         serverSocket.close();
00284         LogManager.traceInfo(LogServices.WEBSERVICE, "Web server is stopped");
00285         //System.exit(0);
00286     }
00287     
00288     private void readServlets(String cfgfile) {
00293         Hashtable servletstbl, parameterstbl;
00294         servletstbl = new Hashtable();
00295         parameterstbl = new Hashtable();
00296         if (cfgfile != null) {
00297           File file = new File(cfgfile);
00298           if (file.exists() && file.canRead()) {
00299             try {
00300               DataInputStream in = new DataInputStream(new FileInputStream(file));
00304               do {
00305                 String servletdsc = in.readLine();
00306                 if (servletdsc == null)
00307                   break;
00308                 StringTokenizer dsctokenzr = new StringTokenizer(servletdsc, ".=,", false);
00309                 if (dsctokenzr.hasMoreTokens()) {
00310                   if (!dsctokenzr.nextToken().equalsIgnoreCase("servlet")) {
00311                     System.err.println("No leading 'servlet' keyword, the sentence is skipped");
00312                     break;
00313                   }
00314                   if (dsctokenzr.hasMoreTokens()) {
00315                     String servletname = dsctokenzr.nextToken();
00316 
00317                     if (dsctokenzr.hasMoreTokens()) {
00318                       String lt = dsctokenzr.nextToken();
00319                       if (lt.equalsIgnoreCase("code")) {
00320                         if (dsctokenzr.hasMoreTokens())
00321                           servletstbl.put(servletname, dsctokenzr.nextToken("="));
00322                       } else if (lt.equalsIgnoreCase("initArgs")) {
00323                         Hashtable initparams = new Hashtable();
00324                         while (dsctokenzr.hasMoreTokens()) {
00325                           String key = dsctokenzr.nextToken("=,");
00326                           if (dsctokenzr.hasMoreTokens())
00327                             initparams.put(key, dsctokenzr.nextToken(",="));
00328                         }
00329                         parameterstbl.put(servletname, initparams);
00330                       } else
00331                         System.err.println("Unrecognized token " + lt + " in " + servletdsc + ", the line's skipped");
00332                     }
00333                   }
00334                 }
00335               }
00336               while (true);
00337             } catch (IOException e) {
00338               System.err.println("Problem reading cfg file: " + e);
00339             }
00340             Enumeration se = servletstbl.keys();
00341             String servletname;
00342             while (se.hasMoreElements()) {
00343               servletname = (String) se.nextElement();
00344               addServlet(servletname, (String) servletstbl.get(servletname), (Hashtable) parameterstbl.get(servletname));
00345             }
00346           }
00347         }
00348       }
00349     
00350 /*    protected void loadServlets() {
00351         // load servlets
00352         
00353         // add the FileServlet by default. By default, if there is no matching
00354         // with the other servlet,
00355         // the file servlet is choosen
00356         this.addServlet("/FileServlet", "org.openmobileis.services.servlet.FileServlet");
00357         
00358         java.util.Properties props = new java.util.Properties();
00359         try {
00360             props.load(new java.io.FileInputStream(servletFile));
00361             java.util.Enumeration enum = props.propertyNames();
00362             while (enum.hasMoreElements()) {
00363                 String className = (String) enum.nextElement();
00364                 String pattern = (String) props.getProperty(className);
00365                 this.addServlet(pattern, className);
00366             }
00367         } catch (IOException ex) {
00368             LogManager.traceError(0, ex);
00369         }
00370     }*/
00371     
00372     
00373     
00374     
00375     
00376     
00377     // ServletContext METHODS
00378     // ***************************************************************************************************************
00379 
00381     // null if the attribute does not exist.  This method allows access to
00382     // additional information about the service, not already provided by
00383     // the other methods in this interface.
00384     public Object getAttribute(String name) {
00385       // This server does not support attributes.
00386       return attributes.get(name);
00387     }
00388     
00389     public Enumeration getAttributeNames() {
00390         return attributes.keys();
00391         }
00392     
00393     public ServletContext getContext(String uripath) {
00394         return this; // only root context supported
00395         }
00396     
00397     // no way to specify parameters for context
00398     public String getInitParameter(String param) {
00399       return null;
00400     }
00401     
00402     public Enumeration getInitParameterNames() {
00403         return null;
00404         }
00405     
00406     public int getMajorVersion() {
00407         return 2; // support 2.x
00408         }
00409 
00411     // @param file file name whose MIME type is required
00412     public String getMimeType(String file) {
00413       file = file.toUpperCase();
00414 
00415       if (file.endsWith(".HTML") || file.endsWith(".HTM"))
00416         return "text/html";
00417       if (file.endsWith(".TXT"))
00418         return "text/plain";
00419       if (file.endsWith(".XML"))
00420         return "text/xml";
00421       if (file.endsWith(".CSS"))
00422         return "text/css";
00423       if (file.endsWith(".SGML") || file.endsWith(".SGM"))
00424         return "text/x-sgml";
00425       // Image
00426       if (file.endsWith(".GIF"))
00427         return "image/gif";
00428       if (file.endsWith(".JPG") || file.endsWith(".JPEG") || file.endsWith(".JPE"))
00429         return "image/jpeg";
00430       if (file.endsWith(".PNG"))
00431         return "image/png";
00432       if (file.endsWith(".TIF") || file.endsWith(".TIFF"))
00433         return "image/tiff";
00434       if (file.endsWith(".RGB"))
00435         return "image/x-rgb";
00436       if (file.endsWith(".XPM"))
00437         return "image/x-xpixmap";
00438       if (file.endsWith(".XBM"))
00439         return "image/x-xbitmap";
00440       if (file.endsWith(".SVG"))
00441         return "image/svg-xml ";
00442       if (file.endsWith(".SVGZ"))
00443         return "image/svg-xml ";
00444       // Audio
00445       if (file.endsWith(".AU") || file.endsWith(".SND"))
00446         return "audio/basic";
00447       if (file.endsWith(".MID") || file.endsWith(".MIDI") || file.endsWith(".RMI") || file.endsWith(".KAR"))
00448         return "audio/mid";
00449       if (file.endsWith(".MPGA") || file.endsWith(".MP2") || file.endsWith(".MP3"))
00450         return "audio/mpeg";
00451       if (file.endsWith(".WAV"))
00452         return "audio/wav";
00453       if (file.endsWith(".AIFF") || file.endsWith(".AIFC"))
00454         return "audio/aiff";
00455       if (file.endsWith(".AIF"))
00456         return "audio/x-aiff";
00457       if (file.endsWith(".RA"))
00458         return "audio/x-realaudio";
00459       if (file.endsWith(".RPM"))
00460         return "audio/x-pn-realaudio-plugin";
00461       if (file.endsWith(".RAM"))
00462         return "audio/x-pn-realaudio";
00463       if (file.endsWith(".SD2"))
00464         return "audio/x-sd2";
00465       // Application
00466       if (file.endsWith(".BIN") || file.endsWith(".DMS") || file.endsWith(".LHA") || file.endsWith(".LZH") || file.endsWith(".EXE") || file.endsWith(".CLASS"))
00467         return "application/octet-stream";
00468       if (file.endsWith(".HQX"))
00469         return "application/mac-binhex40";
00470       if (file.endsWith(".PS") || file.endsWith(".AI") || file.endsWith(".EPS"))
00471         return "application/postscript";
00472       if (file.endsWith(".PDF"))
00473         return "application/pdf";
00474       if (file.endsWith(".RTF"))
00475         return "application/rtf";
00476       if (file.endsWith(".DOC"))
00477         return "application/msword";
00478       if (file.endsWith(".PPT"))
00479         return "application/powerpoint";
00480       if (file.endsWith(".FIF"))
00481         return "application/fractals";
00482       if (file.endsWith(".P7C"))
00483         return "application/pkcs7-mime";
00484       // Application/x
00485       if (file.endsWith(".JS"))
00486         return "application/x-javascript";
00487       if (file.endsWith(".Z"))
00488         return "application/x-compress";
00489       if (file.endsWith(".GZ"))
00490         return "application/x-gzip";
00491       if (file.endsWith(".TAR"))
00492         return "application/x-tar";
00493       if (file.endsWith(".TGZ"))
00494         return "application/x-compressed";
00495       if (file.endsWith(".ZIP"))
00496         return "application/x-zip-compressed";
00497       if (file.endsWith(".DIR") || file.endsWith(".DCR") || file.endsWith(".DXR"))
00498         return "application/x-director";
00499       if (file.endsWith(".DVI"))
00500         return "application/x-dvi";
00501       if (file.endsWith(".TEX"))
00502         return "application/x-tex";
00503       if (file.endsWith(".LATEX"))
00504         return "application/x-latex";
00505       if (file.endsWith(".TCL"))
00506         return "application/x-tcl";
00507       if (file.endsWith(".CER") || file.endsWith(".CRT") || file.endsWith(".DER"))
00508         return "application/x-x509-ca-cert";
00509       // Video
00510       if (file.endsWith(".MPG") || file.endsWith(".MPE") || file.endsWith(".MPEG"))
00511         return "video/mpeg";
00512       if (file.endsWith(".QT") || file.endsWith(".MOV"))
00513         return "video/quicktime";
00514       if (file.endsWith(".AVI"))
00515         return "video/x-msvideo";
00516       if (file.endsWith(".MOVIE"))
00517         return "video/x-sgi-movie";
00518       // Chemical
00519       if (file.endsWith(".PDB") || file.endsWith(".XYZ"))
00520         return "chemical/x-pdb";
00521       // X-
00522       if (file.endsWith(".ICE"))
00523         return "x-conference/x-cooltalk";
00524       if (file.endsWith(".WRL") || file.endsWith(".VRML"))
00525         return "x-world/x-vrml";
00526       if (file.endsWith(".WML"))
00527         return "text/vnd.wap.wml";
00528       if (file.endsWith(".WMLC"))
00529         return "application/vnd.wap.wmlc";
00530       if (file.endsWith(".WMLS"))
00531         return "text/vnd.wap.wmlscript";
00532       if (file.endsWith(".WMLSC"))
00533         return "application/vnd.wap.wmlscriptc";
00534       if (file.endsWith(".WBMP"))
00535         return "image/vnd.wap.wbmp";
00536 
00537       return null;
00538     }
00539     
00540         public int getMinorVersion() {
00541             return 3; // support 2.3
00542         }
00543     
00544     public RequestDispatcher getNamedDispatcher(String name) {
00545         return this;
00546     }
00547     
00548     public String getRealPath(String path) {
00549         return installPath + FileUtilities.convertFileNameToSystem(path);
00550         //return htdocs + File.separator + FileUtilities.convertFileNameToSystem(path);
00551     }
00552     
00553     public RequestDispatcher getRequestDispatcher(String path) {
00554         return this;
00555     }
00556     
00557     // only root relative in this implementation
00558     public URL getResource(String path) throws MalformedURLException {
00559       return new URL("http", hostName, port, path);
00560     }
00561     
00562     public InputStream getResourceAsStream(String path) {
00563         return null; // we don't provide resources in this way
00564         }
00565     
00566     public java.util.Set getResourcePaths(java.lang.String path) {
00567         // TODO: implement
00568         return null;
00569         }
00570     
00572     // is running.
00573     // Same as the CGI variable SERVER_SOFTWARE.
00574     public String getServerInfo() {
00575       return Identification.serverName + " " + Identification.serverVersion + " (" + Identification.serverUrl + ")";
00576     }
00577     
00578     public Servlet getServlet(String name) {
00579         // Deprecated. As of Java Servlet API 2.1, with no direct replacement.
00580         // This method was originally defined to retrieve a servlet from a ServletContext.
00581         // In this version, this method always returns null and remains only to preserve binary compatibility.
00582         // This method will be permanently removed in a future version of the Java Servlet API.
00583 
00584         // In lieu of this method, servlets can share information using the ServletContext class
00585         // and can perform shared business logic by invoking methods on common non-servlet classes.
00586         return null;
00587     }
00588     
00595     public java.lang.String getServletContextName() {
00596       return null; //"ROOT";
00597     }
00598     
00600     // servlets that are accesible will be returned.  This enumeration always
00601     // includes the servlet itself.
00602     public Enumeration getServletNames() {
00603         // Deprecated. As of Java Servlet API 2.1, with no replacement.
00604         // This method was originally defined to return an Enumeration of all the servlet names known to this context.
00605         // In this version, this method always returns an empty Enumeration and remains only to preserve binary compatibility.
00606         // This method will be permanently removed in a future version of the Java Servlet API.
00607         return new Vector().elements();
00608         }
00609     
00610     public Enumeration getServlets() {
00611         // Deprecated. As of Java Servlet API 2.0, with no replacement.
00612         // This method was originally defined to return an Enumeration of all the servlets known to this servlet context.
00613         // In this version, this method always returns an empty enumeration and remains only to preserve binary compatibility.
00614         // This method will be permanently removed in a future version of the Java Servlet API.
00615         return new Vector().elements();
00616     }
00617     
00618     public void log(Exception exception, String msg) {
00619         LogManager.traceWarning(LogServices.WEBSERVICE, msg);
00620         LogManager.traceWarning(LogServices.WEBSERVICE, exception);
00621     }
00622     
00623     public void log(String msg) {
00624         LogManager.traceWarning(LogServices.WEBSERVICE, msg);
00625     }
00626     
00627     public void log(String message, Throwable throwable) {
00628         LogManager.traceWarning(LogServices.WEBSERVICE, message);
00629         LogManager.traceWarning(LogServices.WEBSERVICE, throwable);
00630     }
00631     
00632     public void removeAttribute(String name) {
00633         attributes.remove(name);
00634         }
00635     
00636     public void setAttribute(String name, Object object) {
00637         attributes.put(name, object);
00638         }
00639     
00640     
00641     
00642     // RequestDispatcher METHODS
00643     // ***************************************************************************************************************
00644     
00645     public void forward(ServletRequest request, ServletResponse response) {
00646     }
00647     public void include(ServletRequest request, ServletResponse response) {
00648     }
00649 }

Generated on Wed Dec 14 21:05:35 2005 for OpenMobileIS by  doxygen 1.4.4