Source Code Cross Referenced for EnhydraServer.java in  » J2EE » Enhydra-Application-Framework » org » enhydra » server » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » Enhydra Application Framework » org.enhydra.server 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package org.enhydra.server;
0002:
0003:        import java.io.File;
0004:        import java.util.ArrayList;
0005:        import java.util.Date;
0006:        import java.util.Enumeration;
0007:        import java.util.HashMap;
0008:        import java.util.Hashtable;
0009:        import java.util.Iterator;
0010:
0011:        import javax.servlet.Servlet;
0012:
0013:        import org.enhydra.server.conf.EnhydraServerXML;
0014:        import org.enhydra.server.util.PathUtil;
0015:        import org.enhydra.server.util.UnpackWar;
0016:
0017:        import com.lutris.appserver.server.Application;
0018:        import com.lutris.appserver.server.httpPresentation.servlet.HttpPresentationServlet;
0019:        import com.lutris.appserver.server.session.MemoryPersistence;
0020:        import com.lutris.logging.LogChannel;
0021:        import com.lutris.logging.Logger;
0022:        import com.lutris.util.Config;
0023:
0024:        /**
0025:         * <p>Description:
0026:         * Class EnhydraServer use singleton pattern to provide
0027:         * all necessary data about registered (started) Enhydra applications.
0028:         * All application register itself on startup and unregister when shutdown.
0029:         * Admin application use this class to display applications info.
0030:         * Admin application should get instance of this class first, then calls
0031:         * public methods. Example:</p>
0032:         * <code>
0033:         * <p> EnhydraServer enhydraServer = EnhydraServer.getInstance();</p>
0034:         * <p> SessionsInfo sessInfo = enhydraServer.getSessionsInfo();</p>
0035:         * <p> String activeSessions = sessInfo.getActiveSessions();</p>
0036:         *   ...
0037:         * </code>
0038:         *
0039:         *
0040:         * <p>Copyright: Copyright (c) 2002</p>
0041:         * <p>Company: www.together.at </p>
0042:         * @author Damir Milovic, damir@uns.ns.ac.yu
0043:         * @version 1.0
0044:         * @see <a href="SessionsInfo.html">SessionsInfo</a>
0045:         */
0046:        public class EnhydraServer {
0047:            /**
0048:             * Public static variables
0049:             */
0050:            // Strings used in config file names
0051:            public static final String APPS_DIR = "apps";
0052:            public static final String SERVER = "Server";
0053:            public static final String APPLICATION = "Application";
0054:            public static final String CONF_FILE = "ConfFile";
0055:            public static final String DEFAULT_CONF_FILE = "web.xml";
0056:            public static final String CONF_FILE_CLASS = "ConfFileClass"; // TJ 08.11.2003
0057:            public static final String DEFAULT_CONF_FILE_CLASS = "org.enhydra.util.XMLConfigFile"; // TJ 08.11.2003    
0058:
0059:            public static final String LOG_CLASS = "LogClassName"; // SM 08.11.2003
0060:            public static final String DEFAULT_LOG_CLASS = "com.lutris.logging.StandardLogger"; // SM 08.11.2003    
0061:
0062:            public static final String SERVLET = "Servlet";
0063:            public static final String CLASS_NAME = "ClassName";
0064:            public static final String DOC_ROOT = "DocRoot";
0065:            public static final String DESCRIPTION = "Description";
0066:            public static final String RUNNING = "Running";
0067:            public static final String CLASS_PATH = "ClassPath";
0068:            public static final String INIT_ARGS = "InitArgs";
0069:            public static final String URL = "Url";
0070:            public static final String CONNECTION = "Connection";
0071:            public static final String ENABLED = "Enabled";
0072:            public static final String APP_CLASS = "AppClass";
0073:            public static final String PRESENTATION_PREFIX = "PresentationPrefix";
0074:            public static final String AUTO_RELOAD = "AutoReload";
0075:            public static final String SESSION_MANAGER = "SessionManager";
0076:            public static final String SESSION_MANAGER_KEY = "org.enhydra.session.manager";
0077:            //    private static final String sysConLoggerName = "sysOut";
0078:
0079:            /**
0080:             * attributes in <application> tag in EnhydraServer.xml configuration file.
0081:             */
0082:            protected static final String APP_URLPATH = "URLPath"; //path to context root
0083:            protected static final String APP_CONTEXTPATH = "contextPath"; //context prefix for web application
0084:            protected static final String APP_NAME = "name";
0085:            protected static final String APP_DESCRIPTION = "description";
0086:            protected static final String APP_RUNNING = "running";
0087:            protected static final String APP_CONNECTIONS = "connections"; //Enabled connection ports
0088:            /**
0089:             * Singleton reference
0090:             */
0091:            private static EnhydraServer enhydraServer = null;
0092:            /**
0093:             * Where to find conf files
0094:             */
0095:            private static String appsDir = null;
0096:            /**
0097:             * All available application names
0098:             */
0099:            //private String appNames[];
0100:            /**
0101:             * All available applications (started or stopped) (key=appName, value=appInfo)
0102:             */
0103:            private Hashtable apps;
0104:            /**
0105:             * List of connection port numbers added by EnhydraServer
0106:             */
0107:            private ArrayList connectionPorts;
0108:            /**
0109:             * interface
0110:             */
0111:            private ApplicationServer applicationServer;
0112:            /**
0113:             * Hard coded EnhydraServer config file
0114:             */
0115:            private EnhydraServerXML serverConfig;
0116:            /**
0117:             * Flag that indicate is EnhydraServer started
0118:             */
0119:            private static boolean started = false;
0120:            /**
0121:             * Debug level
0122:             */
0123:            //    private int debug = 0;
0124:            //    private static Logger      standardLogger;
0125:            private static LogChannel logChannel = null;
0126:
0127:            private EnhydraServer() {
0128:                // if there is no initialized root logger in log4j -> initialize root
0129:                // with NullAppender
0130:
0131:                //SINISA 25.11
0132:
0133:                /*        if (server == null) {
0134:                 fatalErr("No server section specified in config file "
0135:                 + configFileName);
0136:                 }
0137:                 // Very first thing is to establish the central logging object.
0138:                 String logClassName = null;
0139:
0140:                 try {
0141:                 logClassName = server.getString(LOG_CLASS);
0142:                 } catch (ConfigException e) {}
0143:                 if (logClassName == null) {
0144:                 logClassName = LOG_TYPE_STANDARD;
0145:                 }
0146:                
0147:                 /*
0148:                 * Done bootstrapping. From here on out we may use logging.
0149:                 */
0150:
0151:                //        try {
0152:                //            standardLogger = (Logger) Class.forName(logClassName).getConstructor(new Class[] {Boolean.TYPE}).newInstance(new Object[] {new Boolean(true)});
0153:                //            standardLogger.configure(server);
0154:                //        } catch (Exception e) {
0155:                //            fatalErr("Cannot set default logger for " + configFileName,
0156:                //                    e);
0157:                //        }            
0158:                if (Logger.getCentralLogger() != null)
0159:                    logChannel = Logger.getCentralLogger()
0160:                            .getChannel("Enhydra");
0161:
0162:                /*        if (!Logger.getRootLogger().getAllAppenders().hasMoreElements()) {
0163:                 LoggerRepository logRepository = Logger.getRootLogger().getLoggerRepository();
0164:                 // set level for log error:
0165:                 logRepository.setThreshold(Level.ERROR);
0166:                 NullAppender nullAppender = new NullAppender();
0167:                 Logger.getRootLogger().addAppender(nullAppender);
0168:                 }
0169:
0170:                 loggerSys = Logger.getLogger(sysConLoggerName);
0171:                 ConsoleAppender conAppender = new ConsoleAppender(
0172:                 new PatternLayout("%d{ISO8601}: [%t] %C{1}, %p, %c: %m%n") );
0173:                 loggerSys.addAppender(conAppender);
0174:                 loggerSys.setLevel(Level.ERROR);// FIXME: change to INFO for distribution
0175:                 // "enhydra" logger will be configured from conf file
0176:                 logger = Logger.getLogger("enhydra");
0177:                 */}
0178:
0179:            /**
0180:             * Init Enhydra Server
0181:             */
0182:            private void init() {
0183:
0184:                //        loggerSys.debug("init()");
0185:                logChannel.write(Logger.DEBUG, "init()");
0186:                apps = new Hashtable();
0187:                applicationServer = null;
0188:                connectionPorts = new ArrayList(0);
0189:            }
0190:
0191:            /**
0192:             * Enhydra applications (HttpPresentationServlet) call this method to obtain
0193:             * EnhydraServer instance.
0194:             * @return One and only instance (singleton pattern) of this class.
0195:             */
0196:            public static EnhydraServer getInstance() {
0197:                if (enhydraServer == null) {
0198:                    enhydraServer = new EnhydraServer();
0199:                    enhydraServer.init();
0200:                }
0201:                return enhydraServer;
0202:            }
0203:
0204:            /**
0205:             * This method is responsible starting applications
0206:             * defined in <code>EnhydraServer.conf</code> file.
0207:             * ApplicationServer  call this method when all necessary application server
0208:             * initialization are done and <code>ApplicationServer</code> reference is setted.
0209:             */
0210:            public synchronized void startup() {
0211:                logChannel.write(Logger.INFO, "Startup Enhydraserver ...");
0212:                try {
0213:                    String home = System.getProperty("enhydra.home");
0214:                    //If appsDir not set, try from System property.
0215:                    if (appsDir == null) {
0216:
0217:                        File appsDirFile = new File(home, APPS_DIR);
0218:                        appsDir = appsDirFile.getAbsolutePath();
0219:                    }
0220:                    logChannel.write(Logger.DEBUG, "conf dir=" + appsDir);
0221:                    // Read config file 'EnhydraServer.xml'
0222:                    File cFile = new File(home, "conf/EnhydraServer.xml");
0223:                    serverConfig = new EnhydraServerXML(cFile.getAbsolutePath());
0224:
0225:                    //   add enhydra loggers from conf file
0226:                    // todo: configure logger from separate xml file 17.03.2003
0227:                    //            PropertyConfigurator.configure(confDir+"EnhydraServer.conf");
0228:                    //            logger.debug("Logger configured");
0229:                    //            loggerSys.addAppender(logger.getAppender("enhydraAppender"));
0230:
0231:                } catch (Exception e) {
0232:                    logChannel.write(Logger.ALERT,
0233:                            "Fail to startup EnhydraServer", e);
0234:                    return;
0235:                }
0236:
0237:                if (applicationServer == null) {
0238:                    logChannel
0239:                            .write(Logger.ERROR,
0240:                                    "Can't startup EnhydraServer, applicationServer = null");
0241:                    return;
0242:                }
0243:                if (started) {
0244:                    logChannel.write(Logger.WARNING,
0245:                            "EnhydraServer already started");
0246:                    return;
0247:                }
0248:
0249:                try {
0250:
0251:                    // Create AppInfo, put into hashtable and start application if running = true.
0252:
0253:                    //17.03.2003            String[] appNames = null;
0254:                    HashMap[] appsHash = serverConfig.getApplications();
0255:
0256:                    String[] appNames = new String[appsHash.length];
0257:                    for (int i = 0; i < appsHash.length; i++) {
0258:                        appNames[i] = (String) appsHash[i].get(APP_NAME);
0259:                    }
0260:                    if (appNames != null) {
0261:                        for (int i = 0; i < appNames.length; i++) {
0262:                            // Create AppInfo
0263:                            AppInfo appInfo = new AppInfo(appNames[i],
0264:                                    appsHash[i]);
0265:                            apps.put(appNames[i], appInfo);
0266:                            logChannel.write(Logger.INFO, "add Application "
0267:                                    + i + ":" + appNames[i]);
0268:                            if (appInfo.isRunning()) {
0269:                                appInfo.setRunning(false); //must cheat startApplication() method on startup
0270:                                startApplication(appNames[i]); //startApplication() will call appInfo.setRunning(true);
0271:                            }
0272:                        }
0273:                    }
0274:                } catch (Exception e) {
0275:                    logChannel.write(Logger.ERROR, "... at startup():", e);
0276:                    return;
0277:                }
0278:                started = true;
0279:                logChannel.write(Logger.INFO,
0280:                        "EnhydraServer is startup successfuly");
0281:            }
0282:
0283:            /**
0284:             * Enhydra Application (HttpPresentationServlet) register itself on startup.
0285:             * @param servlet  only HttpPresentationServlet is currently supported.
0286:             */
0287:            public void register(Servlet servlet) {//FIXME should be synchronized?
0288:                if (servlet == null) {
0289:                    logChannel.write(Logger.ERROR,
0290:                            "Unable to register application, servlet = NULL");
0291:                    return;
0292:                }
0293:                AppInfo appInfo = null;
0294:                // Check is already registered?
0295:                // If application is already registered by ApplicationServer,
0296:                // just need to proceed Application interface, else make new appInfo
0297:                try {
0298:
0299:                    AppInfo appInfoTemp = new AppInfo(servlet);
0300:                    String appName = appInfoTemp.getName();
0301:                    File urlPathTemp = new File(appInfoTemp.getUrlPath());
0302:                    if (apps.containsKey(appName)) {
0303:                        appInfo = ((AppInfo) apps.get(appName));
0304:                        // Check urlPath (if urlPaths are difrerent it is not the same application)
0305:                        if (!urlPathTemp.equals(new File(appInfo.getUrlPath())))
0306:                            appInfo = null;
0307:                    }
0308:                    //try to find equal url path in other appInfos
0309:                    //(maybe user change app name in EnhydraServer.conf)
0310:                    if (appInfo == null) {
0311:                        Enumeration keys = apps.keys();
0312:                        while (keys.hasMoreElements() && (appInfo == null)) {
0313:                            appInfo = ((AppInfo) apps.get((String) keys
0314:                                    .nextElement()));
0315:                            if (!urlPathTemp.equals(new File(appInfo
0316:                                    .getUrlPath())))
0317:                                appInfo = null;
0318:                        }
0319:                    }
0320:                    //if appInfo found just set Application reference
0321:                    if (appInfo != null) {
0322:                        appInfo.setApplication(appInfoTemp.getApplication());
0323:                    } else {
0324:                        // ApplicationServer didn't register this application
0325:                        // this is a case when application server is unknown, and/or application is
0326:                        // autostarted with application server (Servlet Container).
0327:                        // In that case just put appInfo into apps hashtable, don't add
0328:                        // application into EnhydraServer config
0329:                        appInfo = appInfoTemp;
0330:                        appInfo
0331:                                .setDescription("Auto registered Enhydra application.");
0332:                        apps.put(appName, appInfo);
0333:                    }
0334:                    if (!appInfo.isRunning()) {
0335:                        appInfo.setRunning(true);
0336:                        appInfo.setStarted(new Date());
0337:                    }
0338:                    logChannel.write(Logger.INFO, "Application " + appName
0339:                            + " successfuly registered");
0340:                } catch (Exception e) {
0341:                    logChannel.write(Logger.ERROR, "in register() ", e);
0342:                }
0343:                return;
0344:            }
0345:
0346:            /**
0347:             * Enhydra Application unregister itself when stop.
0348:             * @param servlet  usualy HttpPresentationServlet.
0349:             */
0350:            public void unRegister(Servlet servlet) {
0351:                if (servlet instanceof  HttpPresentationServlet) {
0352:
0353:                    String appName = ((HttpPresentationServlet) servlet)
0354:                            .getApplication().getName();
0355:                    if (appName != null) {
0356:                        if (apps.containsKey(appName)) {
0357:                            ((AppInfo) apps.get(appName)).setRunning(false);
0358:                            logChannel.write(Logger.INFO, "Application "
0359:                                    + appName + " successfuly unregistered");
0360:                        }
0361:                    }
0362:                }
0363:            }
0364:
0365:            /**
0366:             * Set path to default Applications context root path.
0367:             * Application context url can be relative against this path.
0368:             * @param dir  absolute path to directory, where are application context reside.
0369:             */
0370:            public static void setAppsfDir(String dir) {
0371:                appsDir = dir;
0372:            }
0373:
0374:            /**
0375:             * Get path to default Applications context root path.
0376:             * @return absolute path to directory, where are application context reside.
0377:             */
0378:            public String getAppsDir() {
0379:                return appsDir;
0380:            }
0381:
0382:            // Methods for reading application data -------------------------------------
0383:
0384:            /**
0385:             * @see <a href="AppInfo.html">AppInfo</a>
0386:             * @param appName application name.
0387:             * @return AppInfo contains all necessary application data.
0388:             */
0389:            public AppInfo getAppInfo(String appName) {
0390:                AppInfo appInfo = (AppInfo) apps.get(appName);
0391:                if (appInfo == null) {
0392:                    logChannel.write(Logger.WARNING,
0393:                            "EnhydraServer: Can't get AppInfo," + appName
0394:                                    + " not registered");
0395:                    return null;
0396:                }
0397:
0398:                return appInfo;
0399:            }
0400:
0401:            /**
0402:             * @see <a href="PresentationInfo.html">PresentationInfo</a>
0403:             * @param appName - application name
0404:             * @return PresentationInfo - JavaBean with getter methods
0405:             */
0406:            public PresentationInfo getPresentationInfo(String appName) {
0407:                PresentationInfo presInfo = null;
0408:                Config config = null;
0409:                AppInfo appInfo = null;
0410:                Application app = null;
0411:                try {
0412:                    if (apps.containsKey(appName)) {
0413:
0414:                        appInfo = (AppInfo) apps.get(appName);
0415:                        app = appInfo.getApplication();
0416:                        config = (Config) appInfo.getConfig();
0417:                        if (config != null)
0418:                            if (config.containsKey("PresentationManager"))
0419:                                config = (Config) config
0420:                                        .getSection("PresentationManager");
0421:                        presInfo = new PresentationInfo(app, config);
0422:                    } else
0423:                        logChannel.write(Logger.WARNING,
0424:                                "Can't get PresentationInfo, " + appName
0425:                                        + " don't exist!");
0426:                } catch (Exception e) {
0427:                    //FIXME maintain exceptions
0428:                    logChannel.write(Logger.ERROR,
0429:                            "Exception in getPresentationInfo", e);
0430:                }
0431:                return presInfo;
0432:            }
0433:
0434:            /**
0435:             * @see <a href="SessionsInfo.html">SessionsInfo</a>
0436:             * @param appName - application name
0437:             * @return SessionInfo - JavaBean with getter methods
0438:             */
0439:            public SessionsInfo getSessionsInfo(String appName) {
0440:                SessionsInfo sessInfo = null;
0441:                Config config = null;
0442:                AppInfo appInfo = null;
0443:                Application app = null;
0444:                try {
0445:                    if (apps.containsKey(appName)) {
0446:
0447:                        appInfo = (AppInfo) apps.get(appName);
0448:                        app = appInfo.getApplication();
0449:                        config = (Config) appInfo.getConfig();
0450:                        if (config != null)
0451:                            if (config.containsKey("SessionManager"))
0452:                                config = (Config) config
0453:                                        .getSection("SessionManager");
0454:                        sessInfo = new SessionsInfo(app, config);
0455:                    } else
0456:                        logChannel.write(Logger.ERROR,
0457:                                "Can't get SessionInfo, " + appName
0458:                                        + " don't exist!");
0459:                } catch (Exception e) {
0460:                    //FIXME maintain exceptions
0461:                    logChannel.write(Logger.ERROR,
0462:                            "Exception in getSessionInfo()", e);
0463:                }
0464:                return sessInfo;
0465:            }
0466:
0467:            /**
0468:             * @see <a href="SessionEdit.html">SessionEdit</a>
0469:             * @param appName applicatin name
0470:             * @return SessionEdit class for editing SessionManager parameters in conf file.
0471:             */
0472:            public SessionEdit getSessionEdit(String appName) {
0473:                AppInfo appInfo = null;
0474:                SessionEdit sessEdit = null;
0475:                Config config = null;
0476:                try {
0477:                    if (apps.containsKey(appName)) {
0478:                        appInfo = (AppInfo) apps.get(appName);
0479:                        config = (Config) appInfo.getConfig();
0480:                        sessEdit = new SessionEdit(config);
0481:                    } else
0482:                        logChannel.write(Logger.WARNING,
0483:                                "Can't get SessionEdit, " + appName
0484:                                        + " don't exist!");
0485:                } catch (Exception e) {
0486:                    //FIXME maintain exceptions
0487:                    logChannel.write(Logger.ERROR,
0488:                            "Exception in getSessionEdit", e);
0489:                }
0490:                return sessEdit;
0491:            }
0492:
0493:            /**
0494:             * @see <a href="DatabaseInfo.html">SessionsInfo</a>
0495:             * @param appName - application name.
0496:             * @return DatabaseInfo - JavaBean with getter methods.
0497:             */
0498:            public DatabaseInfo getDatabaseInfo(String appName) {
0499:                DatabaseInfo dbInfo = null;
0500:                Config config = null;
0501:                AppInfo appInfo = null;
0502:                Application app = null;
0503:                try {
0504:                    if (apps.containsKey(appName)) {
0505:
0506:                        appInfo = (AppInfo) apps.get(appName);
0507:                        app = appInfo.getApplication();
0508:                        config = (Config) appInfo.getConfig();
0509:                        if (config != null)
0510:                            // VR          if ( config.containsKey("DatabaseManager")) config = (Config) config.getSection("DatabaseManager");
0511:                            dbInfo = new DatabaseInfo(app, config);
0512:                    } else
0513:                        logChannel.write(Logger.ERROR,
0514:                                "Can't get DatabaseInfo, " + appName
0515:                                        + " don't exist!");
0516:                } catch (Exception e) {
0517:                    //FIXME maintain exceptions
0518:                    logChannel.write(Logger.ERROR,
0519:                            "Exception in getDatabaseInfo", e);
0520:                }
0521:                return dbInfo;
0522:            }
0523:
0524:            /**
0525:             * Gets instasnce of DatabaseEdit class which is used in edditing of database
0526:             * parameters in configuration file of the application.
0527:             * @param appName the applicatin name.
0528:             * @return instasnce of DatabaseEdit class.
0529:             */
0530:            public DatabaseEdit getDatabaseEdit(String appName) {
0531:                AppInfo appInfo = null;
0532:                DatabaseEdit databaseEdit = null;
0533:                Config config = null;
0534:                try {
0535:                    if (apps.containsKey(appName)) {
0536:                        appInfo = (AppInfo) apps.get(appName);
0537:                        config = (Config) appInfo.getConfig();
0538:                        databaseEdit = new DatabaseEdit(config);
0539:                    } else
0540:                        logChannel.write(Logger.ERROR,
0541:                                "Can't get DatabaseEdit, " + appName
0542:                                        + " don't exist!");
0543:                } catch (Exception e) {
0544:                    //FIXME maintain exceptions
0545:                    logChannel.write(Logger.ERROR,
0546:                            "Exception in getDatabaseEdit", e);
0547:                }
0548:                return databaseEdit;
0549:            }
0550:
0551:            /**
0552:             *
0553:             * @return instance of class that implements ApplicationServer
0554:             */
0555:            public ApplicationServer getApplicationServer() {
0556:                if (applicationServer == null)
0557:                    logChannel
0558:                            .write(Logger.WARNING, "ApplicationServer = null");
0559:                return applicationServer;
0560:            }
0561:
0562:            /**
0563:             * Implementation of ApplicationServer interface are responsible
0564:             * to set reference on himself.
0565:             * @param appServ Implementation of ApplicationServer.
0566:             */
0567:            public void setApplicationServer(ApplicationServer appServ) {
0568:                applicationServer = appServ;
0569:            }
0570:
0571:            //17.03.2003
0572:            /**
0573:             * Update EnhydraServer.xml document without save.
0574:             * @param appInfo application need to update
0575:             */
0576:            private void updateServerConfig(AppInfo appInfo) {
0577:                HashMap appHash = new HashMap();
0578:                //Required attributes
0579:                appHash.put(APP_CONTEXTPATH, appInfo.getContextPath());
0580:                //Make relative URLPath if path is inside apps dir
0581:                appHash.put(APP_URLPATH, PathUtil.makeRelativePath(appsDir,
0582:                        appInfo.getUrlPath()));
0583:                appHash.put(APP_NAME, appInfo.getName());
0584:                if (appInfo.isRunning()) {
0585:                    appHash.put(APP_RUNNING, "true");
0586:                } else {
0587:                    appHash.put(APP_RUNNING, "false");
0588:                }
0589:                appHash.put(APP_DESCRIPTION, appInfo.getDescription());
0590:                int[] conns = appInfo.getConnections();
0591:                String connections = "";
0592:                StringBuffer connectionsBuffer = new StringBuffer(connections);
0593:                if (conns != null) {
0594:                    for (int i = 0; i < conns.length; i++) {
0595:                        if (i == 0) {
0596:                            connectionsBuffer = new StringBuffer(Integer
0597:                                    .toString(conns[i]));
0598:                        } else {
0599:                            connectionsBuffer.append(","
0600:                                    + Integer.toString(conns[i]));
0601:                        }
0602:                    }
0603:                }
0604:                connections = connectionsBuffer.toString();
0605:                appHash.put(APP_CONNECTIONS, connections);
0606:                //Update
0607:                if (serverConfig.getApplication(appInfo.getContextPath()) != null) {
0608:                    serverConfig.removeApplication(appInfo.getContextPath());
0609:                }
0610:                serverConfig.addApplication(appHash);
0611:            }
0612:
0613:            /**
0614:             * Save state of EnhydraServer into xml config file
0615:             * @return TRUE if OK, else FALSE.
0616:             */
0617:            public boolean saveState() {
0618:                boolean isOK = true;
0619:                logChannel.write(Logger.WARNING,
0620:                        "Saving current EnhydraServer config state ...");
0621:                try {
0622:                    //17.03.2003
0623:                    //            ConfigFileInterface confFile = serverConfig.getConfigFile();
0624:                    //            confFile.write();
0625:                    serverConfig.saveDocument();
0626:                } catch (Exception e) {
0627:                    logChannel.write(Logger.WARNING,
0628:                            "Can't write EnhydraServer.conf file", e);
0629:                    isOK = false;
0630:                }
0631:                return isOK;
0632:            }
0633:
0634:            /**
0635:             * Start application.
0636:             * @param appName application name.
0637:             * @return OK if application successfuly started, else FALSE.
0638:             */
0639:            public boolean startApplication(String appName) {
0640:
0641:                AppInfo appInfo = (AppInfo) apps.get(appName);
0642:                logChannel.write(Logger.INFO, "Starting " + appName
0643:                        + " at context path =" + appInfo.getContextPath()
0644:                        + ", URL path = " + appInfo.getUrlPath());
0645:                /* Alex
0646:                 * if (appInfo == null){
0647:                    logChannel.write(Logger.INFO,"Can't start application, invalid application name: "+appName);
0648:                    return false;
0649:                }*/
0650:                if (appInfo.isRunning()) {
0651:                    logChannel.write(Logger.WARNING,
0652:                            "Can't start application : " + appName
0653:                                    + ", already started");
0654:                    return false;
0655:                }
0656:                if (applicationServer == null) {
0657:                    logChannel
0658:                            .write(Logger.ERROR,
0659:                                    "Can't start application, Unknown Application Server");
0660:                    return false;
0661:                }
0662:                if (!applicationServer.startApp(appName)) {
0663:                    logChannel
0664:                            .write(Logger.ERROR,
0665:                                    "Can't start application, ApplicationServer.startApp() FAIL");
0666:                    return false;
0667:                }
0668:                // if all OK, change AppInfo  and config file but not save.
0669:                try {
0670:                    appInfo.getWebAppXML().reloadDocument(); //reload web.xml (maybe is manualy changed) 21.03.2003
0671:                    appInfo.setRunning(true);
0672:                    appInfo.setStarted(new Date());
0673:                    /** Next line is for standard Web applications,
0674:                     *  Enhydra application will register itself anyway.
0675:                     */
0676:                    //startedApps.put(appName,appInfo);
0677:                    //ConfigFileInterface confFile = serverConfig.getConfigFile();
0678:                    //17.03.2003
0679:                    //serverConfig.set("Application."+appName+".Running",new Boolean(true));
0680:                    //update serverConfig (EnhydraServer.xml)
0681:                    updateServerConfig(appInfo);
0682:                } catch (Exception e) {
0683:                    logChannel
0684:                            .write(
0685:                                    Logger.WARNING,
0686:                                    "Application started but fail to change EnhydraServer.conf",
0687:                                    e);
0688:                }
0689:
0690:                return true;
0691:            }
0692:
0693:            /**
0694:             * Shutdown application.
0695:             * @param appName application name.
0696:             * @return OK if application successfuly stopped, else FALSE.
0697:             */
0698:            public boolean stopApplication(String appName) {
0699:                // FIXME ...
0700:                AppInfo appInfo = (AppInfo) apps.get(appName);
0701:                if (appInfo == null) {
0702:                    logChannel.write(Logger.ERROR,
0703:                            "Can't stop application, invalid application name: "
0704:                                    + appName);
0705:                    return false;
0706:                }
0707:                if (!appInfo.isRunning()) {
0708:                    logChannel.write(Logger.ERROR, "Can't stop application : "
0709:                            + appName + ", not started");
0710:                    return false;
0711:                }
0712:                if (applicationServer == null) {
0713:                    logChannel
0714:                            .write(Logger.ERROR,
0715:                                    "Can't stop application, Unknown Application Server");
0716:                    return false;
0717:                }
0718:                if (!applicationServer.stopApp(appName)) {
0719:                    logChannel
0720:                            .write(Logger.ERROR,
0721:                                    "Can't stop application, ApplicationServer.stopApp() FAIL");
0722:                    return false;
0723:                }
0724:                //If everything OK, remove it from startedApps
0725:                //if(startedApps.containsKey(appName)) startedApps.remove(appName);
0726:                try {
0727:                    appInfo.setRunning(false);
0728:                    appInfo.setStarted(null);//Remove old Date
0729:                    //serverConfig.set("Application."+appName+".Running",new Boolean(false));
0730:                    updateServerConfig(appInfo);
0731:                } catch (Exception e) {
0732:                    logChannel
0733:                            .write(
0734:                                    Logger.WARNING,
0735:                                    "Application stopped but fail to change EnhydraServer.conf",
0736:                                    e);
0737:                }
0738:                return true;
0739:            }
0740:
0741:            /**
0742:             * Shutdown application server
0743:             */
0744:            public void stopApplicationServer() {
0745:                if (applicationServer == null)
0746:                    logChannel
0747:                            .write(Logger.ERROR,
0748:                                    "Can't shutdown application server, applicationServer = null");
0749:                else {
0750:                    applicationServer.stop();
0751:                    logChannel.write(Logger.INFO, applicationServer.getName()
0752:                            + " stopped");
0753:                }
0754:            }
0755:
0756:            /**
0757:             * Shutdown EnhydraServer, including all applications and connections.
0758:             */
0759:            public synchronized void shutdown() {
0760:                logChannel.write(Logger.INFO, "Shuting down EnhydraServer...");
0761:                //Stop all applications started by EnhydraServer
0762:                Enumeration enumApps = apps.keys();
0763:                String appName;
0764:                AppInfo appInfo;
0765:                while (enumApps.hasMoreElements()) {
0766:                    appName = (String) enumApps.nextElement();
0767:                    appInfo = (AppInfo) apps.get(appName);
0768:                    if (appInfo.isRunning())
0769:                        stopApplication(appName);
0770:                }
0771:                //  Do not remove 07.04.2003      //Remove all connection added to ApplicationServer by EnhydraServer
0772:                //        String port;
0773:                //        while(!connectionPorts.isEmpty()){
0774:                //            port = (String)connectionPorts.remove(0);
0775:                //            removeConnection(port);
0776:                //        }
0777:                logChannel.write(Logger.INFO, "EnhydraServer is shutdown !");
0778:                MemoryPersistence.shutdown(); //Clean sessions from memory
0779:                apps = new Hashtable();
0780:                connectionPorts = new ArrayList(0);
0781:                started = false;
0782:            }
0783:
0784:            /**
0785:             * Add (create) connection to application server.
0786:             * Admin Presentation should first check available types, before call this method.
0787:             * @param type Connection type ("http","ajp",..) depends on Application Server.
0788:             * @param port Port nubber.
0789:             * @return TRUE if connection added successfuly.
0790:             */
0791:            public boolean addConnection(String type, String port) {
0792:                if (applicationServer == null) {
0793:                    logChannel.write(Logger.WARNING,
0794:                            "Can't add connection, applicationServer = null !");
0795:                    return false;
0796:                }
0797:
0798:                if (applicationServer.addConnection(type, port)) {
0799:                    connectionPorts.add(port);
0800:                    logChannel.write(Logger.INFO, "Connection (" + port + ","
0801:                            + type + ") added.");
0802:                    return true;
0803:                }
0804:                return false;
0805:            }
0806:
0807:            /**
0808:             * Add (create) connection to application server.
0809:             * @param type Connection type ("http","ajp","https"..) depends on Application Server.
0810:             * @param port Port nubber.
0811:             * @param password for "https" required.
0812:             * @param pathToKeyStoreFile absolute path to KeyStore file for "https" required.
0813:             * @return
0814:             */
0815:            public boolean addConnection(String type, String port,
0816:                    String password, String pathToKeyStoreFile) {
0817:                if (applicationServer == null) {
0818:                    logChannel.write(Logger.WARNING,
0819:                            "Can't add connection, applicationServer = null !");
0820:                    return false;
0821:                }
0822:                if (applicationServer.addConnection(type, port, password,
0823:                        pathToKeyStoreFile)) {
0824:                    connectionPorts.add(port);
0825:                    logChannel.write(Logger.INFO, "Connection (" + port + ","
0826:                            + type + ") added.");
0827:                    return true;
0828:                }
0829:                return false;
0830:            }
0831:
0832:            public boolean removeConnection(String port) {
0833:                if (applicationServer == null) {
0834:                    logChannel
0835:                            .write(Logger.WARNING,
0836:                                    "Can't remove connection, applicationServer = null !");
0837:                    return false;
0838:                }
0839:                if (applicationServer.removeConnection(port)) {
0840:                    try {
0841:                        connectionPorts.remove(port);
0842:                        //13.03.2003 no more Server.Connection in config
0843:                        //        serverConfig.remove("Server.Connection.Port"+port);
0844:                        //        logger.info("Connection "+port+" removed.");
0845:                    } catch (Exception e) {
0846:                        logChannel.write(Logger.WARNING,
0847:                                "Fail to remove connection from config!", e);
0848:                    }
0849:                    return true;
0850:                }
0851:                return false;
0852:            }
0853:
0854:            /**
0855:             * Enable connection to the application on port number.
0856:             * @param appName application name.
0857:             * @param portNumber port number of corresponding connection.
0858:             * @return TRUE if connection successfuly enabled, else FALSE.
0859:             */
0860:            public boolean enableConnection(String appName, String portNumber) {
0861:                //String enabledConns[];
0862:                //String enabledConnsNew[];
0863:                //String connsKey = "Application."+appName+".Connections";
0864:                AppInfo appInfo = ((AppInfo) apps.get(appName));
0865:                int enablePort = Integer.parseInt(portNumber);
0866:                int[] connections = appInfo.getConnections();
0867:                int[] newConnections = null;
0868:                if (connections == null) {
0869:                    newConnections = new int[1];
0870:                    newConnections[0] = enablePort;
0871:                } else {
0872:                    newConnections = new int[connections.length + 1];
0873:                    newConnections[0] = enablePort;
0874:                    for (int i = 0; i < connections.length; i++) {
0875:                        if (connections[i] == enablePort) {
0876:                            logChannel
0877:                                    .write(
0878:                                            Logger.DEBUG,
0879:                                            "Connection on port: "
0880:                                                    + portNumber
0881:                                                    + "allready enabled for application "
0882:                                                    + appName);
0883:                            return false;
0884:                        }
0885:                        newConnections[i + 1] = connections[i];
0886:                    }
0887:                }
0888:                appInfo.setConnections(newConnections);
0889:                updateServerConfig(appInfo);
0890:                logChannel.write(Logger.INFO, "Connection on port: "
0891:                        + portNumber + " enabled for application " + appName);
0892:                return true;
0893:            }
0894:
0895:            /**
0896:             * Disable connection to the application on port number.
0897:             * @param appName application name.
0898:             * @param portNumber port number of corresponding connection.
0899:             * @return TRUE if connection successfuly disabled, else FALSE.
0900:             */
0901:            public boolean disableConnection(String appName, String portNumber) {
0902:                //String enabledConns[];
0903:                //String enabledConnsNew[];
0904:                //String connsKey = "Application."+appName+".Connections";
0905:                ArrayList enabledConnsList = new ArrayList(0);
0906:                AppInfo appInfo = ((AppInfo) apps.get(appName));
0907:                int disablePort = Integer.parseInt(portNumber);
0908:                int[] connections = appInfo.getConnections();
0909:
0910:                if (connections != null) {
0911:                    for (int i = 0; i < connections.length; i++) {
0912:                        if (connections[i] != disablePort) {
0913:                            enabledConnsList.add(Integer
0914:                                    .toString(connections[i]));
0915:                        }
0916:                    }
0917:                }
0918:                Object[] objs = enabledConnsList.toArray();
0919:                connections = new int[objs.length];
0920:                //Object[] --> int[], new connections
0921:                for (int i = 0; i < objs.length; i++) {
0922:                    connections[i] = Integer.parseInt((String) objs[i]);
0923:                }
0924:                appInfo.setConnections(connections);
0925:                updateServerConfig(appInfo);
0926:                logChannel.write(Logger.INFO, "Connection on port: "
0927:                        + portNumber + " disabled for application " + appName);
0928:                return true;
0929:            }
0930:
0931:            /**
0932:             *  Method used by EnhydraPortFilter, provides list of enabled ports
0933:             *  for given application name.
0934:             * @param appName Application name.
0935:             * @return Array of enabled port numbers .
0936:             */
0937:            public String[] getEnabledConnections(String appName) {
0938:                AppInfo appInfo = ((AppInfo) apps.get(appName));
0939:
0940:                String[] enabledPorts = null;
0941:                int[] connections = appInfo.getConnections();
0942:                if (connections != null) {
0943:                    enabledPorts = new String[connections.length];
0944:                    for (int i = 0; i < connections.length; i++) {
0945:                        enabledPorts[i] = Integer.toString(connections[i]);
0946:                    }
0947:                }
0948:                return enabledPorts;
0949:            }
0950:
0951:            /**
0952:             * This method  should be call for editing application config file.
0953:             * @param appName application name
0954:             * @return application Config object.
0955:             * @see com.lutris.util.Config
0956:             */
0957:            public Config getAppConfig(String appName) {
0958:                AppInfo ai = (AppInfo) apps.get(appName);
0959:                if (ai == null) {
0960:                    logChannel.write(Logger.WARNING, "Application " + appName
0961:                            + " not available!");
0962:                    return null;
0963:                }
0964:                return ai.getConfig();
0965:            }
0966:
0967:            /**
0968:             * @return names of all available applications
0969:             */
0970:            public String[] getAppNames() {
0971:                // Get application names
0972:                String[] appNames = null;
0973:                try {
0974:                    //appNames = serverConfig.getSection("Application").keys();
0975:                    Enumeration enumKeys = apps.keys();
0976:                    if (enumKeys != null) {
0977:                        appNames = new String[apps.size()];
0978:                        for (int i = 0; enumKeys.hasMoreElements(); i++) {
0979:                            appNames[i] = (String) enumKeys.nextElement();
0980:                        }
0981:                    }
0982:                } catch (Exception e) {
0983:                    logChannel.write(Logger.ERROR, "Exception in getAppNames",
0984:                            e);
0985:                }
0986:                return appNames;
0987:            }
0988:
0989:            public EnhydraServerXML getConfig() {
0990:                return serverConfig;
0991:            }
0992:
0993:            /**
0994:             * Adds new application to Enhydra server
0995:             * @param appName application name.
0996:             * @param contextPath context path ( e.g. '/myapp')
0997:             * @param urlPath url path file (application root directory or path to war file).
0998:             * If path is relative it is resolved against <code>%ENHYDRA_HOME/apps</code> directory.
0999:             * @param description application description not required.
1000:             * @return <code>true</code> if application added successfuly, else <code>false</code>.
1001:             */
1002:
1003:            public boolean addApplication(String appName, String contextPath,
1004:                    String urlFilePath, String description) {
1005:                String message = null;
1006:                HashMap appHash = new HashMap();
1007:                String urlPath = null;
1008:                urlFilePath = PathUtil.makeAbsolutePath(getAppsDir(),
1009:                        urlFilePath);
1010:
1011:                File urlFile = new File(urlFilePath);
1012:                if (appName == null) {
1013:                    logChannel
1014:                            .write(Logger.ERROR,
1015:                                    "Couldn't add application, application name = null");
1016:                    return false;
1017:                }
1018:                appName = appName.trim(); //cut redutant spaces
1019:                if (appName.equals("")) {
1020:                    logChannel
1021:                            .write(Logger.ERROR,
1022:                                    "Couldn't add application, application name = \"\"");
1023:                    return false;
1024:                }
1025:                //Check is file exist
1026:                if (!urlFile.exists()) {
1027:                    logChannel.write(Logger.ERROR, "Couldn't add " + appName
1028:                            + ". URL Path file:'" + urlFilePath
1029:                            + "' don't exist!");
1030:                    return false;
1031:                }
1032:                if (urlFile.isDirectory()) {
1033:                    urlPath = urlFilePath;
1034:                    //chech is application with one of given parameters allready exist
1035:                    if (!checkApplication(appName, contextPath, urlPath)) {
1036:                        return false;
1037:                    }
1038:                } else if (urlFile.isFile()) {
1039:                    // make urlPath from file name (just cut '.war');
1040:                    String fileName = urlFile.getName();
1041:                    urlPath = fileName.substring(0, fileName.length() - 4);
1042:                    //chech is application with one of given parameters allready exist before unpack
1043:                    if (!checkApplication(appName, contextPath, urlPath)) {
1044:                        return false;
1045:                    }
1046:                    //Unpack war to apps directory
1047:                    UnpackWar unpack = new UnpackWar(urlFilePath, PathUtil
1048:                            .makeAbsolutePath(getAppsDir(), urlPath));
1049:                    try {
1050:                        unpack.execute();
1051:                    } catch (Exception e) {
1052:                        logChannel.write(Logger.ERROR, "Couldn't add "
1053:                                + appName + "!", e);
1054:                        return false;
1055:                    }
1056:                }
1057:
1058:                if (!contextPath.startsWith("/")) {
1059:                    logChannel.write(Logger.ERROR, "Couldn't add " + appName
1060:                            + ". Context path must start with '/'!");
1061:                    return false; //exception
1062:                } else {
1063:                    appHash.put(APP_CONTEXTPATH, contextPath);
1064:                }
1065:
1066:                if (apps.get(appName) != null) {
1067:                    message = "Couldn't add " + appName + ". Application "
1068:                            + appName + " already exist!";
1069:                    logChannel.write(Logger.WARNING, message);
1070:                    return false;
1071:                } else {
1072:                    appHash.put(APP_NAME, appName);
1073:                }
1074:                appHash.put(APP_URLPATH, urlPath);
1075:                appHash.put(APP_DESCRIPTION, description);
1076:                appHash.put(APP_RUNNING, "false");
1077:
1078:                try {
1079:                    AppInfo appInfo = new AppInfo(appName, appHash);
1080:                    apps.put(appName, appInfo);
1081:                    updateServerConfig(appInfo);
1082:                } catch (Exception e) {
1083:                    logChannel.write(Logger.ERROR,
1084:                            "ERROR in EnhydraServer.addApplication", e);
1085:                    return false;
1086:                }
1087:
1088:                return true;
1089:            }
1090:
1091:            /**
1092:             * Check application parameters allready exist.
1093:             * @param appName application name.
1094:             * @param contextPath context path.
1095:             * @param urlPath url path file.
1096:             * @return <code>true</code> if application don't exist, otherwise <code>false</code>.
1097:             */
1098:            private boolean checkApplication(String appName,
1099:                    String contextPath, String urlPath) {
1100:                Iterator iter = apps.values().iterator();
1101:                AppInfo appInfo = null;
1102:                String message = null;
1103:                boolean notExist = true;
1104:                while (iter.hasNext()) {
1105:                    appInfo = (AppInfo) iter.next();
1106:                    // check name
1107:                    if (appInfo.getName().equalsIgnoreCase(appName)) {
1108:                        message = "Application name '" + appName
1109:                                + "' allready exist!";
1110:                        notExist = false;
1111:                        break;
1112:                    }
1113:                    // check context path
1114:                    if (appInfo.getContextPath().equalsIgnoreCase(contextPath)) {
1115:                        message = "Application contextPath '" + appName
1116:                                + "' allready exist!";
1117:                        notExist = false;
1118:                        break;
1119:                    }
1120:                    // check url path, compare absolute paths
1121:                    urlPath = PathUtil.makeAbsolutePath(getAppsDir(), urlPath);
1122:                    if (PathUtil.makeAbsolutePath(getAppsDir(),
1123:                            appInfo.getUrlPath()).equalsIgnoreCase(urlPath)) {
1124:                        message = "Application urlPath '" + urlPath
1125:                                + "' allready exist!";
1126:                        notExist = false;
1127:                        break;
1128:                    }
1129:                }
1130:                if (!notExist) {
1131:                    logChannel.write(Logger.ERROR, message);
1132:                }
1133:                return notExist;
1134:            }
1135:
1136:            /**
1137:             * Remove application from Enhydra Server.
1138:             * @param appName application name.
1139:             * @return true if application removing was successful.
1140:             */
1141:            public boolean removeApplication(String appName) {
1142:                if (!apps.containsKey(appName)) {
1143:                    logChannel.write(Logger.WARNING, "in removeApplication(): "
1144:                            + appName + " don't exist!");
1145:                    return false;
1146:                }
1147:                AppInfo appInfo = (AppInfo) apps.get(appName);
1148:                if (appInfo.isRunning()) {
1149:                    if (!stopApplication(appName)) {
1150:                        return false;
1151:                    }
1152:                }
1153:
1154:                apps.remove(appName);
1155:                // remove from config file
1156:                serverConfig.removeApplication(appInfo.getContextPath());
1157:
1158:                logChannel.write(Logger.INFO, "Application " + appName
1159:                        + " removed successfuly.");
1160:                return true;
1161:            }
1162:
1163:            /**
1164:             * AdminGui should call this method to check is EnhydraServer started
1165:             * @return true if EnhydraServer started
1166:             */
1167:            public boolean isStarted() {
1168:                return started;
1169:            }
1170:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.