Java tutorial
/* * This software is distributed under the terms of the FSF * Gnu Lesser General Public License (see lgpl.txt). * * This program is distributed WITHOUT ANY WARRANTY. See the * GNU General Public License for more details. */ package com.scooterframework.admin; import java.io.File; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Observable; import java.util.Observer; import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import com.scooterframework.common.logging.LogUtil; import com.scooterframework.common.util.Converters; import com.scooterframework.common.util.PropertyFileUtil; import com.scooterframework.common.util.WordUtil; import com.scooterframework.orm.activerecord.ActiveRecord; import com.scooterframework.orm.activerecord.ActiveRecordUtil; import com.scooterframework.orm.sqldataexpress.config.DatabaseConfig; import com.scooterframework.web.controller.ActionContext; import com.scooterframework.web.controller.NoViewFileException; /** * EnvConfig class configures the application during startup time. * * <p> * You can add more mappings by using the <tt>additional.mimetypes</tt> * property in the <tt>environment.properties</tt> file. Or you can create * your own content handler plugin by extending the <tt>Plugin</tt> class * and implementing the <tt>ContentHandler</tt> interface. * * @author (Fei) John Chen */ public class EnvConfig implements Observer { private static LogUtil log = LogUtil.getLogger(EnvConfig.class.getName()); public static final String EXTENSION_MIMETYPES_RESOURCE = "/com/scooterframework/admin/extension_mimetypes.properties"; public static final String DATA_PROPERTIES_FILE = "environment.properties"; public static final String DEFAULT_VALUE_defaultViewFilesDirectory = "builtin/crud"; //**************************************************** // Default values for keys in the properties file //**************************************************** public static final String DEFAULT_VALUE_siteAdminUsername = null; public static final String DEFAULT_VALUE_siteAdminPassword = null; public static final String DEFAULT_VALUE_modelClassPrefix = "models"; public static final String DEFAULT_VALUE_modelClassSuffix = ""; public static final String DEFAULT_VALUE_controllerClassPrefix = "controllers"; public static final String DEFAULT_VALUE_controllerClassSuffix = "Controller"; public static final String DEFAULT_VALUE_allowDefaultControllerClass = "false"; public static final String DEFAULT_VALUE_actionExtension = ""; public static final String DEFAULT_VALUE_defaultActionMethod = "index"; public static final String DEFAULT_VALUE_allowDefaultActionMethod = "true"; public static final String DEFAULT_VALUE_webPageDirectoryName = "WEB-INF/views"; public static final String DEFAULT_VALUE_allowForwardToControllerNameViewWhenControllerNotExist = "true"; public static final String DEFAULT_VALUE_allowForwardToActionNameViewWhenActionNotExist = "true"; public static final String DEFAULT_VALUE_runningEnvironment = Constants.RUNNING_ENVIRONMENT_DEVELOPMENT; public static final String DEFAULT_VALUE_passwordScheme = ""; public static final String DEFAULT_VALUE_benchmark = "true"; public static final String DEFAULT_VALUE_benchmarkInHeader = "true"; public static final String DEFAULT_VALUE_locale_language = null; public static final String DEFAULT_VALUE_locale_country = null; public static final String DEFAULT_VALUE_locale_variant = null; public static final Locale DEFAULT_VALUE_gloabalLocale = null; public static final String DEFAULT_VALUE_messageResourcesFileBase = "messages"; public static final String DEFAULT_VALUE_viewExtension = "jsp"; public static final String DEFAULT_VALUE_rootURL = "/WEB-INF/views/index.jsp"; public static final String DEFAULT_VALUE_errorPageURI = "/WEB-INF/views/error.jsp"; public static final String DEFAULT_VALUE_compileErrorPageURI = "/WEB-INF/views/compileError.jsp"; public static final String DEFAULT_VALUE_allowDisplayingErrorDetails = "true"; public static final String DEFAULT_VALUE_allowDataBrowser = "true"; public static final String DEFAULT_VALUE_additionalMimeTypes = ""; public static final String DEFAULT_VALUE_additionalSinglePlural = ""; public static final String DEFAULT_VALUE_defaultCacheProvider = null; public static final String DEFAULT_VALUE_defaultCacheName = ApplicationConfig.getInstance().getContextName(); public static final String DEFAULT_VALUE_useRequestCache = "true"; public static final String DEFAULT_VALUE_useSecondLevelCache = "false"; public static final String DEFAULT_VALUE_flushCacheOnChange = "true"; public static final String DEFAULT_VALUE_localUseCacheExceptions = null; public static final String DEFAULT_VALUE_localFlushCacheExceptions = null; public static final String DEFAULT_VALUE_allowCacheAssociatedObjects = "false"; public static final String DEFAULT_VALUE_upload_file_repository = null; public static final String DEFAULT_VALUE_maximum_bytes_per_uploaded_file_in_memory = "10240"; public static final String DEFAULT_VALUE_maximum_total_bytes_per_upload_request = "-1"; public static final String DEFAULT_VALUE_maximum_bytes_per_uploaded_file = "-1"; private static EnvConfig me; private Properties appProperties = null; private static Map<String, String> defaultMimeTypesMap = new HashMap<String, String>(); private String siteAdminUsername = DEFAULT_VALUE_siteAdminUsername; private String siteAdminPassword = DEFAULT_VALUE_siteAdminPassword; private String modelClassPrefix = DEFAULT_VALUE_modelClassPrefix; private String modelClassSuffix = DEFAULT_VALUE_modelClassSuffix; private String controllerClassPrefix = DEFAULT_VALUE_controllerClassPrefix; private String controllerClassSuffix = DEFAULT_VALUE_controllerClassSuffix; private String allowDefaultControllerClass = DEFAULT_VALUE_allowDefaultControllerClass; private String defaultActionMethod = DEFAULT_VALUE_defaultActionMethod; private String allowDefaultActionMethod = DEFAULT_VALUE_allowDefaultActionMethod; private String webPageDirectoryName = DEFAULT_VALUE_webPageDirectoryName; private String allowForwardToControllerNameViewWhenControllerNotExist = DEFAULT_VALUE_allowForwardToControllerNameViewWhenControllerNotExist; private String allowForwardToActionNameViewWhenActionNotExist = DEFAULT_VALUE_allowForwardToActionNameViewWhenActionNotExist; private String runningEnvironment = DEFAULT_VALUE_runningEnvironment; private String passwordScheme = DEFAULT_VALUE_passwordScheme; private String benchmark = DEFAULT_VALUE_benchmark; private String benchmarkInHeader = DEFAULT_VALUE_benchmarkInHeader; private Locale gloabalLocale = DEFAULT_VALUE_gloabalLocale; private String messageResourcesFileBase = DEFAULT_VALUE_messageResourcesFileBase; private String actionExtension = DEFAULT_VALUE_actionExtension; private String viewExtension = DEFAULT_VALUE_viewExtension; private String rootURL = DEFAULT_VALUE_rootURL; private String errorPageURI = DEFAULT_VALUE_errorPageURI; private String compileErrorPageURI = DEFAULT_VALUE_compileErrorPageURI; private String allowDisplayingErrorDetails = DEFAULT_VALUE_allowDisplayingErrorDetails; private String allowDataBrowser = DEFAULT_VALUE_allowDataBrowser; private String additionalMimeTypes = DEFAULT_VALUE_additionalMimeTypes; private String additionalSinglePlural = DEFAULT_VALUE_additionalSinglePlural; private String defaultCacheProvider = DEFAULT_VALUE_defaultCacheProvider; private String defaultCacheName = DEFAULT_VALUE_defaultCacheName; private String uploadFileRepository = DEFAULT_VALUE_upload_file_repository; private String useRequestCache = DEFAULT_VALUE_useRequestCache; private String useSecondLevelCache = DEFAULT_VALUE_useSecondLevelCache; private String flushCacheOnChange = DEFAULT_VALUE_flushCacheOnChange; private String localUseCacheExceptions = DEFAULT_VALUE_localUseCacheExceptions; private String localFlushCacheExceptions = DEFAULT_VALUE_localFlushCacheExceptions; private String allowCacheAssociatedObjects = DEFAULT_VALUE_allowCacheAssociatedObjects; private String maximumBytesPerUploadedFileInMemory = DEFAULT_VALUE_maximum_bytes_per_uploaded_file_in_memory; private String maximumTotalBytesPerUploadRequest = DEFAULT_VALUE_maximum_total_bytes_per_upload_request; private String maximumBytesPerUploadedFile = DEFAULT_VALUE_maximum_bytes_per_uploaded_file; private DiskFileItemFactory fileFactory; private ServletFileUpload fileUpload; private ConcurrentMap<String, Object> cacheProvidersMap = new ConcurrentHashMap<String, Object>(); private ConcurrentMap<String, String> mimeTypesMap = new ConcurrentHashMap<String, String>(); static { try { Properties extMimeMapping = PropertyFileUtil.loadPropertiesFromResource(EXTENSION_MIMETYPES_RESOURCE); for (Map.Entry<Object, Object> entry : extMimeMapping.entrySet()) { Object name = entry.getKey(); Object value = entry.getValue(); if (name != null && value != null) defaultMimeTypesMap.put(name.toString(), value.toString()); } me = new EnvConfig(); } catch (Exception ex) { log.fatal("Error instantiating EnvConfig: " + ex.getMessage()); ex.printStackTrace(); } } private EnvConfig() { init(); PropertyFileChangeMonitor.getInstance().registerObserver(this, DATA_PROPERTIES_FILE); EventsManager.getInstance().registerListener(Constants.EVENT_COMPILE, SoundPlayer.getInstance()); } private void clear() { mimeTypesMap.clear(); cacheProvidersMap.clear(); PluginManager.getInstance().removePlugins(); fileFactory = null; fileUpload = null; } private void init() { clear(); mimeTypesMap.putAll(defaultMimeTypesMap); loadProperties(); siteAdminUsername = getProperty("site.admin.username", DEFAULT_VALUE_siteAdminUsername); siteAdminPassword = getProperty("site.admin.password", DEFAULT_VALUE_siteAdminPassword); controllerClassPrefix = getProperty("controller.class.prefix", DEFAULT_VALUE_controllerClassPrefix); controllerClassSuffix = getProperty("controller.class.suffix", DEFAULT_VALUE_controllerClassSuffix); modelClassPrefix = getProperty("model.class.prefix", DEFAULT_VALUE_modelClassPrefix); modelClassSuffix = getProperty("model.class.suffix", DEFAULT_VALUE_modelClassSuffix); allowDefaultControllerClass = getProperty("auto.crud", DEFAULT_VALUE_allowDefaultControllerClass); actionExtension = getProperty("action.extension", DEFAULT_VALUE_actionExtension); if (!actionExtension.startsWith(".") && !"".equals(actionExtension)) actionExtension = "." + actionExtension; viewExtension = getProperty("view.extension", DEFAULT_VALUE_viewExtension); if (!viewExtension.startsWith(".") && !"".equals(viewExtension)) viewExtension = "." + viewExtension; defaultActionMethod = getProperty("default.action.method", DEFAULT_VALUE_defaultActionMethod); allowDefaultActionMethod = getProperty("allow.default.action.method", DEFAULT_VALUE_allowDefaultActionMethod); webPageDirectoryName = getProperty("webpage.directory.name", DEFAULT_VALUE_webPageDirectoryName); allowForwardToControllerNameViewWhenControllerNotExist = getProperty( "allow.forward.to.controller.name.view.when.controller.not.exist", DEFAULT_VALUE_allowForwardToControllerNameViewWhenControllerNotExist); allowForwardToActionNameViewWhenActionNotExist = getProperty( "allow.forward.to.action.name.view.when.action.not.exist", DEFAULT_VALUE_allowForwardToActionNameViewWhenActionNotExist); rootURL = getProperty("root.url", DEFAULT_VALUE_rootURL); if (!rootURL.startsWith("/")) rootURL = "/" + rootURL; runningEnvironment = getProperty("running.environment", DEFAULT_VALUE_runningEnvironment); ApplicationConfig.getInstance().setRunningEnvironment(runningEnvironment); passwordScheme = getProperty("password.scheme", DEFAULT_VALUE_passwordScheme); benchmark = getProperty("benchmark", DEFAULT_VALUE_benchmark); benchmarkInHeader = getProperty("benchmark.in.header", DEFAULT_VALUE_benchmarkInHeader); String language = getProperty("locale.language", DEFAULT_VALUE_locale_language); String country = getProperty("locale.country", DEFAULT_VALUE_locale_country); String variant = getProperty("locale.variant", DEFAULT_VALUE_locale_variant); if (language != null && country != null && variant != null) { gloabalLocale = new Locale(language, country, variant); } else if (language != null && country != null) { gloabalLocale = new Locale(language, country); } else if (language != null) { gloabalLocale = new Locale(language); } else { gloabalLocale = DEFAULT_VALUE_gloabalLocale; } ActionContext.setGlobalLocale(gloabalLocale); messageResourcesFileBase = getProperty("message.resources.file.base", DEFAULT_VALUE_messageResourcesFileBase); errorPageURI = getProperty("app.error.page.uri", DEFAULT_VALUE_errorPageURI); compileErrorPageURI = getProperty("app.compile.error.page.uri", DEFAULT_VALUE_compileErrorPageURI); allowDisplayingErrorDetails = getProperty("allow.displaying.error.details", DEFAULT_VALUE_allowDisplayingErrorDetails); allowDataBrowser = getProperty("allow.databrowser", DEFAULT_VALUE_allowDataBrowser); additionalMimeTypes = getProperty("additional.mimetypes", DEFAULT_VALUE_additionalMimeTypes); additionalSinglePlural = getProperty("additional.single.plural", DEFAULT_VALUE_additionalSinglePlural); Map<String, String> mimeTypes = Converters.convertStringToMap(additionalMimeTypes, ":", ","); mimeTypesMap.putAll(mimeTypes); Map<String, String> words = Converters.convertStringToMap(additionalSinglePlural, ":", ","); for (Map.Entry<String, String> entry : words.entrySet()) { String value = entry.getValue(); WordUtil.addPlural(entry.getKey(), (value != null) ? value : (String) null); } Enumeration<Object> en = appProperties.keys(); while (en.hasMoreElements()) { String key = (String) en.nextElement(); if (key.startsWith("plugin")) { String name = key.substring(key.indexOf('.') + 1); Properties p = PropertyFileUtil.parseNestedPropertiesFromLine(getProperty(key), "=", ","); p.setProperty(Plugin.KEY_PLUGIN_NAME, name); PluginManager.getInstance().registerPlugin(name, p); if (key.startsWith("plugin.cache.provider.")) { cacheProvidersMap.put(key.substring("plugin.cache.provider.".length()), p); } } } defaultCacheProvider = getProperty("default.cache.provider.name", DEFAULT_VALUE_defaultCacheProvider); if (defaultCacheProvider != null && !cacheProvidersMap.keySet().contains(defaultCacheProvider)) { log.error("There is no definition for default cache provider " + defaultCacheProvider); } defaultCacheName = getProperty("default.cache.name", DEFAULT_VALUE_defaultCacheName); useRequestCache = getProperty("useRequestCache", DEFAULT_VALUE_useRequestCache); useSecondLevelCache = getProperty("useSecondLevelCache", DEFAULT_VALUE_useSecondLevelCache); flushCacheOnChange = getProperty("flushCacheOnChange", DEFAULT_VALUE_flushCacheOnChange); localUseCacheExceptions = getProperty("localUseCacheExceptions", DEFAULT_VALUE_localUseCacheExceptions); localFlushCacheExceptions = getProperty("localFlushCacheExceptions", DEFAULT_VALUE_localFlushCacheExceptions); allowCacheAssociatedObjects = getProperty("allowCacheAssociatedObjects", DEFAULT_VALUE_allowCacheAssociatedObjects); uploadFileRepository = getProperty("upload.file.repository", DEFAULT_VALUE_upload_file_repository); maximumBytesPerUploadedFileInMemory = getProperty("maximum.bytes.per.uploaded.file.in.memory", DEFAULT_VALUE_maximum_bytes_per_uploaded_file_in_memory); maximumTotalBytesPerUploadRequest = getProperty("maximum.total.bytes.per.upload.request", DEFAULT_VALUE_maximum_total_bytes_per_upload_request); maximumBytesPerUploadedFile = getProperty("maximum.bytes.per.uploaded.file", DEFAULT_VALUE_maximum_bytes_per_uploaded_file); configFileUpload(); } private void loadProperties() { if (appProperties != null) appProperties.clear(); appProperties = PropertyReader.loadPropertiesFromFile(DATA_PROPERTIES_FILE); if (appProperties == null) appProperties = new Properties(); } /* * Configures file upload setting. */ private void configFileUpload() { int maxMemorySize = getMaximumBytesPerUploadedFileInMemory(); String uploadDirectory = getUploadFileRepository(); long maxRequestSize = getMaximumTotalBytesPerUploadRequest(); long fileSizeMax = getMaximumBytesPerUploadedFile(); fileFactory = (uploadDirectory == null) ? new DiskFileItemFactory(maxMemorySize, null) : new DiskFileItemFactory(maxMemorySize, new File(uploadDirectory)); fileUpload = new ServletFileUpload(fileFactory); fileUpload.setSizeMax(maxRequestSize); fileUpload.setFileSizeMax(fileSizeMax); } private void initializePlugins() { PluginManager.getInstance().startPlugins(); } public static EnvConfig getInstance() { return me; } public void update(Observable o, Object arg) { init(); initializePlugins(); } /** * Returns all properties. */ public Properties getProperties() { return appProperties; } /** * Returns a String property corresponding to a key. */ public String getProperty(String key) { return appProperties.getProperty(key); } /** * Returns a String property corresponding to a key. The method returns the * default value argument if the property is not found. */ public String getProperty(String key, String defaultValue) { return appProperties.getProperty(key, defaultValue); } /** * Returns site admin username. */ public String getSiteAdminUsername() { return siteAdminUsername; } /** * Returns site admin password. */ public String getSiteAdminPassword() { return siteAdminPassword; } /** * Returns action extension * * @return action extension */ public String getActionExtension() { return actionExtension; } /** * Returns view extension * * @return view extension */ public String getViewExtension() { return viewExtension; } /** * Returns root url. * * @return root url */ public String getRootURL() { return rootURL; } /** * Returns controller class name prefix. */ public String getControllerClassPrefix() { return controllerClassPrefix; } /** * Returns controller class name suffix. */ public String getControllerClassSuffix() { return controllerClassSuffix; } /** * Checks if a built-in default controller class is allowed to use. */ public boolean allowDefaultControllerClass() { return ("true".equalsIgnoreCase(allowDefaultControllerClass)) ? true : false; } /** * Alias of <tt>allowDefaultControllerClass</tt> method. */ public boolean allowAutoCRUD() { return allowDefaultControllerClass(); } /** * Returns default method name of a controller class. */ public String getDefaultActionMethod() { return defaultActionMethod; } /** * Checks if a default action name is used when an action method is not * obtained from parsing a url. */ public boolean allowDefaultActionMethod() { return ("true".equalsIgnoreCase(allowDefaultActionMethod)) ? true : false; } /** * Returns model class name prefix. */ public String getModelClassPrefix() { return modelClassPrefix; } /** * Returns model class name suffix. */ public String getModelClassSuffix() { return modelClassSuffix; } /** * Returns directory name which contains all web pages. */ public String getWebPageDirectoryName() { if (webPageDirectoryName == null) return ""; if (!"".equals(webPageDirectoryName) && !webPageDirectoryName.startsWith("/")) { webPageDirectoryName = "/" + webPageDirectoryName; } return webPageDirectoryName; } /** * Returns action URI for a specific action method. * * If there is no extension type in the action name, the action is treated * as an extension type defined in config properties file. For example, * if the action is "show", the action could be treated as "show.do" action if * the <tt>actionExtension</tt> property is defined as ".do". * * <pre> * Examples: * getActionUriFor("list") => list.do (extension = .do) * </pre> * @param action the action method * @return action URI string */ public static String getActionUriFor(String action) { return getActionUriFor(null, action); } /** * Returns action URI for a controller path with a specific action method. * * If there is no extension type in the action name, the action is treated * as an extension type defined in config properties file. For example, * if the action is "show", the action could be treated as "show.do" action if * the <tt>actionExtension</tt> property is defined as ".do". * * <pre> * Examples: * getActionUriFor("/posts", "list") => /posts/list.do * </pre> * @param controllerPath path to the action * @param action the action method * @return action URI string */ public static String getActionUriFor(String controllerPath, String action) { if (action == null || "".equals(action)) { if (getInstance().allowDefaultActionMethod()) { action = getInstance().getDefaultActionMethod(); } else { throw new IllegalArgumentException( "The value for action " + "input cannot be null or empty unless the default action " + "method is specified in property file."); } } if (!action.endsWith(EnvConfig.getInstance().getActionExtension())) { action += EnvConfig.getInstance().getActionExtension(); } return (controllerPath == null || "".equals(controllerPath)) ? action : (controllerPath + "/" + action); } /** * <p> * Returns view URI for a controller with a specific action.</p> * * <p> * If there is no extension type in the view name, the view is treated * as an extension type defined in config properties file. For example, * if the view is "show", the view could be treated as "show.jsp" action if * the <tt>view.extension</tt> property is defined as ".jsp". The directory * path for view files is set by the <tt>webpage.directory.name</tt> * property in properties file.</p> * * <pre> * Examples: * If your JSP web pages are under webapp: * webpage.directory.name="" * getViewURI("posts", "list") => /posts/list.jsp * * If your jsp web pages are under WEB-INF/views: * webpage.directory.name="WEB-INF/views" (default) * getViewURI("posts", "list") => /WEB-INF/views/posts/list.jsp * </pre> * @param controller controller name * @param actionOrView the action method name or view name * @return view URI. */ public static String getViewURI(String controller, String actionOrView) { return getViewURI(controller, actionOrView, null); } /** * Returns a view URI. This URI is a real view file associated with the * controller and the action or view name. * * @param controller the name of the controller * @param actionOrView the action method name or view name * @return view URI. */ public static String getViewURI(String controller, String actionOrView, String defaultViewDir) { if (controller == null) { controller = ""; } else { controller = controller.toLowerCase(); } if (!controller.startsWith("/") && !"".equals(controller)) controller = "/" + controller; if (actionOrView == null || "".equals(actionOrView)) { if (getInstance().allowDefaultActionMethod()) { actionOrView = getInstance().getDefaultActionMethod(); } else { throw new IllegalArgumentException( "The value for action " + "input cannot be null or empty unless the default action " + "method is specified in property file."); } } if (!actionOrView.endsWith(EnvConfig.getInstance().getViewExtension()) && actionOrView.indexOf('.') == -1) { actionOrView += EnvConfig.getInstance().getViewExtension(); } String uri = ""; if (!actionOrView.startsWith("/")) { uri = EnvConfig.getInstance().getWebPageDirectoryName() + controller + "/" + actionOrView; } else { uri = EnvConfig.getInstance().getWebPageDirectoryName() + controller + actionOrView; } String realPath = getRealPath(); String filePath = realPath + uri; File f = new File(filePath); if (!f.exists()) { if (defaultViewDir != null) { log.warn("File \"" + filePath + "\" does not exist. Use " + "default view file in \"" + defaultViewDir + "\"."); return getViewURI(defaultViewDir, actionOrView, null); } else { String errorMsg = "View file \"" + filePath + "\" does not exist."; log.error(errorMsg); throw new NoViewFileException(errorMsg, filePath); } } return uri; } /** * Returns real path of the application. * * @return real path of the application. */ public static String getRealPath() { return ApplicationConfig.getInstance().getApplicationPath(); } /** * Returns directory name which contains default view files. * * Default view files directory specifies directory name for default view * files. These view files are related to the non-restful way of actions. * For restful way of requests, the default view files are in * {DEFAULT_VALUE_defaultViewFilesDirectory}_restful directory. */ public String getDefaultViewFilesDirectory() { return DEFAULT_VALUE_defaultViewFilesDirectory; } /** * Returns directory name which contains default view files for builtin * RestfulCRUDController or RestfulRequestProcessor. */ public String getDefaultViewFilesDirectoryForREST() { return DEFAULT_VALUE_defaultViewFilesDirectory + "_restful"; } /** * Checks if controller name is used as a view when the controller does not exist. */ public boolean allowForwardToControllerNameViewWhenControllerNotExist() { return ("true".equalsIgnoreCase(allowForwardToControllerNameViewWhenControllerNotExist)) ? true : false; } /** * Checks if action name is used as a view when the action does not exist. */ public boolean allowForwardToActionNameViewWhenActionNotExist() { return ("true".equalsIgnoreCase(allowForwardToActionNameViewWhenActionNotExist)) ? true : false; } /** * Returns server type */ public String getServerType() { return ApplicationConfig.getInstance().getConfiguredMode(); } /** * Returns password scheme */ public String getPasswordScheme() { return passwordScheme; } public String applyPasswordScheme(String password) { if (passwordScheme == null || "".equals(passwordScheme)) return password; return passwordScheme + "(" + password + ")"; } /** * Returns full controller class name. * * @param controllerPath controller path * @return full java class name */ public String getControllerClassName(String controllerPath) { String fullName = Converters.convertToJavaClassLikeString(controllerPath.toLowerCase()); String prefix = getControllerClassPrefix(); String suffix = getControllerClassSuffix(); if (!fullName.startsWith(prefix) && prefix != null && !"".equals(prefix)) { fullName = prefix + "." + fullName; } if (!fullName.endsWith(getControllerClassSuffix()) && suffix != null && !"".equals(suffix)) { fullName = fullName + getControllerClassSuffix(); } return fullName; } /** * Returns controller name in lower case. * * @param fullClassName full class name of the controller * @return short controller name (in lower case) */ public String getControllerName(String fullClassName) { if (fullClassName.indexOf('.') == -1) return fullClassName; String controller = fullClassName.substring(fullClassName.lastIndexOf('.') + 1); String suffix = getControllerClassSuffix(); if (!"".equals(suffix) && controller.indexOf(suffix) != -1) { controller = controller.substring(0, controller.indexOf(suffix)); } return controller.toLowerCase(); } /** * Returns full model class name. * * @param model model name * @return full java class name */ public String getModelClassName(String model) { String fullName = Converters.convertToJavaClassLikeString(model); if (!model.startsWith(getModelClassPrefix())) { fullName = getModelClassPrefix() + "." + fullName; } if (!model.endsWith(getModelClassSuffix())) { fullName = fullName + getModelClassSuffix(); } return fullName; } /** * Returns model class name based on controller class name. */ public String getModelClassNameFromControllerClassName(String controllerClassName) { String controller = getControllerName(controllerClassName); String model = (DatabaseConfig.getInstance().usePluralTableName()) ? WordUtil.singularize(controller) : controller; return getModelClassName(model); } /** * <p>Returns home instance of a model.</p> * * <p>A home instance of a record is a read-only instance for a model type. * Its main function is to provide meta information of the model and some * finder methods.</p> * * @param model name corresponding to the model home instance * @return a home instance of a model */ public ActiveRecord getHomeInstance(String model) { return ActiveRecordUtil.getHomeInstance(getModelClassName(model)); } /** * Checks if bench mark info is allowed to record. * * @return true if allowed */ public boolean allowRecordBenchmark() { return ("true".equalsIgnoreCase(benchmark)) ? true : false; } /** * Checks if bench mark info is allowed to record in header. * * @return true if allowed */ public boolean allowRecordBenchmarkInHeader() { return ("true".equalsIgnoreCase(benchmarkInHeader)) ? true : false; } /** * Returns configured locale. */ public Locale getGlobalLocale() { return gloabalLocale; } /** * Returns the language for the configured locale. */ public String getGlobalLanguage() { return (gloabalLocale != null) ? gloabalLocale.getLanguage() : null; } /** * Returns the country for the configured locale. */ public String getGlobalCountry() { return (gloabalLocale != null) ? gloabalLocale.getCountry() : null; } /** * Returns the variant for the configured locale. */ public String getGlobalVariant() { return (gloabalLocale != null) ? gloabalLocale.getVariant() : null; } /** * Returns the base name of message files. */ public String getMessageResourcesFileBase() { return messageResourcesFileBase; } /** * Returns error page URI. */ public String getErrorPageURI() { return errorPageURI; } /** * Returns compile error page URI. */ public String getCompileErrorPageURI() { return compileErrorPageURI; } /** * Checks if displaying error details is allowed. * * @return true if allowed */ public boolean allowDisplayingErrorDetails() { return ("true".equalsIgnoreCase(allowDisplayingErrorDetails)) ? true : false; } /** * Checks if DataBroser is allowed. * * @return true if allowed */ public boolean allowDataBrowser() { return ("true".equalsIgnoreCase(allowDataBrowser)) ? true : false; } /** * Returns cache provider properties */ public Properties getPredefinedCacheProviderProperties(String providerName) { Properties p = (Properties) cacheProvidersMap.get(providerName); return (p != null) ? p : (new Properties()); } /** * Returns cache provider names */ public Iterator<String> getPredefinedCacheProviderNames() { return cacheProvidersMap.keySet().iterator(); } /** * Returns default cache provider name */ public String getDefaultCacheProviderName() { return defaultCacheProvider; } /** * Returns default cache name */ public String getDefaultCacheName() { return defaultCacheName; } /** * Returns default cache provider properties */ public Properties getDefaultCacheProviderProperties() { return getPredefinedCacheProviderProperties(getDefaultCacheProviderName()); } /** * Checks if using thread cache for all model classes. * * @return true if using thread cache */ public boolean getUseThreadCache() { return "true".equals(useRequestCache); } /** * Checks if using second-level cache for all model classes. * * @return true if using second-level cache */ public boolean getUseSecondLevelCache() { return "true".equals(useSecondLevelCache); } /** * Checks if using second-level cache for all model classes. * * @return true if using second-level cache */ public boolean getFlushCacheOnChange() { return "true".equals(flushCacheOnChange); } /** * Returns a collection methods that are exceptional to the setting of * <tt>useRequestCache</tt> and <tt>useSecondLevelCache</tt>. * * @return true if using thread cache */ public Collection<String> getLocalUseCacheExceptions(String modelClassName) { if (localUseCacheExceptions == null) return null; Set<String> localUseCacheExceptionsSet = new HashSet<String>(); StringTokenizer st = new StringTokenizer(localUseCacheExceptions, ","); while (st.hasMoreTokens()) { String token = st.nextToken().trim(); if (token.startsWith(modelClassName)) localUseCacheExceptionsSet.add(token); } return localUseCacheExceptionsSet; } /** * Returns a collection methods that are exceptional to the setting of * <tt>useRequestCache</tt> and <tt>useSecondLevelCache</tt>. * * @return a collection of exceptional method names */ public Collection<String> getLocalFlushCacheExceptions(String modelClassName) { if (localFlushCacheExceptions == null) return null; Set<String> localFlushCacheExceptionsSet = new HashSet<String>(); StringTokenizer st = new StringTokenizer(localFlushCacheExceptions, ","); while (st.hasMoreTokens()) { String token = st.nextToken().trim(); if (token.startsWith(modelClassName)) localFlushCacheExceptionsSet.add(token); } return localFlushCacheExceptionsSet; } /** * Checks if using second-level cache. * * @return true if using second-level cache */ public boolean allowCacheAssociatedObjects(String modelClassName) { return "true".equals(allowCacheAssociatedObjects); } /** * Returns plugin properties */ public Properties getPluginProperties(String pluginName) { return PluginManager.getInstance().getPluginProperties(pluginName); } /** * Returns the extension/mimetype mapping. */ public Map<String, String> getMimeTypeMap() { return mimeTypesMap; } /** * Returns MIME type corresponding the specific extension. * * @param extension The extension string. * @return the MIME type string for the extension. */ public String getMimeType(String extension) { Object o = mimeTypesMap.get(extension); return (o != null) ? o.toString() : (String) null; } /** * Checks if the specific <tt>extension</tt> has a registered MIME type. * * @param extension The extension string. * @return true if there is a MIME type for the <tt>extension</tt>. */ public boolean hasMimeTypeFor(String extension) { return mimeTypesMap.containsKey(extension); } /** * Returns file directory for storing uploaded files. */ public String getUploadFileRepository() { if (uploadFileRepository == null || "null".equals(uploadFileRepository) || "".equals(uploadFileRepository)) return null; return uploadFileRepository; } /** * Returns the threshold, in bytes, below which items will be retained in * memory and above which they will be stored as a file. * The default value is 10240 bytes. */ public int getMaximumBytesPerUploadedFileInMemory() { return Integer.valueOf(maximumBytesPerUploadedFileInMemory); } /** * Returns the maximum allowed bytes of an upload request. * The default value of -1 indicates, that there is no limit. */ public long getMaximumTotalBytesPerUploadRequest() { return Long.valueOf(maximumTotalBytesPerUploadRequest); } /** * Returns the maximum allowed bytes of an upload file. * The default value of -1 indicates, that there is no limit. */ public long getMaximumBytesPerUploadedFile() { return Long.valueOf(maximumBytesPerUploadedFile); } /** * Returns DiskFileItemFactory instance for file upload. */ public DiskFileItemFactory getDiskFileItemFactory() { if (fileFactory == null) { configFileUpload(); } return fileFactory; } /** * Returns ServletFileUpload instance for file upload. */ public ServletFileUpload getServletFileUpload() { if (fileUpload == null) { configFileUpload(); } return fileUpload; } /** * Checks whether a file is a text file. * * @param file the file to check * @return true if it is a text file. */ public boolean isTextFile(File file) { if (file == null) return false; String fName = file.getName(); String extension = fName.substring(fName.lastIndexOf('.') + 1); return isTextFile(extension); } /** * Checks whether a file extension indicates that it is a text file. * * @param extension the file extension to check * @return true if it is a text file. */ public boolean isTextFile(String extension) { if (extension == null) return false; boolean result = false; String mimeType = EnvConfig.getInstance().getMimeType(extension); if ((mimeType != null && (mimeType.startsWith("text") || mimeType.endsWith("xml"))) || "csh".equalsIgnoreCase(extension) || "dtd".equalsIgnoreCase(extension) || "js".equalsIgnoreCase(extension)) { result = true; } return result; } /** * Checks if the content of the file can be highlighted. Only a selected * types of file extensions are highlightable. * * @param fileExtension * @return true if highlightable */ public boolean isHighlightable(String fileExtension) { return isTextFile(fileExtension); } }