Java tutorial
/* * ConcourseConnect * Copyright 2009 Concursive Corporation * http://www.concursive.com * * This file is part of ConcourseConnect, an open source social business * software and community platform. * * Concursive ConcourseConnect is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, version 3 of the License. * * Under the terms of the GNU Affero General Public License you must release the * complete source code for any application that uses any part of ConcourseConnect * (system header files and libraries used by the operating system are excluded). * These terms must be included in any work that has ConcourseConnect components. * If you are developing and distributing open source applications under the * GNU Affero General Public License, then you are free to use ConcourseConnect * under the GNU Affero General Public License. * * If you are deploying a web site in which users interact with any portion of * ConcourseConnect over a network, the complete source code changes must be made * available. For example, include a link to the source archive directly from * your web site. * * For OEMs, ISVs, SIs and VARs who distribute ConcourseConnect with their * products, and do not license and distribute their source code under the GNU * Affero General Public License, Concursive provides a flexible commercial * license. * * To anyone in doubt, we recommend the commercial license. Our commercial license * is competitively priced and will eliminate any confusion about how * ConcourseConnect can be used and distributed. * * ConcourseConnect is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License * along with ConcourseConnect. If not, see <http://www.gnu.org/licenses/>. * * Attribution Notice: ConcourseConnect is an Original Work of software created * by Concursive Corporation */ package com.concursive.connect.config; import com.concursive.commons.codec.PrivateString; import com.concursive.commons.db.ConnectionElement; import com.concursive.commons.db.ConnectionPool; import com.concursive.commons.jsp.JspUtils; import com.concursive.commons.workflow.ObjectHookManager; import com.concursive.commons.xml.XMLUtils; import com.concursive.connect.Constants; import com.concursive.connect.cache.CacheContext; import com.concursive.connect.cache.Caches; import com.concursive.connect.indexer.IndexerContext; import com.concursive.connect.indexer.IndexerFactory; import com.concursive.connect.scheduler.ScheduledJobs; import com.concursive.connect.web.modules.upgrade.utils.UpgradeUtils; import com.concursive.connect.web.webdav.WebdavManager; import com.concursive.connect.workflow.utils.WorkflowUtils; import freemarker.cache.FileTemplateLoader; import freemarker.cache.MultiTemplateLoader; import freemarker.cache.TemplateLoader; import freemarker.cache.WebappTemplateLoader; import freemarker.template.Configuration; import freemarker.template.DefaultObjectWrapper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.quartz.Scheduler; import org.w3c.dom.Element; import org.w3c.dom.Node; import javax.servlet.ServletContext; import java.io.*; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; import java.security.Key; import java.sql.Connection; import java.text.NumberFormat; import java.util.*; import java.util.prefs.Preferences; /** * Handles storing and retrieving web application preferences * * @author matt rajkowski * @version $Id: ApplicationPrefs.java,v 2.18.2.1 2004/09/13 02:30:47 matt Exp * $ * @created August 26, 2003 */ public class ApplicationPrefs { private static Log LOG = LogFactory.getLog(ApplicationPrefs.class); public final static String GENERATED_MESSAGE = "### GENERATED BY com.concursive.connect.config.ApplicationPrefs"; // Object constants public final static String FILE_LIBRARY_PATH = "FILELIBRARY"; public final static String TEAM_KEY = "TEAM.KEY"; // Connection Properties public final static String CONNECTION_DRIVER = "SITE.DRIVER"; public final static String CONNECTION_URL = "SITE.URL"; public final static String CONNECTION_USER = "SITE.USER"; public final static String CONNECTION_PASSWORD = "SITE.PASSWORD"; // Connection Pool Properties public final static String CONNECTION_POOL_DEBUG = "CONNECTION_POOL.DEBUG"; public final static String CONNECTION_POOL_TEST_CONNECTIONS = "CONNECTION_POOL.TEST_CONNECTIONS"; public final static String CONNECTION_POOL_ALLOW_SHRINKING = "CONNECTION_POOL.ALLOW_SHRINKING"; public final static String CONNECTION_POOL_MAX_CONNECTIONS = "CONNECTION_POOL.MAX_CONNECTIONS"; public final static String CONNECTION_POOL_MAX_IDLE_TIME = "CONNECTION_POOL.MAX_IDLE_TIME.SECONDS"; public final static String CONNECTION_POOL_MAX_DEAD_TIME = "CONNECTION_POOL.MAX_DEAD_TIME.SECONDS"; public final static String CONNECTION_POOL_MAX_RSS_CONNECTIONS = "CONNECTION_POOL.MAX_CONNECTIONS.RSS"; public final static String CONNECTION_POOL_MAX_API_CONNECTIONS = "CONNECTION_POOL.MAX_CONNECTIONS.API"; public final static String CONNECTION_POOL_MAX_WORKFLOW_CONNECTIONS = "CONNECTION_POOL.MAX_CONNECTIONS.WORKFLOW"; public final static String CONNECTION_POOL_MAX_SCHEDULER_CONNECTIONS = "CONNECTION_POOL.MAX_CONNECTIONS.APPS"; public final static String CONNECTION_POOL_MAX_CACHE_CONNECTIONS = "CONNECTION_POOL.MAX_CONNECTIONS.CACHE"; // Mail Server Properties public final static String MAILSERVER = "MAILSERVER"; public final static String MAILSERVER_USERNAME = "MAILSERVER.CONNECTION.USERNAME"; public final static String MAILSERVER_PASSWORD = "MAILSERVER.CONNECTION.PASSWORD"; public final static String MAILSERVER_PORT = "MAILSERVER.CONNECTION.PORT"; public final static String MAILSERVER_SSL = "MAILSERVER.CONNECTION.SSL"; public final static String EMAILADDRESS = "EMAILADDRESS"; // DimDim Properties public final static String DIMDIM_ENABLED = "DIMDIM.ENABLED"; public final static String DIMDIM_API_DOMAIN = "DIMDIM.DOMAIN"; // Google Properties public final static String GOOGLE_MAPS_API_DOMAIN = "GOOGLE_MAPS.DOMAIN"; public final static String GOOGLE_MAPS_API_KEY = "GOOGLE_MAPS.KEY"; public final static String GOOGLE_ANALYTICS_ID = "GOOGLE_ANALYTICS.ID"; public final static String GOOGLE_ANALYTICS_VERIFY = "GOOGLE_ANALYTICS.VERIFY"; // Twitter Properties public final static String TWITTER_HASH = "TWITTER_HASH"; // Services Properties public final static String CONCURSIVE_SERVICES_SERVER = "CONCURSIVE_SERVICES.SERVER"; public final static String CONCURSIVE_SERVICES_ID = "CONCURSIVE_SERVICES.ID"; public final static String CONCURSIVE_SERVICES_KEY = "CONCURSIVE_SERVICES.KEY"; public final static String CONSUMER_SESSION_SUPPORT = "CONSUMER_SESSION_SUPPORT"; // Web Application Behavior Properties public final static String LOGIN_MODE = "LOGIN.MODE"; public final static String PURPOSE = "PURPOSE"; // The Application's URL public final static String WEB_SCHEME = "URL.SCHEME"; public final static String WEB_DOMAIN_NAME = "URL.DOMAIN_NAME"; public final static String WEB_PORT = "URL.PORT"; public final static String WEB_CONTEXT = "URL.CONTEXT"; // Web Application Look and Feel public final static String THEME = "THEME"; public final static String COLOR_SCHEME = "COLOR_SCHEME"; public final static String JSP_TEMPLATE = "TEMPLATE"; public final static String CSS_FILE = "CSS"; public final static String HOME_URL = "PORTAL.INDEX"; public final static String WEB_PAGE_TITLE = "TITLE"; public final static String WEB_PAGE_DESCRIPTION = "DESCRIPTION"; public final static String WEB_PAGE_KEYWORDS = "KEYWORDS"; public final static String WEB_PAGE_LOGO = "LOGO"; // Application Behavior Properties public final static String WORKFLOW_FILE = "WORKFLOW"; public final static String SYSTEM_SETTINGS_FILE = "SETTINGS"; public final static String USERS_CAN_REGISTER = "REGISTER"; public final static String INFORMATION_IS_SENSITIVE = "SENSITIVE_INFORMATION"; public final static String USERS_CAN_INVITE = "INVITE"; public final static String USERS_CAN_START_PROJECTS = "START_PROJECTS"; public final static String USERS_ARE_ANONYMOUS = "ANONYMOUS"; public final static String DEFAULT_USER_PROFILE_ROLE = "DEFAULT_USER_PROFILE_ROLE"; public final static String DEFAULT_USER_PROFILE_TABS = "DEFAULT_USER_PROFILE_TABS"; public final static String SHOW_TERMS_AND_CONDITIONS = "LICENSE"; public final static String SEARCH_USES_LOCATION = "USE_LOCATIONS"; public final static String LANGUAGE = "SYSTEM.LANGUAGE"; public final static String TIMEZONE = "SYSTEM.TIMEZONE"; public final static String CURRENCY = "SYSTEM.CURRENCY"; public final static String LANGUAGES_SUPPORTED = "SUPPORTED.LANGUAGES"; public final static String MAIN_PROFILE = "MAIN_PROFILE"; public final static String SHOW_HOLIDAYS = "HOLIDAYS"; // Default values public final static String DEFAULT_NODE = "primary"; // Community Management Settings public final static String CONCURSIVE_CRM_SERVER = "CONCURSIVE_CRM.SERVER"; public final static String CONCURSIVE_CRM_ID = "CONCURSIVE_CRM.ID"; public final static String CONCURSIVE_CRM_CODE = "CONCURSIVE_CRM.CODE"; public final static String CONCURSIVE_CRM_CLIENT = "CONCURSIVE_CRM.CLIENT"; // System constants public final static String ls = System.getProperty("line.separator"); public final static String fs = System.getProperty("file.separator"); // Variable context properties private String node = null; private Map<String, Dictionary> dictionaries = new HashMap<String, Dictionary>(); private Map<String, String> prefs = new LinkedHashMap<String, String>(); private Map<String, String> nodePrefs = new LinkedHashMap<String, String>(); /** * Constructor for the ApplicationPrefs object */ public ApplicationPrefs() { } /** * Constructor for the ApplicationPrefs object * * @param context Description of the Parameter */ public ApplicationPrefs(ServletContext context) { initializePrefs(context); } /** * Description of the Method * * @param param Description of the Parameter * @return Description of the Return Value */ public String get(String param) { String value = nodePrefs.get(param); if (value == null) { value = prefs.get(param); } return value; } public String get(String param, String defaultValue) { String value = get(param); if (value == null) { return defaultValue; } return value; } /** * Description of the Method * * @param param Description of the Parameter * @return Description of the Return Value */ public boolean has(String param) { return (prefs.containsKey(param) || nodePrefs.containsKey(param)); } /** * Description of the Method * * @param param Description of the Parameter * @param value Description of the Parameter */ public void add(String param, String value) { if (param != null) { if (value != null) { prefs.put(param, value); } else { prefs.remove(param); } } } public void add(String param, boolean value) { add(param, (value ? "true" : "false")); } public Map<String, String> getPrefs() { Map<String, String> allPrefs = new LinkedHashMap<String, String>(); allPrefs.putAll(prefs); allPrefs.putAll(nodePrefs); return allPrefs; } /** * Description of the Method */ public void clear() { prefs.clear(); nodePrefs.clear(); } /** * Initializes preferences * * @param context ServletContext */ public void initializePrefs(ServletContext context) { LOG.info("Initializing..."); // Load the application node name, if any try { Properties instanceProperties = new Properties(); instanceProperties.load(context.getResourceAsStream("/WEB-INF/instance.property")); node = instanceProperties.getProperty("node", DEFAULT_NODE); LOG.info("Node: " + node); } catch (Exception e) { LOG.info("Default Node: " + DEFAULT_NODE); node = DEFAULT_NODE; } // Determine the file library String fileLibrary = retrieveFileLibraryLocation(context); if (fileLibrary != null) { loadProperties(fileLibrary); this.add(FILE_LIBRARY_PATH, fileLibrary); configureDebug(); verifyKey(context, fileLibrary); configureConnectionPool(context); configureFreemarker(context); configureWebdavManager(context); configureSystemSettings(context); configureCache(context); if (isConfigured()) { if (ApplicationVersion.isOutOfDate(this)) { LOG.info("Upgrade triggered... obtaining lock to continue"); // Use a lock file to to start upgrading File upgradeLockFile = new File(fileLibrary + "upgrade.lock"); FileChannel fileChannel = null; FileLock fileLock = null; try { // Configure the file for locking fileChannel = new RandomAccessFile(upgradeLockFile, "rw").getChannel(); // Use fileChannel.lock which blocks until the lock is obtained fileLock = fileChannel.lock(); // Reload the prefs to make sure the upgrade isn't already complete loadProperties(fileLibrary); if (ApplicationVersion.isOutOfDate(this)) { // The application needs an update LOG.info("Installed version " + ApplicationVersion.getInstalledVersion(this) + " will be upgraded to " + ApplicationVersion.VERSION); performUpgrade(context); } } catch (Exception e) { LOG.error("initializePrefs-> performUpgrade", e); } finally { try { if (fileLock != null) { fileLock.release(); } if (fileChannel != null) { fileChannel.close(); } } catch (Exception eclose) { LOG.error("initializePrefs-> lock", eclose); } } } if (!ApplicationVersion.isOutOfDate(this)) { // Start the services now that everything is ready initializeServices(context); } } } configureDefaultBehavior(context); loadApplicationDictionaries(context); } /** * Initializes services * * @param context ServletContext */ public void initializeServices(ServletContext context) { // These require up-to-date objects, so postpone if an update is needed configureWorkflowManager(context); configureScheduler(context); configureIndexer(); } /** * Description of the Method * * @param context Description of the Parameter * @return Description of the Return Value */ private String retrieveFileLibraryLocation(ServletContext context) { String dir = ApplicationPrefs.getRealPath(context); try { if (dir == null) { dir = node; } // Read from Preferences LOG.info("Java preferences key: " + dir); Preferences javaPrefs = Preferences.userNodeForPackage(ApplicationPrefs.class); // Check "dir" prefs first, based on the installed directory of this webapp String fileLibrary = null; if (dir.length() <= Preferences.MAX_KEY_LENGTH) { fileLibrary = javaPrefs.get(dir, null); } else { fileLibrary = javaPrefs.get(dir.substring(dir.length() - Preferences.MAX_KEY_LENGTH), null); } boolean doSave = false; // Preferences not found if (fileLibrary == null) { // Check in the current dir of the webapp for a pointer to the properties // NOTE: Some containers return null for getRealPath() String realPath = ApplicationPrefs.getRealPath(context); if (realPath != null) { fileLibrary = realPath + "WEB-INF" + fs + "fileLibrary" + fs; doSave = true; } } // See if properties exist if (fileLibrary != null) { File propertyFile = new File(fileLibrary + "build.properties"); if (propertyFile.exists()) { if (doSave) { saveFileLibraryLocation(dir, fileLibrary); } return fileLibrary; } } } catch (Exception e) { LOG.error("ApplicationPrefs", e); e.printStackTrace(System.out); } return null; } /** * Constructor for the ApplicationPrefs object * * @param path Description of the Parameter */ public void loadProperties(String path) { this.clear(); // Application properties loadProperties(path, "build.properties", prefs); // Any node properties File nodeFile = new File(path + "instances" + fs + node + ".properties"); if (nodeFile.exists()) { loadProperties(path + "instances" + fs, node + ".properties", nodePrefs); } } private void loadProperties(String path, String filename, Map<String, String> prefsToAddTo) { try { BufferedReader in = new BufferedReader(new FileReader(path + filename)); String line = null; int count = 0; while ((line = in.readLine()) != null) { ++count; if (!line.startsWith("#") && line.indexOf("=") > 0) { String param = line.substring(0, line.indexOf("=")); String value = ""; if (line.indexOf("=") + 1 < line.length()) { value = line.substring(line.indexOf("=") + 1); } prefsToAddTo.put(param, value); } else if (!line.startsWith(GENERATED_MESSAGE)) { prefsToAddTo.put("#" + count, line); } } in.close(); LOG.info("Read properties: " + path + filename + " (" + count + ")"); } catch (Exception e) { LOG.error("Could not load properties from: " + path + filename, e); } } /** * Description of the Method */ private void configureDebug() { if (this.has("DEBUG")) { System.setProperty("Debug", this.get("DEBUG")); System.setProperty("DEBUG", this.get("DEBUG")); } } /** * Description of the Method * * @param context Description of the Parameter * @param fileLibrary Description of the Parameter */ private void verifyKey(ServletContext context, String fileLibrary) { // Configure the encryption key Key key = PrivateString.generateKeyFile(fileLibrary + "team.key"); context.setAttribute(TEAM_KEY, key); } /** * Description of the Method * * @param context Description of the Parameter */ public void configureConnectionPool(ServletContext context) { LOG.info("configureConnectionPool"); //Define the ConnectionPool, else defaults from the ContextListener will be used ConnectionPool cp = (ConnectionPool) context.getAttribute(Constants.CONNECTION_POOL); if (cp != null) { // Apply any settings if (this.has(CONNECTION_POOL_DEBUG)) { cp.setDebug(this.get(CONNECTION_POOL_DEBUG)); } if (this.has(CONNECTION_POOL_TEST_CONNECTIONS)) { cp.setTestConnections(this.get(CONNECTION_POOL_TEST_CONNECTIONS)); } if (this.has(CONNECTION_POOL_ALLOW_SHRINKING)) { cp.setAllowShrinking(this.get(CONNECTION_POOL_ALLOW_SHRINKING)); } if (this.has(CONNECTION_POOL_MAX_CONNECTIONS)) { cp.setMaxConnections(this.get(CONNECTION_POOL_MAX_CONNECTIONS)); } if (this.has(CONNECTION_POOL_MAX_IDLE_TIME)) { cp.setMaxIdleTimeSeconds(this.get(CONNECTION_POOL_MAX_IDLE_TIME)); } if (this.has(CONNECTION_POOL_MAX_DEAD_TIME)) { cp.setMaxDeadTimeSeconds(this.get(CONNECTION_POOL_MAX_DEAD_TIME)); } // Clone it for RSS Feeds if (this.get(CONNECTION_POOL_MAX_RSS_CONNECTIONS) != null) { ConnectionPool rssCP = new ConnectionPool(); rssCP.setDebug(cp.getDebug()); rssCP.setTestConnections(cp.getTestConnections()); rssCP.setAllowShrinking(cp.getAllowShrinking()); rssCP.setMaxConnections(this.get(CONNECTION_POOL_MAX_RSS_CONNECTIONS)); rssCP.setMaxIdleTime(cp.getMaxIdleTime()); rssCP.setMaxDeadTime(cp.getMaxDeadTime()); context.setAttribute(Constants.CONNECTION_POOL_RSS, rssCP); } else { context.setAttribute(Constants.CONNECTION_POOL_RSS, cp); } // Clone it for API Requests if (this.get(CONNECTION_POOL_MAX_API_CONNECTIONS) != null) { ConnectionPool apiCP = new ConnectionPool(); apiCP.setDebug(cp.getDebug()); apiCP.setTestConnections(cp.getTestConnections()); apiCP.setAllowShrinking(cp.getAllowShrinking()); apiCP.setMaxConnections(this.get(CONNECTION_POOL_MAX_API_CONNECTIONS)); apiCP.setMaxIdleTime(cp.getMaxIdleTime()); apiCP.setMaxDeadTime(cp.getMaxDeadTime()); context.setAttribute(Constants.CONNECTION_POOL_API, apiCP); } else { context.setAttribute(Constants.CONNECTION_POOL_API, cp); } } else { LOG.error("ConnectionPool is null"); } } /** * Description of the Method * * @param context Description of the Parameter */ public void configureWorkflowManager(ServletContext context) { // Load the defaults ObjectHookManager hookManager = (ObjectHookManager) context.getAttribute(Constants.OBJECT_HOOK_MANAGER); if (hookManager != null) { // Configure a few settings hookManager.setFileLibraryPath(this.get(FILE_LIBRARY_PATH)); hookManager.setApplicationPrefs(this.getPrefs()); if (ApplicationPrefs.getFreemarkerConfiguration(context) == null) { LOG.error("Free marker configuration is null"); } hookManager.setFreemarkerConfiguration(ApplicationPrefs.getFreemarkerConfiguration(context)); hookManager.setKey((Key) context.getAttribute(TEAM_KEY)); Scheduler scheduler = (Scheduler) context.getAttribute(Constants.SCHEDULER); hookManager.setScheduler(scheduler); try { // Configure a separate connection pool ConnectionPool commonCP = (ConnectionPool) context.getAttribute(Constants.CONNECTION_POOL); if (commonCP != null) { if (!this.has(CONNECTION_POOL_MAX_WORKFLOW_CONNECTIONS)) { hookManager.setConnectionPool( (ConnectionPool) context.getAttribute(Constants.CONNECTION_POOL)); } else { ConnectionPool workflowCP = new ConnectionPool(); workflowCP.setDebug(commonCP.getDebug()); workflowCP.setTestConnections(commonCP.getTestConnections()); workflowCP.setAllowShrinking(commonCP.getAllowShrinking()); workflowCP.setMaxConnections(this.get(CONNECTION_POOL_MAX_WORKFLOW_CONNECTIONS)); workflowCP.setMaxIdleTime(commonCP.getMaxIdleTime()); workflowCP.setMaxDeadTime(commonCP.getMaxDeadTime()); hookManager.setConnectionPool(workflowCP); } } ConnectionElement ce = new ConnectionElement(); ce.setDriver(this.get(CONNECTION_DRIVER)); ce.setUrl(this.get(CONNECTION_URL)); ce.setUsername(this.get(CONNECTION_USER)); ce.setPassword(this.get(CONNECTION_PASSWORD)); hookManager.setConnectionElement(ce); WorkflowUtils.addWorkflow(hookManager, context); } catch (Exception e) { e.printStackTrace(System.out); LOG.error("Workflow Error: " + e.getMessage(), e); } } } private void configureScheduler(ServletContext context) { Scheduler scheduler = (Scheduler) context.getAttribute(Constants.SCHEDULER); if (scheduler != null) { // Initialize try { scheduler.getContext().setAllowsTransientData(true); scheduler.getContext().put("ServletContext", context); // Give the scheduler its own connection pool... this can speed up the web-tier // when background processing is occurring ConnectionPool commonCP = (ConnectionPool) context.getAttribute(Constants.CONNECTION_POOL); if (commonCP != null) { if (!this.has(CONNECTION_POOL_MAX_SCHEDULER_CONNECTIONS)) { scheduler.getContext().put(Constants.CONNECTION_POOL, context.getAttribute(Constants.CONNECTION_POOL)); } else { ConnectionPool schedulerCP = new ConnectionPool(); schedulerCP.setDebug(commonCP.getDebug()); schedulerCP.setTestConnections(commonCP.getTestConnections()); schedulerCP.setAllowShrinking(commonCP.getAllowShrinking()); schedulerCP.setMaxConnections(this.get(CONNECTION_POOL_MAX_SCHEDULER_CONNECTIONS)); schedulerCP.setMaxIdleTime(commonCP.getMaxIdleTime()); schedulerCP.setMaxDeadTime(commonCP.getMaxDeadTime()); scheduler.getContext().put("ConnectionPool", schedulerCP); } } ConnectionElement ce = new ConnectionElement(); ce.setDriver(this.get(CONNECTION_DRIVER)); ce.setUrl(this.get(CONNECTION_URL)); ce.setUsername(this.get(CONNECTION_USER)); ce.setPassword(this.get(CONNECTION_PASSWORD)); scheduler.getContext().put("ConnectionElement", ce); scheduler.getContext().put("ApplicationPrefs", this); scheduler.start(); scheduler.getContext().put(ScheduledJobs.CONTEXT_SCHEDULER_GROUP, ScheduledJobs.UNIQUE_GROUP); ScheduledJobs.addJobs(scheduler, context); } catch (Exception e) { e.printStackTrace(System.out); LOG.error("Scheduler Error: " + e.getMessage(), e); } } } private void configureWebdavManager(ServletContext context) { LOG.info("configureWebdavManager"); WebdavManager webdavManager = (WebdavManager) context.getAttribute(Constants.WEBDAV_MANAGER); if (webdavManager != null) { webdavManager.setFileLibraryPath(this.get(FILE_LIBRARY_PATH)); } } private void configureSystemSettings(ServletContext context) { LOG.info("configureSystemSettings"); SystemSettings systemSettings = new SystemSettings(); try { // Load the settings... InputStream source = null; // Look in build.properties, or use default String settingsFile = this.get(SYSTEM_SETTINGS_FILE); if (settingsFile != null) { LOG.info("SystemSettings path: " + this.get(FILE_LIBRARY_PATH) + settingsFile); source = new FileInputStream(this.get(FILE_LIBRARY_PATH) + settingsFile); } else { LOG.info("SystemSettings path: /WEB-INF/settings.xml"); source = context.getResourceAsStream("/WEB-INF/settings.xml"); } if (source != null) { LOG.info("Loading system settings..."); XMLUtils xml = new XMLUtils(source); systemSettings.initialize(xml.getDocumentElement()); source.close(); } } catch (Exception e) { e.printStackTrace(System.out); LOG.error("System Settings Error", e); } context.setAttribute(Constants.SYSTEM_SETTINGS, systemSettings); } /** * Description of the Method * * @param context Description of the Parameter */ public void configureDefaultBehavior(ServletContext context) { LOG.info("Configuring default behavior..."); // Default login and session validation if (!this.has(LOGIN_MODE)) { this.add(LOGIN_MODE, "Default"); } // Detect if this instance is using a legacy default, and upgrade to a theme if (!this.has(THEME)) { if (!this.has(JSP_TEMPLATE) || "/layoutDefault.jsp".equals(this.get(JSP_TEMPLATE))) { this.add(THEME, "default"); this.add(COLOR_SCHEME, "dark_blue"); } } // Determine the site theme if (this.has(THEME)) { // Use a theme and its color scheme; always use the default if the theme is missing String theme = "default"; String colorScheme = "dark_blue"; Set<String> themeFiles = context.getResourcePaths("/themes/" + this.get(THEME) + "/color-schemes"); if (themeFiles != null && themeFiles.size() > 0) { for (String thisFile : themeFiles) { if (thisFile.startsWith( "/themes/" + this.get(THEME) + "/color-schemes/" + this.get(COLOR_SCHEME))) { theme = this.get(THEME); colorScheme = this.get(COLOR_SCHEME); } } } if (!theme.equals(get(THEME))) { LOG.error("The theme (" + get(THEME) + ") and color scheme (" + get(COLOR_SCHEME) + ") could not be found, using default theme"); } addParameter(context, Constants.TEMPLATE_THEME, theme); addParameter(context, Constants.TEMPLATE_COLOR_SCHEME, colorScheme); // Determine the layout (or use the default layout) String layout = "default"; Set<String> layoutFiles = context.getResourcePaths("/themes/" + this.get(THEME) + "/jsp/"); if (layoutFiles != null && layoutFiles.size() > 0) { for (String thisFile : layoutFiles) { if (("/themes/" + this.get(THEME) + "/jsp/layout.jsp").equals(thisFile)) { layout = this.get(THEME); } } } if ("default".equals(layout) && !"default".equals(this.get(THEME))) { try { // Check for a compiled layout Class.forName("org.apache.jsp.themes." + JspUtils.makeJavaIdentifier(this.get(THEME)) + ".jsp.layout_jsp"); layout = this.get(THEME); } catch (Exception e) { LOG.info("Using default theme: " + e.getMessage()); } } addParameter(context, Constants.TEMPLATE_LAYOUT, "/themes/" + layout + "/jsp/layout.jsp"); LOG.info("THEME: " + get(THEME)); LOG.info(" COLOR SCHEME: " + get(COLOR_SCHEME)); LOG.info(" LAYOUT: " + "/themes/" + layout + "/jsp/layout.jsp"); } else { // Use the specified template addParameter(context, Constants.TEMPLATE_LAYOUT, this.get(JSP_TEMPLATE)); // Default CSS for all items on page addParameter(context, Constants.TEMPLATE_CSS, this.get(CSS_FILE)); } // Default color scheme for themeable items (deprecated) if (this.has("SKIN")) { addParameter(context, "SKIN", this.get("SKIN")); } else { addParameter(context, "SKIN", "blue"); this.add("SKIN", "blue"); } // Application Settings if (!this.has(USERS_CAN_REGISTER)) { this.add(USERS_CAN_REGISTER, "true"); } if (!this.has(USERS_CAN_INVITE)) { this.add(USERS_CAN_INVITE, "true"); } if (!this.has(SHOW_TERMS_AND_CONDITIONS)) { this.add(SHOW_TERMS_AND_CONDITIONS, "true"); } if (!this.has(USERS_CAN_START_PROJECTS)) { this.add(USERS_CAN_START_PROJECTS, "false"); } if (!this.has(USERS_ARE_ANONYMOUS)) { this.add(USERS_ARE_ANONYMOUS, "false"); } if (!this.has(SEARCH_USES_LOCATION)) { this.add(SEARCH_USES_LOCATION, "true"); } if (!this.has(SHOW_HOLIDAYS)) { this.add(SHOW_HOLIDAYS, "true"); } // Portal if (!this.has(HOME_URL)) { this.add(HOME_URL, "index.shtml"); } else if ("Portal.do?command=Default".equals(this.get(HOME_URL))) { this.add(HOME_URL, "index.shtml"); } if (!this.has("PORTAL")) { this.add("PORTAL", "true"); } if (!this.has(WEB_PAGE_TITLE)) { this.add(WEB_PAGE_TITLE, ApplicationVersion.TITLE); } if (!this.has(LANGUAGE)) { this.add(LANGUAGE, "en_US"); } if (!this.has(TIMEZONE)) { this.add(TIMEZONE, TimeZone.getDefault().getID()); } if (!this.has(CURRENCY)) { this.add(CURRENCY, NumberFormat.getCurrencyInstance().getCurrency().getCurrencyCode()); } if (!this.has(LANGUAGES_SUPPORTED)) { this.add(LANGUAGES_SUPPORTED, "en_US"); } if (!this.has(MAIN_PROFILE)) { this.add(MAIN_PROFILE, "main-profile"); } // Dimdim service if (!this.has(DIMDIM_ENABLED)) { this.add(DIMDIM_ENABLED, "false"); } if (!this.has(DIMDIM_API_DOMAIN)) { // @note Dimdim public API is no longer available //this.add(DIMDIM_API_DOMAIN, "http://webmeeting.dimdim.com/portal"); } } private void configureCache(ServletContext context) { LOG.info("configureCache"); CacheContext cacheContext = new CacheContext(); // Give the cache manager its own connection pool... this can speed up the web-tier // when background processing is occurring ConnectionPool commonCP = (ConnectionPool) context.getAttribute(Constants.CONNECTION_POOL); if (commonCP != null) { if (!this.has(CONNECTION_POOL_MAX_CACHE_CONNECTIONS)) { cacheContext.setConnectionPool(commonCP); } else { ConnectionPool cacheCP = new ConnectionPool(); cacheCP.setDebug(commonCP.getDebug()); cacheCP.setTestConnections(commonCP.getTestConnections()); cacheCP.setAllowShrinking(commonCP.getAllowShrinking()); cacheCP.setMaxConnections(this.get(CONNECTION_POOL_MAX_CACHE_CONNECTIONS)); cacheCP.setMaxIdleTime(commonCP.getMaxIdleTime()); cacheCP.setMaxDeadTime(commonCP.getMaxDeadTime()); cacheContext.setConnectionPool(cacheCP); } } if (cacheContext.getConnectionPool() != null) { // The cacheContext is ready to be finalized ConnectionElement ce = new ConnectionElement(); ce.setDriver(this.get(CONNECTION_DRIVER)); ce.setUrl(this.get(CONNECTION_URL)); ce.setUsername(this.get(CONNECTION_USER)); ce.setPassword(this.get(CONNECTION_PASSWORD)); cacheContext.setConnectionElement(ce); cacheContext.setApplicationPrefs(this); cacheContext.setKey((Key) context.getAttribute(TEAM_KEY)); Caches.addCaches(cacheContext); } } private void configureIndexer() { // Determine the Lucene Indexer Context LOG.info("Configuring Indexer..."); IndexerContext indexerContext = new IndexerContext(this); try { // Get the IndexerService instance... which configures it as well IndexerFactory.getInstance().initializeIndexService(indexerContext); } catch (Exception e) { LOG.error("configureIndexer", e); e.printStackTrace(System.out); } } /** * Configures freemarker for template loading * * @param context the servlet context to store the configuration */ private void configureFreemarker(ServletContext context) { LOG.info("configureFreemarker"); try { Configuration freemarkerConfiguration = new Configuration(); // Customized templates are stored here File customEmailFolder = new File(get(FILE_LIBRARY_PATH) + "1" + fs + "email"); FileTemplateLoader ftl = null; if (customEmailFolder.exists()) { ftl = new FileTemplateLoader(customEmailFolder); } // Default templates are stored here WebappTemplateLoader wtl = new WebappTemplateLoader(context, "/WEB-INF/email"); // Order the loaders TemplateLoader[] loaders = null; if (ftl != null) { loaders = new TemplateLoader[] { ftl, wtl }; } else { loaders = new TemplateLoader[] { wtl }; } MultiTemplateLoader mtl = new MultiTemplateLoader(loaders); freemarkerConfiguration.setTemplateLoader(mtl); freemarkerConfiguration.setObjectWrapper(new DefaultObjectWrapper()); context.setAttribute(Constants.FREEMARKER_CONFIGURATION, freemarkerConfiguration); } catch (Exception e) { LOG.error("freemarker error", e); } } /** * Utility for upgrading the application * * @param context */ private void performUpgrade(ServletContext context) { Connection db = null; ConnectionPool commonCP = (ConnectionPool) context.getAttribute(Constants.CONNECTION_POOL); try { LOG.info("Upgrading the database..."); // Share the preferences with the upgrade scripts context.setAttribute(Constants.APPLICATION_PREFS, this); // Determine the database connection to use ConnectionElement ce = new ConnectionElement(); ce.setDriver(this.get(CONNECTION_DRIVER)); ce.setUrl(this.get(CONNECTION_URL)); ce.setUsername(this.get(CONNECTION_USER)); ce.setPassword(this.get(CONNECTION_PASSWORD)); // Retrieve a database connection db = commonCP.getConnection(ce, true); // Perform the upgrade UpgradeUtils.performUpgrade(db, context); // Persist the new version info save(); } catch (Exception e) { LOG.error("performUpgrade", e); e.printStackTrace(System.out); } finally { commonCP.free(db); } } /** * Saves the Application Prefs to disk * * @param filename Description of the Parameter * @return Description of the Return Value */ public synchronized boolean save(String filename) { try { BufferedWriter out = new BufferedWriter(new FileWriter(filename)); out.write(GENERATED_MESSAGE + " on " + new java.util.Date() + " ###" + ls); add("VERSION", ApplicationVersion.VERSION); add("APP_VERSION", ApplicationVersion.APP_VERSION); add("DB_VERSION", ApplicationVersion.DB_VERSION); for (String param : prefs.keySet()) { String value = prefs.get(param); if (param.startsWith("#")) { out.write(value + ls); } else { out.write(param + "=" + value + ls); } } out.close(); return true; } catch (Exception e) { LOG.error("save", e); return false; } } /** * Saves the properties to where they were loaded from * * @return Description of the Return Value */ public boolean save() { if (this.has(FILE_LIBRARY_PATH)) { return save(this.get(FILE_LIBRARY_PATH) + "build.properties"); } return false; } /** * Adds a feature to the Parameter attribute of the ApplicationPrefs object * * @param context The feature to be added to the Parameter attribute * @param param The feature to be added to the Parameter attribute * @param value The feature to be added to the Parameter attribute */ private void addParameter(ServletContext context, String param, String value) { addParameter(context, param, value, null); } /** * Adds a feature to the Parameter attribute of the ApplicationPrefs object * * @param context The feature to be added to the Parameter attribute * @param param The feature to be added to the Parameter attribute * @param value The feature to be added to the Parameter attribute * @param defaultValue The feature to be added to the Parameter attribute */ private void addParameter(ServletContext context, String param, String value, String defaultValue) { if (value != null) { context.setAttribute(param, value); } else { if (defaultValue != null) { context.setAttribute(param, defaultValue); } else { context.removeAttribute(param); } } } /** * Save a name/value pair to the Java Preferences store * * @param instanceName Description of the Parameter * @param fileLibraryLocation Description of the Parameter * @return Description of the Return Value */ public static boolean saveFileLibraryLocation(String instanceName, String fileLibraryLocation) { try { if (instanceName == null || fileLibraryLocation == null) { LOG.error("Invalid parameters: " + instanceName + "=" + fileLibraryLocation); } Preferences javaPrefs = Preferences.userNodeForPackage(ApplicationPrefs.class); if (javaPrefs == null) { LOG.error("Couldn't create java preferences for: " + ApplicationPrefs.class); } if (instanceName.length() <= Preferences.MAX_KEY_LENGTH) { javaPrefs.put(instanceName, fileLibraryLocation); } else { javaPrefs.put(instanceName.substring(instanceName.length() - Preferences.MAX_KEY_LENGTH), fileLibraryLocation); } javaPrefs.flush(); return true; } catch (Exception e) { LOG.error("saveFileLibraryLocation", e); e.printStackTrace(System.out); return false; } } /** * Gets the configured attribute of the ApplicationPrefs object * * @return The configured value */ public boolean isConfigured() { return (this.has(FILE_LIBRARY_PATH) && !this.has("CONFIGURING")); } /** * Gets the realPath attribute of the ApplicationPrefs class * * @param context Description of the Parameter * @return The realPath value */ public static String getRealPath(ServletContext context) { String dir = context.getRealPath("/"); if (dir != null && !dir.endsWith(fs)) { dir += fs; } return dir; } /** * Gets the war attribute of the ApplicationPrefs class * * @param context Description of the Parameter * @return The war value */ public static boolean isWar(ServletContext context) { String realPath = context.getRealPath("/"); String fs = System.getProperty("file.separator"); if (realPath == null) { return true; } else if (realPath.endsWith(".war")) { return true; } else if (realPath.endsWith(".war" + fs)) { return true; } else if (realPath.indexOf("Instance") > -1) { return true; } else { return false; } } public void loadApplicationDictionaries(ServletContext context) { // Load the default String language = this.get(LANGUAGE); if (language == null) { language = "en_US"; } addDictionary(context, language); // Check for additional languages String languages = this.get(LANGUAGES_SUPPORTED); if (languages == null) { return; } // Load additional languages if (languages.indexOf(",") > -1) { StringTokenizer tokenizer = new StringTokenizer(languages, ","); while (tokenizer.hasMoreTokens()) { String langToken = tokenizer.nextToken(); addDictionary(context, langToken); } } else { if (!languages.equals(language)) { addDictionary(context, languages); } } } public synchronized void addDictionary(ServletContext context, String language) { if (language == null) { LOG.error("addDictionary: language cannot be null"); } else { if (!dictionaries.containsKey(language)) { LOG.info("Loading dictionary: " + language); try { // Create a dictionary with the default language String languagePath = "/WEB-INF/languages/"; Dictionary dictionary = new Dictionary(context, languagePath, "en_US"); if (!"en_US".equals(language)) { // Override the text with a selected language dictionary.load(context, languagePath, language); } dictionaries.put(language, dictionary); } catch (Exception e) { LOG.error("Language loading error (file exists?): " + e.getMessage(), e); } } } } public String getValue(String section, String parameter, String tagName, String language) { if (null == dictionaries) { return null; } final Dictionary dictionary = dictionaries.get(language); if (null == dictionary) { return null; } Map prefGroup = (Map) dictionary.getLocalizationPrefs().get(section); if (null != prefGroup) { Node param = (Node) prefGroup.get(parameter); if (null != param) { return XMLUtils.getNodeText(XMLUtils.getFirstChild((Element) param, tagName)); } } return null; } public String getLabel(String parameter, String language) { return getLabel("system.fields.label", parameter, language); } public String getLabel(String section, String parameter, String language) { return getValue(section, parameter, "value", language); } public static ApplicationPrefs getApplicationPrefs(ServletContext context) { return (ApplicationPrefs) context.getAttribute(Constants.APPLICATION_PREFS); } public static Configuration getFreemarkerConfiguration(ServletContext context) { return (Configuration) context.getAttribute(Constants.FREEMARKER_CONFIGURATION); } }