001: /**
002: * The XMOJO Project 5
003: * Copyright © 2003 XMOJO.org. All rights reserved.
004:
005: * NO WARRANTY
006:
007: * BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
008: * THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
009: * OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
010: * PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
011: * OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
012: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
013: * TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE
014: * LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
015: * REPAIR OR CORRECTION.
016:
017: * IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
018: * ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
019: * THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
020: * GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
021: * USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF
022: * DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
023: * PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE),
024: * EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
025: * SUCH DAMAGES.
026: **/package com.adventnet.adaptors.html;
027:
028: import java.io.File;
029: import java.util.Collection;
030: import java.util.Iterator;
031: import java.util.Properties;
032: import java.util.Vector;
033: import java.net.URL;
034:
035: import com.adventnet.agent.logging.Log;
036: import com.adventnet.agent.logging.LogFactory;
037: import com.adventnet.agent.utilities.xml.XMLNode;
038: import com.adventnet.agent.utilities.xml.XMLDataReader;
039: import com.adventnet.agent.utilities.xml.XMLDataWriter;
040:
041: import org.mortbay.util.*;
042: import org.mortbay.jetty.*;
043: import org.mortbay.http.*;
044:
045: /**
046: * This class plugs in the Jetty WebServer to the HtmlAdaptor.
047: *
048: * @see HttpServerInterface
049: */
050: public class JettyHtmlServer implements HttpServerInterface {
051: private static final int defaultPortNumber = 8030;
052:
053: private String configFileName = "conf/http/etc/JettyConfig.xml";
054: private String jarConfig = "conf/http/etc/JarConfig.xml";
055:
056: private Properties props = null;
057: private boolean authentication = false;
058: private int port = defaultPortNumber;
059: private boolean isStarted = false;
060: private boolean sslSupport = false;
061: private boolean isJarFile = false;
062: private boolean fromSetPort = false;
063:
064: private Server server = null;
065:
066: private Log log = null;
067:
068: /**
069: * Primary constructor for the HttpServerImpl without any configuration options.
070: */
071: public JettyHtmlServer() {
072: this (defaultPortNumber, false, false, false);
073: }
074:
075: /**
076: * Secondary constructor with configuration options.
077: *
078: * Note: For this version, authentication is disabled and hence will not
079: * have any effect by setting authentication to true.
080: *
081: * @param port The port to start the WebServer
082: *
083: * @param authentication The boolean flag to turn ON/OFF
084: * Authentication of the Requests. Default is false.
085: */
086: public JettyHtmlServer(int port, boolean authentication) {
087: this (port, authentication, false, false);
088: }
089:
090: /**
091: * Constructor with configuration options.
092: *
093: * Note: For this version, authentication and SSL support are disabled and
094: * hence will not have any effect by setting true to those parameters.
095: *
096: * @param port The port to start the WebServer
097: *
098: * @param authentication The boolean flag to turn ON/OFF
099: * Authentication of the Requests. Default is false.
100: *
101: * @param sslSupport The boolean flag to turn ON/OFF SSL Support.
102: * Default is false.
103: */
104: public JettyHtmlServer(int port, boolean authentication,
105: boolean sslSupport) {
106: this (port, authentication, sslSupport, false);
107: }
108:
109: /**
110: * Constructor with configuration options.
111: *
112: * Note: For this version, authentication and SSL support are disabled and
113: * hence will not have any effect by setting true to those parameters.
114: *
115: * @param port The port to start the WebServer
116: *
117: * @param authentication The boolean flag to turn ON/OFF
118: * Authentication of the Requests. Default is false.
119: *
120: * @param sslSupport The boolean flag to turn ON/OFF SSL Support.
121: * Default is false.
122: *
123: * @param isJarFile Boolean flag to indicate configuration files taken from Jar.
124: */
125: public JettyHtmlServer(int port, boolean authentication,
126: boolean sslSupport, boolean isJarFile) {
127: log = getLogObject();
128: this .authentication = authentication;
129: this .sslSupport = sslSupport;
130: this .port = port;
131: this .isJarFile = isJarFile;
132:
133: if (!isJarFile) {
134: XMLDataReader xmld = new XMLDataReader(HtmlAdaptor
135: .getParentDirectory()
136: + File.separator + configFileName);
137: XMLNode rootNode = xmld.getRootNode();
138:
139: Vector vec = rootNode.getChildNodes();
140: changePort(rootNode, (new Integer(port)).toString());
141:
142: changeSSL(rootNode, sslSupport);
143: changeAgentDir(rootNode, HtmlAdaptor.getParentDirectory());
144:
145: XMLDataWriter xw = new XMLDataWriter(HtmlAdaptor
146: .getParentDirectory()
147: + File.separator + configFileName, rootNode);
148: }
149: }
150:
151: /**
152: * Setter for the configuration file Name with location.
153: *
154: * @param configFileName The configuration file name with path.
155: */
156: public void setConfigFileName(String configFileName) {
157: this .configFileName = configFileName;
158:
159: try {
160: restartHttpServer();
161: } catch (Exception ex) {
162: log.error("Exception", ex);
163: }
164: }
165:
166: /**
167: * Getter for the configFileName.
168: *
169: * @return The configuration file Name by which the Server is running.
170: */
171: public String getConfigFileName() {
172: return this .configFileName;
173: }
174:
175: /**
176: * Setter for the configuration file Name which will be inside the
177: * jar containing this class.
178: *
179: * @param jarConfig The configuration file name with path as in the jar File.
180: */
181: public void setConfigJarFile(String jarConfig) {
182: this .jarConfig = jarConfig;
183:
184: try {
185: restartHttpServer();
186: } catch (Exception ex) {
187: log.error("Exception", ex);
188: }
189: }
190:
191: /**
192: * Setter for the configuration file Name which will be inside the
193: * jar containing this class.
194: *
195: * @return The configuration file name by which the Server is running
196: * with path as in the jar File.
197: */
198: public String getConfigJarFile() {
199: return this .jarConfig;
200: }
201:
202: /**
203: * Returns the port number in which the http server gets started.
204: *
205: * @return the port number.
206: *
207: * @see setPort(Integer port)
208: */
209: public Integer getPort() {
210: return new Integer(port);
211: }
212:
213: /**
214: * Sets the port number in which the http server to get started.
215: *
216: * @param the port number of the http web-server.
217: *
218: * @see getPort()
219: */
220: public void setPort(Integer port) throws Exception {
221: setPort(port.intValue());
222: }
223:
224: /**
225: * Sets the port number in which the http server to get started.
226: *
227: * @param the port number of the http web-server.
228: *
229: * @see getPort()
230: */
231: public void setPort(int port) {
232: if (port < 0 || port > 65535) {
233: return;
234: }
235:
236: if (port != this .port) {
237: this .port = port;
238:
239: if (!isJarFile) {
240: XMLDataReader xmld = new XMLDataReader(HtmlAdaptor
241: .getParentDirectory()
242: + File.separator + configFileName);
243:
244: XMLNode rootNode = xmld.getRootNode();
245:
246: changePort(rootNode, String.valueOf(port));
247:
248: XMLDataWriter xw = new XMLDataWriter(HtmlAdaptor
249: .getParentDirectory()
250: + File.separator + configFileName, rootNode);
251: } else {
252: fromSetPort = true;
253: }
254:
255: //restart the Http server at the specified port
256: log
257: .info("applying the new port number by restarting the Http server");
258:
259: try {
260: restartHttpServer();
261: log.info("successfully changed to new port number");
262: } catch (Exception ex) {
263: log
264: .error(
265: "Exception while trying to change server port number",
266: ex);
267: log.fatal("Failed to change to new port number");
268: }
269: }
270: }
271:
272: /**
273: * Setter for enabling and disabling Authentication of the WebServer.
274: *
275: * Note: For this version, this is disabled and hence will not have
276: * any effect by calling this method.
277: *
278: * @param auth The flag for turning ON/OFF the authentication of WebServer.
279: */
280: public void setAuthentication(boolean auth) {
281: //this.authentication = auth;
282: this .authentication = false;
283: }
284:
285: /**
286: * To know whether the authentication is enabled in the WebServer.
287: *
288: * Note: For this version, this is disabled and hence will always return false.
289: *
290: * @return true if the authentication of the WebServer is turned ON else false.
291: */
292: public boolean isAuthentication() {
293: return this .authentication;
294: }
295:
296: /**
297: * This method adds a new User with the userName and password
298: * to the Authentication of the WebServer.
299: *
300: * Note: For this version, this is disabled and hence will not have
301: * any effect by calling this method.
302: *
303: * @param userName The user name to be added.
304: *
305: * @param password The password for the user.
306: */
307: public void addUser(String userName, String passwd) {
308: //this is not supported in this release
309: }
310:
311: /**
312: * Setter for enabling and disabling SSL Support of the WebServer.
313: *
314: * Note: For this version, this is disabled and hence will not have
315: * any effect by calling this method.
316: *
317: * @param sslSupport The flag for turning ON/OFF the SSL Support of WebServer.
318: */
319: public void setSslSupport(boolean sslSupport) {
320: //this.sslSupport = sslSupport;
321: this .sslSupport = false;
322: }
323:
324: /**
325: * To know whether the SSL Support is enabled in the WebServer.
326: *
327: * Note: For this version, this is disabled and hence will always return false.
328: *
329: * @return true if the SSL Support of the WebServer is turned ON else false.
330: */
331: public boolean isSslSupport() {
332: return this .sslSupport;
333: }
334:
335: /**
336: * Starts the HttpServer - Jetty WebServer.
337: *
338: * @see stopHttpServer()
339: *
340: * @exception Exception on error while starting WebServer.
341: */
342: public void startHttpServer() throws Exception {
343: System.setProperty("LOG_FILE", "logs/agent.log");
344: System.setProperty("LOG_CLASSES",
345: "org.mortbay.util.WriterLogSink");
346:
347: if (!isJarFile) {
348: server = new Server(HtmlAdaptor.getParentDirectory()
349: + File.separator + configFileName);
350: } else {
351: URL url = this .getClass().getResource("/" + jarConfig);
352: server = new Server(url);
353: if ((sslSupport) || (fromSetPort)) {
354: //removes the listener configured through xml file.
355: Collection lisCol = server.getListeners();
356: if (!(lisCol.isEmpty())) {
357: Iterator iter = lisCol.iterator();
358: if (iter.hasNext())
359: server.removeListener((HttpListener) iter
360: .next());
361: }
362:
363: if (!sslSupport) {
364: SocketListener socLis = new SocketListener(
365: new InetAddrPort(this .port));
366: server.addListener(socLis);
367: }
368: }
369: }
370:
371: server.start();
372: isStarted = true;
373: }
374:
375: /**
376: * Stops the WebServer.
377: *
378: * @exception Exception on error while stopping WebServer.
379: */
380: public void stopHttpServer() throws Exception {
381: server.stop();
382: isStarted = false;
383: }
384:
385: /**
386: * Restarts the WebServer.
387: *
388: * @exception Exception while error trying to restart the WebServer
389: */
390: public void restartHttpServer() throws Exception {
391: try {
392: stopHttpServer();
393: } catch (Exception ee) {
394: throw new Exception(
395: "Exception while stopping WebServer in restart");
396: }
397:
398: try {
399: startHttpServer();
400: } catch (Exception eee) {
401: throw new Exception(
402: "Exception while starting WebServer in restart");
403: }
404: }
405:
406: void changeAgentDir(XMLNode node, String agentDir) {
407: if (node.getNodeName().equals("Call")
408: && node.getAttributeList().get("name").equals(
409: "addContext")) {
410: XMLNode setNode = (XMLNode) node.getChildNodes().elementAt(
411: 1);
412:
413: if (setNode.getAttributeList().get("name").equals(
414: "ResourceBase")) {
415: XMLNode sysNode = (XMLNode) setNode.getChildNodes()
416: .elementAt(0);
417: sysNode.getAttributeList().put("default",
418: agentDir + "/conf/http/ssi");
419: return;
420: }
421:
422: }
423:
424: Vector childVec = node.getChildNodes();
425: if (childVec != null) {
426: int len = childVec.size();
427:
428: for (int i = 0; i < len; i++) {
429: changeAgentDir((XMLNode) childVec.elementAt(i),
430: agentDir);
431: }
432: }
433: }
434:
435: private boolean changeSSL(XMLNode node, boolean flag) {
436: if (node.getNodeName().equals("Call")
437: && node.getAttributeList().get("name").equals(
438: "addListener")) {
439: XMLNode argNode = (XMLNode) node.getChildNodes().elementAt(
440: 0);
441: XMLNode newNode = (XMLNode) argNode.getChildNodes()
442: .elementAt(0);
443:
444: if (flag) {
445: newNode.getAttributeList().put("class",
446: "org.mortbay.http.SunJsseListener");
447:
448: XMLNode setNode = null;
449:
450: Vector vec = newNode.getChildNodes();
451: int size = vec.size();
452: boolean keyStore = true;
453: boolean keyPassword = true;
454: boolean password = true;
455:
456: String keyStoreStr = null;
457: String keyPasswordStr = null;
458: String passwordStr = null;
459:
460: XMLDataReader myReader = new XMLDataReader(HtmlAdaptor
461: .getParentDirectory()
462: + File.separator
463: + "etc"
464: + File.separator
465: + "HtmlAdaptorSSLConf.xml");
466: XMLNode myConfigNode = myReader.getRootNode();
467: Vector configChilds = myConfigNode.getChildNodes();
468: int configSize = configChilds.size();
469: for (int j = 0; j < configSize; j++) {
470: XMLNode configChild = (XMLNode) configChilds.get(j);
471: if (configChild.getNodeName().equals("Store")
472: && configChild.getAttribute("name").equals(
473: "keyStore")) {
474: Vector properties = configChild.getChildNodes();
475: int propsSize = properties.size();
476: for (int k = 0; k < propsSize; k++) {
477: XMLNode prop = (XMLNode) properties.get(k);
478: String value = (String) prop
479: .getAttribute("name");
480: if (value.equals("Name")) {
481: keyStoreStr = (String) prop
482: .getAttribute("value");
483: } else if (value.equals("Password")) {
484: passwordStr = (String) prop
485: .getAttribute("value");
486: } else if (value.equals("Keypassword")) {
487: keyPasswordStr = (String) prop
488: .getAttribute("value");
489: }
490:
491: if (keyPasswordStr != null
492: && passwordStr != null
493: && keyStoreStr != null) {
494: break;
495: }
496: }
497: }
498: }
499:
500: Vector newNodeChilds = newNode.getChildNodes();
501: int newNodeChildSize = newNodeChilds.size();
502: for (int i = 0; i < newNodeChildSize; i++) {
503: XMLNode newNodeChild = (XMLNode) newNodeChilds
504: .get(i);
505: if (newNodeChild.getNodeName().equals("Set")) {
506: if (newNodeChild.getAttribute("name").equals(
507: "Keystore")) {
508: newNodeChild.removeFromParent();
509: } else if (newNodeChild.getAttribute("name")
510: .equals("Password")) {
511: newNodeChild.removeFromParent();
512: } else if (newNodeChild.getAttribute("name")
513: .equals("KeyPassword")) {
514: newNodeChild.removeFromParent();
515: } else if (newNodeChild.getAttribute("name")
516: .equals("ConfigFileName")) {
517: newNodeChild.removeFromParent();
518: }
519: }
520: }
521:
522: XMLNode addNode = new XMLNode();
523: addNode.setNodeType(XMLNode.ELEMENT);
524: addNode.setNodeName("Set");
525:
526: addNode.setAttribute("name", "Keystore");
527: addNode.setNodeValue("etc/adventnetkey");
528: newNode.addChildNode(addNode);
529:
530: addNode = new XMLNode();
531: addNode.setNodeType(XMLNode.ELEMENT);
532: addNode.setNodeName("Set");
533:
534: addNode.setAttribute("name", "KeyPassword");
535: addNode.setNodeValue("adventnet");
536: newNode.addChildNode(addNode);
537:
538: addNode = new XMLNode();
539: addNode.setNodeType(XMLNode.ELEMENT);
540: addNode.setNodeName("Set");
541:
542: addNode.setAttribute("name", "Password");
543: addNode.setNodeValue("adventnet");
544: if (password) {
545: newNode.addChildNode(addNode);
546: }
547: return true;
548: } else {
549: if (newNode.getAttributeList().get("class").equals(
550: "org.mortbay.http.SunJsseListener")) {
551: newNode.getAttributeList().put("class",
552: "org.mortbay.http.SocketListener");
553:
554: XMLNode setNode = null;
555: for (int i = 0; i < newNode.getChildNodes().size(); i++) {
556: setNode = (XMLNode) newNode.getChildNodes()
557: .elementAt(i);
558:
559: if (setNode.getAttributeList().get("name")
560: .equals("KeyPassword")
561: || setNode.getAttributeList().get(
562: "name").equals("Keystore")
563: || setNode.getAttributeList().get(
564: "name").equals("Password")) {
565: setNode.removeFromParent();
566: // return true;
567: }
568: }
569: }
570: }
571: }
572:
573: Vector childVec = node.getChildNodes();
574:
575: if (childVec != null) {
576: int len = childVec.size();
577: for (int i = 0; i < len; i++) {
578: if (changeSSL((XMLNode) childVec.elementAt(i), flag)) {
579: return true;
580: }
581: }
582: }
583:
584: return false;
585: }
586:
587: //this method changes the value of port in the config file
588: private void changePort(XMLNode node, String port) {
589: if (node.getNodeName().equals("Call")
590: && node.getAttributeList().get("name").equals(
591: "addListener")) {
592: XMLNode argNode = (XMLNode) node.getChildNodes().elementAt(
593: 0);
594: XMLNode newNode = (XMLNode) argNode.getChildNodes()
595: .elementAt(0);
596:
597: XMLNode setNode = null;
598:
599: for (int i = 0; i < newNode.getChildNodes().size(); i++) {
600: setNode = (XMLNode) newNode.getChildNodes()
601: .elementAt(i);
602:
603: if (setNode.getAttributeList().get("name").equals(
604: "Port")) {
605: setNode.setNodeValue(port);
606: return;
607: }
608: }
609: }
610:
611: Vector childVec = node.getChildNodes();
612: if (childVec != null) {
613: int len = childVec.size();
614:
615: for (int i = 0; i < len; i++) {
616: changePort((XMLNode) childVec.elementAt(i), port);
617: }
618: }
619: }
620:
621: private Log getLogObject() {
622: try {
623: log = LogFactory.getInstance("HTML");
624: } catch (InstantiationException ie) {
625: // ie.printStackTrace();
626: }
627:
628: return log;
629: }
630: }
|