00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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.SessionContextManager;
00055 import org.openmobileis.common.util.PropertiesManager;
00056 import org.openmobileis.common.util.file.FileUtilities;
00057 import org.openmobileis.common.util.log.LogManager;
00058 import org.openmobileis.common.util.log.LogServices;
00059
00060 public class WebServer implements ServletContext, RequestDispatcher {
00061
00062 private final static int DEFAULT_PORT = 8080;
00063
00064 private ServerThreadPool connexionPool;
00065
00066 protected PathTreeDictionary registry;
00067
00068
00069 private Hashtable servlets = new Hashtable();
00070
00071 private Hashtable attributes;
00072
00073 boolean running = true;
00074
00075 private ServerSocket serverSocket;
00076
00077 protected String hostName;
00078
00079 protected int port = DEFAULT_PORT;
00080
00081 private static Properties webserverProps;
00082
00083
00084 public static String servletFile = "";
00085
00086 public static String installPath = "";
00087
00089
00090 public WebServer() {
00091 this(System.getProperty("user.dir"));
00092 }
00093
00094 public WebServer(String pathToConfFile) {
00095 System.setProperty("user.dir", pathToConfFile);
00096 System.out.println("Webserver const userdir:"+pathToConfFile);
00097 try {
00098 if (pathToConfFile != null) {
00099 try {
00100
00101 webserverProps = PropertiesManager.getManager().getPropertiesFromPath("/WEB-INF/conf/properties/webserver.properties");
00102 } catch (Throwable ex) {
00103
00104 webserverProps = PropertiesManager.getManager().getPropertiesFromPath(
00105 pathToConfFile + File.separator + "WEB-INF" + File.separator + "conf" + java.io.File.separator + "properties" + java.io.File.separator
00106 + "webserver.properties");
00107 }
00108 } else {
00109 webserverProps = PropertiesManager.getManager().getPropertiesFromPath("properties" + java.io.File.separator + "webserver.properties");
00110 }
00111
00112 } catch (Exception ex) {
00113 ex.printStackTrace();
00114 System.out.println("Unable to find webserver.properties !!\nexit(1)");
00115 System.exit(1);
00116 }
00117 String strPort = webserverProps.getProperty("port");
00118 if (strPort != null && strPort.length() > 0) {
00119 try {
00120 this.port = Integer.parseInt(strPort);
00121 } catch (NumberFormatException ex) {
00122 this.port = DEFAULT_PORT;
00123 }
00124 }
00125
00126 WebServer.installPath = webserverProps.getProperty("installPath");
00127 servletFile = webserverProps.getProperty("servletFile");
00128 registry = new PathTreeDictionary();
00129 try {
00130 connexionPool = new ServerThreadPool();
00131 } catch (Exception ex) {
00132 LogManager.traceError(LogServices.WEBSERVICE, "can not initialise server connexion pool");
00133 LogManager.traceError(0, ex);
00134 }
00135 attributes = new Hashtable();
00136
00137
00138
00139 SessionContextManager.getManager().createSessionContext("OPENMOBILEISSESSION");
00140 SessionContextManager.getManager().joinSessionContext("OPENMOBILEISSESSION");
00141 }
00142
00143 public void stopServer() {
00144 try {
00145 serverSocket.close();
00146 connexionPool.freeResources();
00147 connexionPool = null;
00148 } catch (Throwable ex) {
00149 LogManager.traceError(0, ex);
00150 }
00151 }
00152
00154
00155
00156
00157 public void addServlet(String urlPat, String className) {
00158 addServlet(urlPat, className, (Hashtable) null);
00159 }
00160
00161 public void addServlet(String urlPat, String className, Hashtable initParams) {
00162
00163 SecurityManager security = System.getSecurityManager();
00164 if (security != null) {
00165 int i = className.lastIndexOf('.');
00166 if (i != -1) {
00167 security.checkPackageAccess(className.substring(0, i));
00168 security.checkPackageDefinition(className.substring(0, i));
00169 }
00170 }
00171
00172
00173 try {
00174 addServlet(urlPat, (Servlet) Class.forName(className).newInstance(), initParams);
00175 return;
00176 } catch (ClassNotFoundException e) {
00177 LogManager.traceError(0, e);
00178 LogManager.traceError(LogServices.WEBSERVICE, "Class not found: " + className);
00179 } catch (ClassCastException e) {
00180 LogManager.traceError(0, e);
00181 LogManager.traceError(LogServices.WEBSERVICE, "Class cast problem: " + e.getMessage());
00182 } catch (InstantiationException e) {
00183 LogManager.traceError(0, e);
00184 LogManager.traceError(LogServices.WEBSERVICE, "Instantiation problem: " + e.getMessage());
00185 } catch (IllegalAccessException e) {
00186 LogManager.traceError(0, e);
00187 LogManager.traceError(LogServices.WEBSERVICE, "Illegal class access: " + e.getMessage());
00188 } catch (Exception e) {
00189 LogManager.traceError(0, e);
00190 LogManager.traceError(LogServices.WEBSERVICE, "Unexpected problem creating servlet: " + e);
00191 LogManager.traceError(LogServices.WEBSERVICE, e);
00192 }
00193 }
00194
00196
00197
00198
00199 public void addServlet(String urlPat, Servlet servlet) {
00200 addServlet(urlPat, servlet, (Hashtable) null);
00201 }
00202
00203 public void addServlet(String urlPat, Servlet servlet, Hashtable initParams) {
00204 try {
00205 servlet.init(new ServeConfig((ServletContext) this, initParams, urlPat));
00206 registry.put(urlPat, servlet);
00207 servlets.put(servlet.getClass().getName(), urlPat);
00208 } catch (ServletException e) {
00209 LogManager.traceError(0, e);
00210 LogManager.traceError(LogServices.WEBSERVICE, "Problem initializing servlet: " + e);
00211 }
00212 }
00213
00214 public Object[] getServletByURLorClassName(String name) {
00215 Object[] servlet = new Object[2];
00216 servlet = registry.get(name);
00217 if (servlet[0] == null) {
00218 String servletUri = (String) servlets.get(name);
00219 if (servletUri != null && servletUri.trim().length() > 0) {
00220 servlet = registry.get(servletUri);
00221 }
00222 }
00223 if (servlet[0] == null) {
00224 String newName = name;
00225 int index = newName.lastIndexOf('/');
00226 while (index != -1) {
00227 newName = newName.substring(0, index);
00228 servlet = registry.get(newName);
00229 if (servlet[0] != null) {
00230 break;
00231 }
00232 index = newName.lastIndexOf('/');
00233 }
00234 }
00235 return servlet;
00236 }
00237
00238
00239 public void serve() throws IOException {
00240
00241
00242 if (LogManager.getInstance() == null) {
00243 LogManager.registerLogManager(null);
00244 }
00245
00246 System.out.println("Webserver server servletFile" + servletFile);
00247 this.readServlets(servletFile);
00248 serverSocket = new ServerSocket(port, 1000);
00249 hostName = serverSocket.getInetAddress().getHostName();
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 try {
00287 while (true) {
00288 Socket socket = serverSocket.accept();
00289 connexionPool.runServerConnexion(this, socket);
00290 }
00291 } catch (IOException e) {
00292
00293 LogManager.traceError(LogServices.WEBSERVICE, "Web server connexion stopped ");
00294 } finally {
00295 try {
00296 serverSocket.close();
00297 } catch (Exception e) {
00298 LogManager.traceError(LogServices.WEBSERVICE, e);
00299 }
00300 }
00301 }
00302
00304 public void destroyAllServlets() {
00305 Enumeration en = registry.elements();
00306 while (en.hasMoreElements()) {
00307 Servlet servlet = (Servlet) en.nextElement();
00308 servlet.destroy();
00309 }
00310 registry = new PathTreeDictionary();
00311
00312 }
00313
00314
00315
00316
00317 public void freeResources() throws Exception {
00318 this.destroyAllServlets();
00319 connexionPool.freeResources();
00320 serverSocket.close();
00321 LogManager.traceInfo(LogServices.WEBSERVICE, "Web server is stopped");
00322
00323 }
00324
00325 private void readServlets(String cfgfile) {
00330 Hashtable servletstbl, parameterstbl;
00331 servletstbl = new Hashtable();
00332 parameterstbl = new Hashtable();
00333 if (cfgfile != null) {
00334 File file = new File(cfgfile);
00335 try {
00336 DataInputStream in = null;
00337 if (file.exists() && file.canRead()) {
00338 in = new DataInputStream(new FileInputStream(file));
00339 } else {
00340 in = new DataInputStream(PropertiesManager.getManager().getRessourceAsStream(cfgfile));
00341 }
00345 do {
00346 String servletdsc = in.readLine();
00347 if (servletdsc == null)
00348 break;
00349 StringTokenizer dsctokenzr = new StringTokenizer(servletdsc, ".=,", false);
00350 if (dsctokenzr.hasMoreTokens()) {
00351 if (!dsctokenzr.nextToken().equalsIgnoreCase("servlet")) {
00352 System.err.println("No leading 'servlet' keyword, the sentence is skipped");
00353 break;
00354 }
00355 if (dsctokenzr.hasMoreTokens()) {
00356 String servletname = dsctokenzr.nextToken();
00357
00358 if (dsctokenzr.hasMoreTokens()) {
00359 String lt = dsctokenzr.nextToken();
00360 if (lt.equalsIgnoreCase("code")) {
00361 if (dsctokenzr.hasMoreTokens())
00362 servletstbl.put(servletname, dsctokenzr.nextToken("="));
00363 } else if (lt.equalsIgnoreCase("initArgs")) {
00364 Hashtable initparams = new Hashtable();
00365 while (dsctokenzr.hasMoreTokens()) {
00366 String key = dsctokenzr.nextToken("=,");
00367 if (dsctokenzr.hasMoreTokens())
00368 initparams.put(key, dsctokenzr.nextToken(",="));
00369 }
00370 parameterstbl.put(servletname, initparams);
00371 } else
00372 System.err.println("Unrecognized token " + lt + " in " + servletdsc + ", the line's skipped");
00373 }
00374 }
00375 }
00376 } while (true);
00377 Enumeration se = servletstbl.keys();
00378 String servletname;
00379 while (se.hasMoreElements()) {
00380 servletname = (String) se.nextElement();
00381 addServlet(servletname, (String) servletstbl.get(servletname), (Hashtable) parameterstbl.get(servletname));
00382 }
00383 } catch (IOException e) {
00384 System.err.println("Problem reading cfg file: " + e);
00385 }
00386
00387 }
00388 }
00389
00390
00391
00392
00394
00395
00396
00397 public Object getAttribute(String name) {
00398
00399 return attributes.get(name);
00400 }
00401
00402 public Enumeration getAttributeNames() {
00403 return attributes.keys();
00404 }
00405
00406 public ServletContext getContext(String uripath) {
00407 return this;
00408 }
00409
00410
00411 public String getInitParameter(String param) {
00412 return null;
00413 }
00414
00415 public Enumeration getInitParameterNames() {
00416 return null;
00417 }
00418
00419 public int getMajorVersion() {
00420 return 2;
00421 }
00422
00424
00425 public String getMimeType(String file) {
00426 file = file.toUpperCase();
00427
00428 if (file.endsWith(".HTML") || file.endsWith(".HTM"))
00429 return "text/html";
00430 if (file.endsWith(".TXT"))
00431 return "text/plain";
00432 if (file.endsWith(".XML"))
00433 return "text/xml";
00434 if (file.endsWith(".CSS"))
00435 return "text/css";
00436 if (file.endsWith(".SGML") || file.endsWith(".SGM"))
00437 return "text/x-sgml";
00438
00439 if (file.endsWith(".GIF"))
00440 return "image/gif";
00441 if (file.endsWith(".JPG") || file.endsWith(".JPEG") || file.endsWith(".JPE"))
00442 return "image/jpeg";
00443 if (file.endsWith(".PNG"))
00444 return "image/png";
00445 if (file.endsWith(".TIF") || file.endsWith(".TIFF"))
00446 return "image/tiff";
00447 if (file.endsWith(".RGB"))
00448 return "image/x-rgb";
00449 if (file.endsWith(".XPM"))
00450 return "image/x-xpixmap";
00451 if (file.endsWith(".XBM"))
00452 return "image/x-xbitmap";
00453 if (file.endsWith(".SVG"))
00454 return "image/svg-xml ";
00455 if (file.endsWith(".SVGZ"))
00456 return "image/svg-xml ";
00457
00458 if (file.endsWith(".AU") || file.endsWith(".SND"))
00459 return "audio/basic";
00460 if (file.endsWith(".MID") || file.endsWith(".MIDI") || file.endsWith(".RMI") || file.endsWith(".KAR"))
00461 return "audio/mid";
00462 if (file.endsWith(".MPGA") || file.endsWith(".MP2") || file.endsWith(".MP3"))
00463 return "audio/mpeg";
00464 if (file.endsWith(".WAV"))
00465 return "audio/wav";
00466 if (file.endsWith(".AIFF") || file.endsWith(".AIFC"))
00467 return "audio/aiff";
00468 if (file.endsWith(".AIF"))
00469 return "audio/x-aiff";
00470 if (file.endsWith(".RA"))
00471 return "audio/x-realaudio";
00472 if (file.endsWith(".RPM"))
00473 return "audio/x-pn-realaudio-plugin";
00474 if (file.endsWith(".RAM"))
00475 return "audio/x-pn-realaudio";
00476 if (file.endsWith(".SD2"))
00477 return "audio/x-sd2";
00478
00479 if (file.endsWith(".BIN") || file.endsWith(".DMS") || file.endsWith(".LHA") || file.endsWith(".LZH") || file.endsWith(".EXE") || file.endsWith(".CLASS"))
00480 return "application/octet-stream";
00481 if (file.endsWith(".HQX"))
00482 return "application/mac-binhex40";
00483 if (file.endsWith(".PS") || file.endsWith(".AI") || file.endsWith(".EPS"))
00484 return "application/postscript";
00485 if (file.endsWith(".PDF"))
00486 return "application/pdf";
00487 if (file.endsWith(".RTF"))
00488 return "application/rtf";
00489 if (file.endsWith(".DOC"))
00490 return "application/msword";
00491 if (file.endsWith(".PPT"))
00492 return "application/powerpoint";
00493 if (file.endsWith(".FIF"))
00494 return "application/fractals";
00495 if (file.endsWith(".P7C"))
00496 return "application/pkcs7-mime";
00497
00498 if (file.endsWith(".JS"))
00499 return "application/x-javascript";
00500 if (file.endsWith(".Z"))
00501 return "application/x-compress";
00502 if (file.endsWith(".GZ"))
00503 return "application/x-gzip";
00504 if (file.endsWith(".TAR"))
00505 return "application/x-tar";
00506 if (file.endsWith(".TGZ"))
00507 return "application/x-compressed";
00508 if (file.endsWith(".ZIP"))
00509 return "application/x-zip-compressed";
00510 if (file.endsWith(".DIR") || file.endsWith(".DCR") || file.endsWith(".DXR"))
00511 return "application/x-director";
00512 if (file.endsWith(".DVI"))
00513 return "application/x-dvi";
00514 if (file.endsWith(".TEX"))
00515 return "application/x-tex";
00516 if (file.endsWith(".LATEX"))
00517 return "application/x-latex";
00518 if (file.endsWith(".TCL"))
00519 return "application/x-tcl";
00520 if (file.endsWith(".CER") || file.endsWith(".CRT") || file.endsWith(".DER"))
00521 return "application/x-x509-ca-cert";
00522
00523 if (file.endsWith(".MPG") || file.endsWith(".MPE") || file.endsWith(".MPEG"))
00524 return "video/mpeg";
00525 if (file.endsWith(".QT") || file.endsWith(".MOV"))
00526 return "video/quicktime";
00527 if (file.endsWith(".AVI"))
00528 return "video/x-msvideo";
00529 if (file.endsWith(".MOVIE"))
00530 return "video/x-sgi-movie";
00531
00532 if (file.endsWith(".PDB") || file.endsWith(".XYZ"))
00533 return "chemical/x-pdb";
00534
00535 if (file.endsWith(".ICE"))
00536 return "x-conference/x-cooltalk";
00537 if (file.endsWith(".WRL") || file.endsWith(".VRML"))
00538 return "x-world/x-vrml";
00539 if (file.endsWith(".WML"))
00540 return "text/vnd.wap.wml";
00541 if (file.endsWith(".WMLC"))
00542 return "application/vnd.wap.wmlc";
00543 if (file.endsWith(".WMLS"))
00544 return "text/vnd.wap.wmlscript";
00545 if (file.endsWith(".WMLSC"))
00546 return "application/vnd.wap.wmlscriptc";
00547 if (file.endsWith(".WBMP"))
00548 return "image/vnd.wap.wbmp";
00549
00550 return null;
00551 }
00552
00553 public int getMinorVersion() {
00554 return 3;
00555 }
00556
00557 public RequestDispatcher getNamedDispatcher(String name) {
00558 return this;
00559 }
00560
00561 public String getRealPath(String path) {
00562 return installPath + FileUtilities.convertFileNameToSystem(path);
00563
00564 }
00565
00566 public RequestDispatcher getRequestDispatcher(String path) {
00567 return this;
00568 }
00569
00570
00571 public URL getResource(String path) throws MalformedURLException {
00572 return new URL("http", hostName, port, path);
00573 }
00574
00575 public InputStream getResourceAsStream(String path) {
00576 return null;
00577 }
00578
00579 public java.util.Set getResourcePaths(java.lang.String path) {
00580
00581 return null;
00582 }
00583
00585
00586
00587 public String getServerInfo() {
00588 return Identification.serverName + " " + Identification.serverVersion + " (" + Identification.serverUrl + ")";
00589 }
00590
00591 public Servlet getServlet(String name) {
00592
00593
00594
00595
00596
00597
00598
00599 return null;
00600 }
00601
00608 public java.lang.String getServletContextName() {
00609 return null;
00610 }
00611
00613
00614
00615 public Enumeration getServletNames() {
00616
00617
00618
00619
00620 return new Vector().elements();
00621 }
00622
00623 public Enumeration getServlets() {
00624
00625
00626
00627
00628 return new Vector().elements();
00629 }
00630
00631 public void log(Exception exception, String msg) {
00632 LogManager.traceWarning(LogServices.WEBSERVICE, msg);
00633 LogManager.traceWarning(LogServices.WEBSERVICE, exception);
00634 }
00635
00636 public void log(String msg) {
00637 LogManager.traceWarning(LogServices.WEBSERVICE, msg);
00638 }
00639
00640 public void log(String message, Throwable throwable) {
00641 LogManager.traceWarning(LogServices.WEBSERVICE, message);
00642 LogManager.traceWarning(LogServices.WEBSERVICE, throwable);
00643 }
00644
00645 public void removeAttribute(String name) {
00646 attributes.remove(name);
00647 }
00648
00649 public void setAttribute(String name, Object object) {
00650 attributes.put(name, object);
00651 }
00652
00653
00654
00655
00656 public void forward(ServletRequest request, ServletResponse response) {
00657 }
00658
00659 public void include(ServletRequest request, ServletResponse response) {
00660 }
00661 }