KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > server > EnhydraServer


1 package org.enhydra.server;
2
3 import java.io.File JavaDoc;
4 import java.util.ArrayList JavaDoc;
5 import java.util.Date JavaDoc;
6 import java.util.Enumeration JavaDoc;
7 import java.util.HashMap JavaDoc;
8 import java.util.Hashtable JavaDoc;
9 import java.util.Iterator JavaDoc;
10
11 import javax.servlet.Servlet JavaDoc;
12
13 import org.enhydra.server.conf.EnhydraServerXML;
14 import org.enhydra.server.util.PathUtil;
15 import org.enhydra.server.util.UnpackWar;
16
17 import com.lutris.appserver.server.Application;
18 import com.lutris.appserver.server.httpPresentation.servlet.HttpPresentationServlet;
19 import com.lutris.appserver.server.session.MemoryPersistence;
20 import com.lutris.logging.LogChannel;
21 import com.lutris.logging.Logger;
22 import com.lutris.util.Config;
23
24 /**
25  * <p>Description:
26  * Class EnhydraServer use singleton pattern to provide
27  * all necessary data about registered (started) Enhydra applications.
28  * All application register itself on startup and unregister when shutdown.
29  * Admin application use this class to display applications info.
30  * Admin application should get instance of this class first, then calls
31  * public methods. Example:</p>
32  * <code>
33  * <p> EnhydraServer enhydraServer = EnhydraServer.getInstance();</p>
34  * <p> SessionsInfo sessInfo = enhydraServer.getSessionsInfo();</p>
35  * <p> String activeSessions = sessInfo.getActiveSessions();</p>
36  * ...
37  * </code>
38  *
39  *
40  * <p>Copyright: Copyright (c) 2002</p>
41  * <p>Company: www.together.at </p>
42  * @author Damir Milovic, damir@uns.ns.ac.yu
43  * @version 1.0
44  * @see <a HREF="SessionsInfo.html">SessionsInfo</a>
45  */

46 public class EnhydraServer {
47     /**
48      * Public static variables
49      */

50     // Strings used in config file names
51
public static final String JavaDoc APPS_DIR = "apps";
52     public static final String JavaDoc SERVER = "Server";
53     public static final String JavaDoc APPLICATION = "Application";
54     public static final String JavaDoc CONF_FILE = "ConfFile";
55     public static final String JavaDoc CONF_FILE_CLASS = "ConfFileClass"; // TJ 08.11.2003
56
public static final String JavaDoc DEFAULT_CONF_FILE_CLASS = "com.lutris.util.ConfigFile"; // TJ 08.11.2003
57

58     public static final String JavaDoc LOG_CLASS = "LogClassName"; // SM 08.11.2003
59
public static final String JavaDoc DEFAULT_LOG_CLASS = "com.lutris.logging.StandardLogger"; // SM 08.11.2003
60

61     public static final String JavaDoc SERVLET = "Servlet";
62     public static final String JavaDoc CLASS_NAME = "ClassName";
63     public static final String JavaDoc DOC_ROOT = "DocRoot";
64     public static final String JavaDoc DESCRIPTION = "Description";
65     public static final String JavaDoc RUNNING = "Running";
66     public static final String JavaDoc CLASS_PATH = "ClassPath";
67     public static final String JavaDoc INIT_ARGS = "InitArgs";
68     public static final String JavaDoc URL = "Url";
69     public static final String JavaDoc CONNECTION = "Connection";
70     public static final String JavaDoc ENABLED = "Enabled";
71     public static final String JavaDoc APP_CLASS = "AppClass";
72     public static final String JavaDoc PRESENTATION_PREFIX = "PresentationPrefix";
73     public static final String JavaDoc AUTO_RELOAD = "AutoReload";
74     public static final String JavaDoc SESSION_MANAGER = "SessionManager";
75     public static final String JavaDoc SESSION_MANAGER_KEY = "org.enhydra.session.manager";
76 // private static final String sysConLoggerName = "sysOut";
77

78     /**
79      * attributes in <application> tag in EnhydraServer.xml configuration file.
80      */

81     protected static final String JavaDoc APP_URLPATH = "URLPath"; //path to context root
82
protected static final String JavaDoc APP_CONTEXTPATH = "contextPath"; //context prefix for web application
83
protected static final String JavaDoc APP_NAME = "name";
84     protected static final String JavaDoc APP_DESCRIPTION = "description";
85     protected static final String JavaDoc APP_RUNNING = "running";
86     protected static final String JavaDoc APP_CONNECTIONS = "connections"; //Enabled connection ports
87
/**
88      * Singleton reference
89      */

90     private static EnhydraServer enhydraServer = null;
91     /**
92      * Where to find conf files
93      */

94     private static String JavaDoc appsDir = null;
95     /**
96      * All available application names
97      */

98     //private String appNames[];
99
/**
100      * All available applications (started or stopped) (key=appName, value=appInfo)
101      */

102     private Hashtable JavaDoc apps;
103     /**
104      * List of connection port numbers added by EnhydraServer
105      */

106     private ArrayList JavaDoc connectionPorts;
107     /**
108      * interface
109      */

110     private ApplicationServer applicationServer;
111     /**
112      * Hard coded EnhydraServer config file
113      */

114     private EnhydraServerXML serverConfig;
115     /**
116      * Flag that indicate is EnhydraServer started
117      */

118     private static boolean started = false;
119     /**
120      * Debug level
121      */

122     private int debug = 0;
123     
124     private static Logger standardLogger;
125     private static LogChannel logChannel = null;
126     
127
128     private EnhydraServer() {
129         // if there is no initialized root logger in log4j -> initialize root
130
// with NullAppender
131

132 //SINISA 25.11
133

134 /* if (server == null) {
135             fatalErr("No server section specified in config file "
136                     + configFileName);
137         }
138         // Very first thing is to establish the central logging object.
139         String logClassName = null;
140
141         try {
142             logClassName = server.getString(LOG_CLASS);
143         } catch (ConfigException e) {}
144         if (logClassName == null) {
145             logClassName = LOG_TYPE_STANDARD;
146         }
147         
148         /*
149          * Done bootstrapping. From here on out we may use logging.
150          */

151         
152 // try {
153
// standardLogger = (Logger) Class.forName(logClassName).getConstructor(new Class[] {Boolean.TYPE}).newInstance(new Object[] {new Boolean(true)});
154
// standardLogger.configure(server);
155
// } catch (Exception e) {
156
// fatalErr("Cannot set default logger for " + configFileName,
157
// e);
158
// }
159
if (Logger.getCentralLogger() != null)
160     logChannel = Logger.getCentralLogger().getChannel("Enhydra");
161
162 /* if (!Logger.getRootLogger().getAllAppenders().hasMoreElements()) {
163             LoggerRepository logRepository = Logger.getRootLogger().getLoggerRepository();
164             // set level for log error:
165             logRepository.setThreshold(Level.ERROR);
166             NullAppender nullAppender = new NullAppender();
167             Logger.getRootLogger().addAppender(nullAppender);
168         }
169
170         loggerSys = Logger.getLogger(sysConLoggerName);
171         ConsoleAppender conAppender = new ConsoleAppender(
172                 new PatternLayout("%d{ISO8601}: [%t] %C{1}, %p, %c: %m%n") );
173         loggerSys.addAppender(conAppender);
174         loggerSys.setLevel(Level.ERROR);// FIXME: change to INFO for distribution
175         // "enhydra" logger will be configured from conf file
176         logger = Logger.getLogger("enhydra");
177 */
}
178     /**
179      * Init Enhydra Server
180      */

181     private void init(){
182
183 // loggerSys.debug("init()");
184
logChannel.write(Logger.DEBUG, "init()");
185         apps = new Hashtable JavaDoc();
186         applicationServer = null;
187         connectionPorts = new ArrayList JavaDoc(0);
188     }
189     /**
190      * Enhydra applications (HttpPresentationServlet) call this method to obtain
191      * EnhydraServer instance.
192      * @return One and only instance (singleton pattern) of this class.
193      */

194     public static EnhydraServer getInstance(){
195         if (enhydraServer == null) {
196             enhydraServer = new EnhydraServer();
197             enhydraServer.init();
198         }
199         return enhydraServer;
200     }
201     /**
202      * This method is responsible starting applications
203      * defined in <code>EnhydraServer.conf</code> file.
204      * ApplicationServer call this method when all necessary application server
205      * initialization are done and <code>ApplicationServer</code> reference is setted.
206      */

207     public synchronized void startup(){
208         logChannel.write(Logger.INFO,"Startup Enhydraserver ...");
209         try{
210             String JavaDoc home = System.getProperty("enhydra.home");
211             //If appsDir not set, try from System property.
212
if(appsDir == null){
213
214                 File JavaDoc appsDirFile = new File JavaDoc(home,APPS_DIR);
215                 appsDir = appsDirFile.getAbsolutePath();
216             }
217             logChannel.write(Logger.DEBUG,"conf dir="+appsDir);
218             // Read config file 'EnhydraServer.xml'
219
File JavaDoc cFile = new File JavaDoc(home,"conf/EnhydraServer.xml");
220             serverConfig = new EnhydraServerXML(cFile.getAbsolutePath());
221
222             // add enhydra loggers from conf file
223
// todo: configure logger from separate xml file 17.03.2003
224
// PropertyConfigurator.configure(confDir+"EnhydraServer.conf");
225
// logger.debug("Logger configured");
226
// loggerSys.addAppender(logger.getAppender("enhydraAppender"));
227

228         }catch(Exception JavaDoc e){
229             logChannel.write(Logger.ALERT,"Fail to startup EnhydraServer", e);
230             return;
231         }
232
233         if (applicationServer == null){
234             logChannel.write(Logger.ERROR,"Can't startup EnhydraServer, applicationServer = null");
235             return;
236         }
237         if (started){
238             logChannel.write(Logger.WARNING,"EnhydraServer already started");
239             return;
240         }
241
242         try{
243
244             // Create AppInfo, put into hashtable and start application if running = true.
245

246 //17.03.2003 String[] appNames = null;
247
HashMap JavaDoc[] appsHash = serverConfig.getApplications();
248
249             String JavaDoc[] appNames = new String JavaDoc[appsHash.length];
250             for(int i=0;i<appsHash.length;i++){
251                 appNames[i] = (String JavaDoc) appsHash[i].get(APP_NAME);
252             }
253             if(appNames != null){
254                 for (int i=0;i<appNames.length;i++){
255                     // Create AppInfo
256
AppInfo appInfo = new AppInfo(appNames[i],appsHash[i]);
257                     apps.put(appNames[i],appInfo);
258                     logChannel.write(Logger.INFO,"add Application "+i+":"+appNames[i]);
259                     if(appInfo.isRunning()){
260                         appInfo.setRunning(false); //must cheat startApplication() method on startup
261
startApplication(appNames[i]); //startApplication() will call appInfo.setRunning(true);
262
}
263                 }
264             }
265         }catch (Exception JavaDoc e){
266             logChannel.write(Logger.ERROR,"... at startup():",e);
267             return;
268         }
269         started = true;
270         logChannel.write(Logger.INFO,"EnhydraServer is startup successfuly");
271     }
272
273     /**
274      * Enhydra Application (HttpPresentationServlet) register itself on startup.
275      * @param servlet only HttpPresentationServlet is currently supported.
276      */

277     public void register(Servlet JavaDoc servlet){//FIXME should be synchronized?
278
if (servlet == null){
279             logChannel.write(Logger.ERROR,"Unable to register application, servlet = NULL");
280             return;
281         }
282         AppInfo appInfo = null;
283         // Check is already registered?
284
// If application is already registered by ApplicationServer,
285
// just need to proceed Application interface, else make new appInfo
286
try{
287
288             AppInfo appInfoTemp = new AppInfo(servlet);
289             String JavaDoc appName = appInfoTemp.getName();
290             File JavaDoc urlPathTemp = new File JavaDoc(appInfoTemp.getUrlPath());
291             if(apps.containsKey(appName)){
292                 appInfo = ((AppInfo) apps.get(appName));
293                 // Check urlPath (if urlPaths are difrerent it is not the same application)
294
if(!urlPathTemp.equals(new File JavaDoc(appInfo.getUrlPath())))
295                     appInfo = null;
296             }
297             //try to find equal url path in other appInfos
298
//(maybe user change app name in EnhydraServer.conf)
299
if(appInfo==null){
300                 Enumeration JavaDoc keys = apps.keys();
301                 while(keys.hasMoreElements() && (appInfo==null)){
302                     appInfo = ((AppInfo) apps.get((String JavaDoc) keys.nextElement()));
303                     if(!urlPathTemp.equals(new File JavaDoc(appInfo.getUrlPath())))
304                         appInfo = null;
305                 }
306             }
307             //if appInfo found just set Application reference
308
if(appInfo != null){
309                 appInfo.setApplication(appInfoTemp.getApplication());
310             }else{
311                 // ApplicationServer didn't register this application
312
// this is a case when application server is unknown, and/or application is
313
// autostarted with application server (Servlet Container).
314
// In that case just put appInfo into apps hashtable, don't add
315
// application into EnhydraServer config
316
appInfo = appInfoTemp;
317                 appInfo.setDescription("Auto registered Enhydra application.");
318                 apps.put(appName, appInfo);
319             }
320             if(!appInfo.isRunning()){
321                 appInfo.setRunning(true);
322                 appInfo.setStarted(new Date JavaDoc());
323             }
324             logChannel.write(Logger.INFO,"Application "+appName+" successfuly registered");
325             }catch(Exception JavaDoc e) {logChannel.write(Logger.ERROR, "in register() ",e);}
326             return;
327     }
328     /**
329      * Enhydra Application unregister itself when stop.
330      * @param servlet usualy HttpPresentationServlet.
331      */

332     public void unRegister(Servlet JavaDoc servlet){
333         if (servlet instanceof HttpPresentationServlet){
334
335             String JavaDoc appName = ((HttpPresentationServlet) servlet).getApplication().getName();
336             if (appName != null){
337                 if(apps.containsKey(appName)){
338                     ((AppInfo) apps.get(appName)).setRunning(false);
339                     logChannel.write(Logger.INFO,"Application "+appName+" successfuly unregistered");
340                 }
341             }
342         }
343     }
344
345     /**
346      * Set path to default Applications context root path.
347      * Application context url can be relative against this path.
348      * @param dir absolute path to directory, where are application context reside.
349      */

350     public static void setAppsfDir(String JavaDoc dir){
351         appsDir = dir;
352     }
353
354     /**
355      * Get path to default Applications context root path.
356      * @return absolute path to directory, where are application context reside.
357      */

358     public String JavaDoc getAppsDir(){
359         return appsDir;
360     }
361
362     // Methods for reading application data -------------------------------------
363

364
365     /**
366      * @see <a HREF="AppInfo.html">AppInfo</a>
367      * @param appName application name.
368      * @return AppInfo contains all necessary application data.
369      */

370     public AppInfo getAppInfo(String JavaDoc appName){
371         AppInfo appInfo = (AppInfo)apps.get(appName);
372         if (appInfo == null){
373             logChannel.write(Logger.WARNING,"EnhydraServer: Can't get AppInfo,"+appName+" not registered");
374             return null;
375         }
376
377         return appInfo;
378     }
379
380     /**
381      * @see <a HREF="PresentationInfo.html">PresentationInfo</a>
382      * @param appName - application name
383      * @return PresentationInfo - JavaBean with getter methods
384      */

385     public PresentationInfo getPresentationInfo(String JavaDoc appName){
386         PresentationInfo presInfo = null;
387         Config config = null;
388         AppInfo appInfo = null;
389         Application app = null;
390         try{
391             if(apps.containsKey(appName)){
392
393                 appInfo = (AppInfo) apps.get(appName);
394                 app = appInfo.getApplication();
395                 config = (Config)appInfo.getConfig();
396                 if ( config!=null )
397                     if ( config.containsKey("PresentationManager"))
398                         config = (Config) config.getSection("PresentationManager");
399                 presInfo = new PresentationInfo(app,config);
400                 }else logChannel.write(Logger.WARNING,"Can't get PresentationInfo, "+appName+" don't exist!");
401         }
402         catch(Exception JavaDoc e) {
403             //FIXME maintain exceptions
404
logChannel.write(Logger.ERROR,"Exception in getPresentationInfo", e);
405         }
406         return presInfo;
407     }
408
409     /**
410      * @see <a HREF="SessionsInfo.html">SessionsInfo</a>
411      * @param appName - application name
412      * @return SessionInfo - JavaBean with getter methods
413      */

414     public SessionsInfo getSessionsInfo(String JavaDoc appName){
415         SessionsInfo sessInfo = null;
416         Config config = null;
417         AppInfo appInfo = null;
418         Application app = null;
419         try{
420             if(apps.containsKey(appName)){
421
422                 appInfo = (AppInfo) apps.get(appName);
423                 app = appInfo.getApplication();
424                 config = (Config)appInfo.getConfig();
425                 if ( config!=null )
426                     if ( config.containsKey("SessionManager")) config = (Config) config.getSection("SessionManager");
427                 sessInfo = new SessionsInfo(app,config);
428                 }else logChannel.write(Logger.ERROR,"Can't get SessionInfo, "+appName+" don't exist!");
429         }catch(Exception JavaDoc e){
430             //FIXME maintain exceptions
431
logChannel.write(Logger.ERROR,"Exception in getSessionInfo()",e);
432         }
433         return sessInfo;
434     }
435
436     /**
437      * @see <a HREF="SessionEdit.html">SessionEdit</a>
438      * @param appName applicatin name
439      * @return SessionEdit class for editing SessionManager parameters in conf file.
440      */

441     public SessionEdit getSessionEdit(String JavaDoc appName){
442         AppInfo appInfo = null;
443         SessionEdit sessEdit = null;
444         Config config = null;
445         try{
446             if(apps.containsKey(appName)){
447                 appInfo = (AppInfo) apps.get(appName);
448                 config = (Config)appInfo.getConfig();
449                 sessEdit = new SessionEdit(config);
450                 }else logChannel.write(Logger.WARNING,"Can't get SessionEdit, "+appName+" don't exist!");
451         }catch(Exception JavaDoc e){
452             //FIXME maintain exceptions
453
logChannel.write(Logger.ERROR,"Exception in getSessionEdit",e);
454         }
455         return sessEdit;
456     }
457
458     /**
459      * @see <a HREF="DatabaseInfo.html">SessionsInfo</a>
460      * @param appName - application name.
461      * @return DatabaseInfo - JavaBean with getter methods.
462      */

463     public DatabaseInfo getDatabaseInfo(String JavaDoc appName){
464         DatabaseInfo dbInfo = null;
465         Config config = null;
466         AppInfo appInfo = null;
467         Application app = null;
468         try{
469             if(apps.containsKey(appName)){
470
471                 appInfo = (AppInfo) apps.get(appName);
472                 app = appInfo.getApplication();
473                 config = (Config)appInfo.getConfig();
474                 if ( config!=null )
475 // VR if ( config.containsKey("DatabaseManager")) config = (Config) config.getSection("DatabaseManager");
476
dbInfo = new DatabaseInfo(app,config);
477                 }else logChannel.write(Logger.ERROR,"Can't get DatabaseInfo, "+appName+" don't exist!");
478         }catch(Exception JavaDoc e){
479             //FIXME maintain exceptions
480
logChannel.write(Logger.ERROR,"Exception in getDatabaseInfo",e);
481         }
482         return dbInfo;
483     }
484
485     /**
486      * Gets instasnce of DatabaseEdit class which is used in edditing of database
487      * parameters in configuration file of the application.
488      * @param appName the applicatin name.
489      * @return instasnce of DatabaseEdit class.
490      */

491     public DatabaseEdit getDatabaseEdit(String JavaDoc appName) {
492         AppInfo appInfo = null;
493         DatabaseEdit databaseEdit = null;
494         Config config = null;
495         try{
496             if(apps.containsKey(appName)){
497                 appInfo = (AppInfo) apps.get(appName);
498                 config = (Config)appInfo.getConfig();
499                 databaseEdit = new DatabaseEdit(config);
500             }
501             else logChannel.write(Logger.ERROR,"Can't get DatabaseEdit, "+appName+" don't exist!");
502         }
503         catch(Exception JavaDoc e) {
504             //FIXME maintain exceptions
505
logChannel.write(Logger.ERROR,"Exception in getDatabaseEdit",e);
506         }
507         return databaseEdit;
508     }
509
510     /**
511      *
512      * @return instance of class that implements ApplicationServer
513      */

514     public ApplicationServer getApplicationServer(){
515         if(applicationServer == null) logChannel.write(Logger.WARNING,"ApplicationServer = null");
516         return applicationServer;
517     }
518
519     /**
520      * Implementation of ApplicationServer interface are responsible
521      * to set reference on himself.
522      * @param appServ Implementation of ApplicationServer.
523      */

524     public void setApplicationServer(ApplicationServer appServ){
525         applicationServer = appServ;
526     }
527 //17.03.2003
528
/**
529      * Update EnhydraServer.xml document without save.
530      * @param appInfo application need to update
531      */

532     private void updateServerConfig(AppInfo appInfo){
533         HashMap JavaDoc appHash = new HashMap JavaDoc();
534         //Required attributes
535
appHash.put(APP_CONTEXTPATH, appInfo.getContextPath());
536         //Make relative URLPath if path is inside apps dir
537
appHash.put(APP_URLPATH, PathUtil.makeRelativePath(appsDir, appInfo.getUrlPath()));
538         appHash.put(APP_NAME, appInfo.getName());
539         if(appInfo.isRunning()){
540             appHash.put(APP_RUNNING, "true");
541         }else{
542             appHash.put(APP_RUNNING, "false");
543         }
544         appHash.put(APP_DESCRIPTION,appInfo.getDescription());
545         int[] conns = appInfo.getConnections();
546         String JavaDoc connections = "";
547         if(conns != null){
548             for(int i=0; i<conns.length; i++){
549                 if(i==0){
550                     connections = Integer.toString(conns[i]);
551                 }else{
552                     connections += ","+Integer.toString(conns[i]);
553                 }
554             }
555         }
556         appHash.put(APP_CONNECTIONS, connections);
557         //Update
558
if(serverConfig.getApplication(appInfo.getContextPath()) != null){
559             serverConfig.removeApplication(appInfo.getContextPath());
560         }
561         serverConfig.addApplication(appHash);
562     }
563     /**
564      * Save state of EnhydraServer into xml config file
565      * @return TRUE if OK, else FALSE.
566      */

567     public boolean saveState(){
568         boolean isOK = true;
569         logChannel.write(Logger.WARNING,"Saving current EnhydraServer config state ...");
570         try{
571             //17.03.2003
572
// ConfigFileInterface confFile = serverConfig.getConfigFile();
573
// confFile.write();
574
serverConfig.saveDocument();
575         }catch(Exception JavaDoc e){
576             logChannel.write(Logger.WARNING,"Can't write EnhydraServer.conf file",e);
577             isOK = false;
578         }
579         return isOK;
580     }
581
582     /**
583      * Start application.
584      * @param appName application name.
585      * @return OK if application successfuly started, else FALSE.
586      */

587     public boolean startApplication(String JavaDoc appName){
588
589         AppInfo appInfo = (AppInfo) apps.get(appName);
590         logChannel.write(Logger.INFO,"Starting "+appName+" at context path ="+appInfo.getContextPath()+", URL path = "+ appInfo.getUrlPath());
591         if (appInfo == null){
592             logChannel.write(Logger.INFO,"Can't start application, invalid application name: "+appName);
593             return false;
594         }
595         if (appInfo.isRunning()){
596             logChannel.write(Logger.WARNING,"Can't start application : "+appName+", already started");
597             return false;
598         }
599         if (applicationServer == null){
600             logChannel.write(Logger.ERROR,"Can't start application, Unknown Application Server");
601             return false;
602         }
603         if (!applicationServer.startApp(appName)){
604             logChannel.write(Logger.ERROR,"Can't start application, ApplicationServer.startApp() FAIL");
605             return false;
606         }
607         // if all OK, change AppInfo and config file but not save.
608
try{
609             appInfo.getWebAppXML().reloadDocument(); //reload web.xml (maybe is manualy changed) 21.03.2003
610
appInfo.setRunning(true);
611             appInfo.setStarted(new Date JavaDoc());
612             /** Next line is for standard Web applications,
613              * Enhydra application will register itself anyway.
614              */

615             //startedApps.put(appName,appInfo);
616
//ConfigFileInterface confFile = serverConfig.getConfigFile();
617
//17.03.2003
618
//serverConfig.set("Application."+appName+".Running",new Boolean(true));
619
//update serverConfig (EnhydraServer.xml)
620
updateServerConfig(appInfo);
621         }catch(Exception JavaDoc e){
622             logChannel.write(Logger.WARNING,"Application started but fail to change EnhydraServer.conf",e);
623         }
624
625         return true;
626     }
627     /**
628      * Shutdown application.
629      * @param appName application name.
630      * @return OK if application successfuly stopped, else FALSE.
631      */

632     public boolean stopApplication(String JavaDoc appName){
633         // FIXME ...
634
AppInfo appInfo = (AppInfo) apps.get(appName);
635         if (appInfo == null){
636             logChannel.write(Logger.ERROR,"Can't stop application, invalid application name: "+appName);
637             return false;
638         }
639         if (!appInfo.isRunning()){
640             logChannel.write(Logger.ERROR,"Can't stop application : "+appName+", not started");
641             return false;
642         }
643         if (applicationServer == null){
644             logChannel.write(Logger.ERROR,"Can't stop application, Unknown Application Server");
645             return false;
646         }
647         if (!applicationServer.stopApp(appName)){
648             logChannel.write(Logger.ERROR,"Can't stop application, ApplicationServer.stopApp() FAIL");
649             return false;
650         }
651         //If everything OK, remove it from startedApps
652
//if(startedApps.containsKey(appName)) startedApps.remove(appName);
653
try{
654             appInfo.setRunning(false);
655             appInfo.setStarted(null);//Remove old Date
656
//serverConfig.set("Application."+appName+".Running",new Boolean(false));
657
updateServerConfig(appInfo);
658         }catch(Exception JavaDoc e){
659             logChannel.write(Logger.WARNING,"Application stopped but fail to change EnhydraServer.conf",e);
660         }
661         return true;
662     }
663     /**
664      * Shutdown application server
665      */

666     public void stopApplicationServer(){
667         if (applicationServer == null)
668             logChannel.write(Logger.ERROR,"Can't shutdown application server, applicationServer = null");
669         else{
670             applicationServer.stop();
671             logChannel.write(Logger.INFO,applicationServer.getName()+" stopped");
672         }
673     }
674     /**
675      * Shutdown EnhydraServer, including all applications and connections.
676      */

677     public synchronized void shutdown(){
678         logChannel.write(Logger.INFO,"Shuting down EnhydraServer...");
679         //Stop all applications started by EnhydraServer
680
Enumeration JavaDoc enumApps = apps.keys();
681         String JavaDoc appName;
682         AppInfo appInfo;
683         while(enumApps.hasMoreElements()){
684             appName = (String JavaDoc)enumApps.nextElement();
685             appInfo = (AppInfo)apps.get(appName);
686             if(appInfo.isRunning()) stopApplication(appName);
687         }
688 // Do not remove 07.04.2003 //Remove all connection added to ApplicationServer by EnhydraServer
689
// String port;
690
// while(!connectionPorts.isEmpty()){
691
// port = (String)connectionPorts.remove(0);
692
// removeConnection(port);
693
// }
694
logChannel.write(Logger.INFO,"EnhydraServer is shutdown !");
695         MemoryPersistence.shutdown(); //Clean sessions from memory
696
apps = new Hashtable JavaDoc();
697         connectionPorts = new ArrayList JavaDoc(0);
698         started = false;
699     }
700
701     /**
702      * Add (create) connection to application server.
703      * Admin Presentation should first check available types, before call this method.
704      * @param type Connection type ("http","ajp",..) depends on Application Server.
705      * @param port Port nubber.
706      * @return TRUE if connection added successfuly.
707      */

708     public boolean addConnection(String JavaDoc type, String JavaDoc port){
709         if (applicationServer == null){
710             logChannel.write(Logger.WARNING,"Can't add connection, applicationServer = null !");
711             return false;
712         }
713
714         if (applicationServer.addConnection(type,port)){
715             connectionPorts.add(port);
716             logChannel.write(Logger.INFO,"Connection ("+port+","+type+") added.");
717             return true;
718         }
719         return false;
720     }
721
722     /**
723      * Add (create) connection to application server.
724      * @param type Connection type ("http","ajp","https"..) depends on Application Server.
725      * @param port Port nubber.
726      * @param password for "https" required.
727      * @param pathToKeyStoreFile absolute path to KeyStore file for "https" required.
728      * @return
729      */

730     public boolean addConnection(String JavaDoc type, String JavaDoc port, String JavaDoc password, String JavaDoc pathToKeyStoreFile){
731         if (applicationServer == null){
732             logChannel.write(Logger.WARNING,"Can't add connection, applicationServer = null !");
733             return false;
734         }
735         if (applicationServer.addConnection(type, port, password, pathToKeyStoreFile)){
736             connectionPorts.add(port);
737             logChannel.write(Logger.INFO,"Connection ("+port+","+type+") added.");
738             return true;
739         }
740         return false;
741     }
742
743     public boolean removeConnection(String JavaDoc port){
744         if (applicationServer == null){
745             logChannel.write(Logger.WARNING,"Can't remove connection, applicationServer = null !");
746             return false;
747         }
748         if (applicationServer.removeConnection(port)){
749             try{
750                 connectionPorts.remove(port);
751 //13.03.2003 no more Server.Connection in config
752
// serverConfig.remove("Server.Connection.Port"+port);
753
// logger.info("Connection "+port+" removed.");
754
}catch(Exception JavaDoc e){
755                 logChannel.write(Logger.WARNING,"Fail to remove connection from config!",e);
756             }
757             return true;
758         }
759         return false;
760     }
761
762     /**
763      * Enable connection to the application on port number.
764      * @param appName application name.
765      * @param portNumber port number of corresponding connection.
766      * @return TRUE if connection successfuly enabled, else FALSE.
767      */

768     public boolean enableConnection(String JavaDoc appName, String JavaDoc portNumber){
769         //String enabledConns[];
770
//String enabledConnsNew[];
771
//String connsKey = "Application."+appName+".Connections";
772
AppInfo appInfo = ((AppInfo) apps.get(appName));
773         int enablePort = Integer.parseInt(portNumber);
774         int[] connections = appInfo.getConnections();
775         int[] newConnections = null;
776         if(connections == null){
777             newConnections = new int[1];
778             newConnections[0] = enablePort;
779         }else{
780             newConnections = new int[connections.length+1];
781             newConnections[0] = enablePort;
782             for(int i=0; i<connections.length; i++){
783                 if(connections[i] == enablePort){
784                     logChannel.write(Logger.DEBUG,"Connection on port: "+portNumber+"allready enabled for application "+appName);
785                     return false;
786                 }
787                 newConnections[i+1] = connections[i];
788             }
789         }
790         appInfo.setConnections(newConnections);
791         updateServerConfig(appInfo);
792         logChannel.write(Logger.INFO,"Connection on port: "+portNumber+" enabled for application "+appName);
793         return true;
794     }
795
796     /**
797      * Disable connection to the application on port number.
798      * @param appName application name.
799      * @param portNumber port number of corresponding connection.
800      * @return TRUE if connection successfuly disabled, else FALSE.
801      */

802     public boolean disableConnection(String JavaDoc appName, String JavaDoc portNumber){
803         //String enabledConns[];
804
//String enabledConnsNew[];
805
//String connsKey = "Application."+appName+".Connections";
806
ArrayList JavaDoc enabledConnsList = new ArrayList JavaDoc(0);
807         AppInfo appInfo = ((AppInfo) apps.get(appName));
808         int disablePort = Integer.parseInt(portNumber);
809         int[] connections = appInfo.getConnections();
810
811         if(connections != null){
812             for(int i=0; i<connections.length; i++){
813                 if(connections[i] != disablePort){
814                     enabledConnsList.add(Integer.toString(connections[i]));
815                 }
816             }
817         }
818         Object JavaDoc[] objs = enabledConnsList.toArray();
819         connections = new int[objs.length];
820         //Object[] --> int[], new connections
821
for(int i=0;i<objs.length;i++){
822             connections[i] = Integer.parseInt((String JavaDoc) objs[i]);
823         }
824         appInfo.setConnections(connections);
825         updateServerConfig(appInfo);
826         logChannel.write(Logger.INFO,"Connection on port: "+portNumber+" disabled for application "+appName);
827         return true;
828     }
829
830     /**
831      * Method used by EnhydraPortFilter, provides list of enabled ports
832      * for given application name.
833      * @param appName Application name.
834      * @return Array of enabled port numbers .
835      */

836     public String JavaDoc[] getEnabledConnections(String JavaDoc appName){
837         AppInfo appInfo = ((AppInfo) apps.get(appName));
838
839         String JavaDoc[] enabledPorts = null;
840         int[] connections = appInfo.getConnections();
841         if(connections != null){
842             enabledPorts = new String JavaDoc[connections.length];
843             for(int i=0; i<connections.length; i++){
844                 enabledPorts[i] = Integer.toString(connections[i]);
845             }
846         }
847         return enabledPorts;
848     }
849
850     /**
851      * This method should be call for editing application config file.
852      * @param appName application name
853      * @return application Config object.
854      * @see com.lutris.util.Config
855      */

856     public Config getAppConfig(String JavaDoc appName){
857         AppInfo ai = (AppInfo) apps.get(appName);
858         if(ai==null){
859             logChannel.write(Logger.WARNING,"Application "+appName+" not available!");
860             return null;
861         }
862         return ai.getConfig();
863     }
864     /**
865      * @return names of all available applications
866      */

867     public String JavaDoc[] getAppNames(){
868         // Get application names
869
String JavaDoc[] appNames = null;
870         try{
871             //appNames = serverConfig.getSection("Application").keys();
872
Enumeration JavaDoc enumKeys = apps.keys();
873             if(enumKeys != null){
874                 appNames = new String JavaDoc[apps.size()];
875                 for(int i=0;enumKeys.hasMoreElements();i++){
876                     appNames[i] = (String JavaDoc) enumKeys.nextElement();
877                 }
878             }
879             }catch(Exception JavaDoc e){ logChannel.write(Logger.ERROR,"Exception in getAppNames",e);}
880             return appNames;
881     }
882
883     public EnhydraServerXML getConfig(){
884         return serverConfig;
885     }
886
887     /**
888      * Adds new application to Enhydra server
889      * @param appName application name.
890      * @param contextPath context path ( e.g. '/myapp')
891      * @param urlPath url path file (application root directory or path to war file).
892      * If path is relative it is resolved against <code>%ENHYDRA_HOME/apps</code> directory.
893      * @param description application description not required.
894      * @return <code>true</code> if application added successfuly, else <code>false</code>.
895      */

896
897     public boolean addApplication(String JavaDoc appName, String JavaDoc contextPath, String JavaDoc urlFilePath,String JavaDoc description){
898         String JavaDoc message = null;
899         HashMap JavaDoc appHash = new HashMap JavaDoc();
900         String JavaDoc urlPath = null;
901         urlFilePath = PathUtil.makeAbsolutePath(getAppsDir(), urlFilePath);
902         
903         File JavaDoc urlFile = new File JavaDoc(urlFilePath);
904         if(appName == null){
905             logChannel.write(Logger.ERROR,"Couldn't add application, application name = null");
906             return false;
907         }
908         appName.trim(); //cut redutant spaces
909
if(appName.equals("")){
910             logChannel.write(Logger.ERROR,"Couldn't add application, application name = \"\"");
911             return false;
912         }
913         //Check is file exist
914
if(!urlFile.exists()){
915             logChannel.write(Logger.ERROR,"Couldn't add "+appName+". URL Path file:'"+urlFilePath+"' don't exist!");
916             return false;
917         }
918         if(urlFile.isDirectory()){
919             urlPath = urlFilePath;
920             //chech is application with one of given parameters allready exist
921
if(!checkApplication(appName,contextPath, urlPath)){
922                 return false;
923             }
924         }else if(urlFile.isFile()){
925             // make urlPath from file name (just cut '.war');
926
String JavaDoc fileName = urlFile.getName();
927             urlPath = fileName.substring(0, fileName.length()-4);
928             //chech is application with one of given parameters allready exist before unpack
929
if(!checkApplication(appName,contextPath, urlPath)){
930                 return false;
931             }
932             //Unpack war to apps directory
933
UnpackWar unpack = new UnpackWar(urlFilePath, PathUtil.makeAbsolutePath(getAppsDir(),urlPath));
934             try{
935             unpack.execute();
936             }catch(Exception JavaDoc e){
937                 logChannel.write(Logger.ERROR,"Couldn't add "+appName+"!", e);
938                 return false;
939             }
940         }
941
942
943         if(!contextPath.startsWith("/")){
944             logChannel.write(Logger.ERROR,"Couldn't add "+appName+". Context path must start with '/'!");
945             return false; //exception
946
}else{
947             appHash.put(APP_CONTEXTPATH, contextPath);
948         }
949
950         if (apps.get(appName)!= null){
951             message = "Couldn't add "+appName+". Application "+appName+" already exist!";
952             logChannel.write(Logger.WARNING,message);
953             return false;
954         }else{
955             appHash.put(APP_NAME, appName);
956         }
957         appHash.put(APP_URLPATH, urlPath);
958         appHash.put(APP_DESCRIPTION, description);
959         appHash.put(APP_RUNNING, "false");
960
961         try{
962             AppInfo appInfo = new AppInfo(appName, appHash);
963             apps.put(appName,appInfo);
964             updateServerConfig(appInfo);
965         }catch(Exception JavaDoc e){
966             logChannel.write(Logger.ERROR,"ERROR in EnhydraServer.addApplication",e);
967             return false;
968         }
969
970         return true;
971     }
972
973     /**
974      * Check application parameters allready exist.
975      * @param appName application name.
976      * @param contextPath context path.
977      * @param urlPath url path file.
978      * @return <code>true</code> if application don't exist, otherwise <code>false</code>.
979      */

980     private boolean checkApplication(String JavaDoc appName, String JavaDoc contextPath, String JavaDoc urlPath){
981         Iterator JavaDoc iter = apps.values().iterator();
982         AppInfo appInfo = null;
983         String JavaDoc message = null;
984         boolean notExist = true;
985         while( iter.hasNext()){
986             appInfo = (AppInfo)iter.next();
987             // check name
988
if(appInfo.getName().equalsIgnoreCase(appName)){
989                 message = "Application name '"+appName+"' allready exist!";
990                 notExist = false;
991                 break;
992             }
993             // check context path
994
if(appInfo.getContextPath().equalsIgnoreCase(contextPath)){
995                 message = "Application contextPath '"+appName+"' allready exist!";
996                 notExist = false;
997                 break;
998             }
999             // check url path, compare absolute paths
1000
urlPath = PathUtil.makeAbsolutePath(getAppsDir(), urlPath);
1001            if(PathUtil.makeAbsolutePath(getAppsDir(), appInfo.getUrlPath()).equalsIgnoreCase(urlPath)){
1002                message = "Application urlPath '"+urlPath+"' allready exist!";
1003                notExist = false;
1004                break;
1005            }
1006        }
1007        if(!notExist){
1008            logChannel.write(Logger.ERROR,message);
1009        }
1010        return notExist;
1011    }
1012
1013    /**
1014     * Remove application from Enhydra Server.
1015     * @param appName application name.
1016     * @return true if application removing was successful.
1017     */

1018    public boolean removeApplication(String JavaDoc appName){
1019        if(!apps.containsKey(appName)){
1020            logChannel.write(Logger.WARNING,"in removeApplication(): "+appName+" don't exist!");
1021            return false;
1022        }
1023        AppInfo appInfo = (AppInfo) apps.get(appName);
1024        if (appInfo.isRunning()){
1025            if(!stopApplication(appName)){
1026                return false;
1027            }
1028        }
1029
1030            apps.remove(appName);
1031            // remove from config file
1032
serverConfig.removeApplication(appInfo.getContextPath());
1033
1034        logChannel.write(Logger.INFO,"Application "+appName+" removed successfuly.");
1035        return true;
1036    }
1037    /**
1038     * AdminGui should call this method to check is EnhydraServer started
1039     * @return true if EnhydraServer started
1040     */

1041    public boolean isStarted(){
1042        return started;
1043    }
1044}
Popular Tags