package act.conf;
/*-
* #%L
* ACT Framework
* %%
* Copyright (C) 2014 - 2017 ActFramework
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import act.Act;
import act.Constants;
import act.app.ActionContext;
import act.app.App;
import act.app.AppHolder;
import act.app.ProjectLayout;
import act.app.conf.AppConfigurator;
import act.app.event.AppEventId;
import act.app.util.NamedPort;
import act.cli.CliOverHttpAuthority;
import act.db.util.SequenceNumberGenerator;
import act.db.util._SequenceNumberGenerator;
import act.handler.UnknownHttpMethodProcessor;
import act.handler.event.ResultEvent;
import act.i18n.I18n;
import act.security.CSRFProtector;
import act.util.*;
import act.view.TemplatePathResolver;
import act.view.View;
import org.osgl.$;
import org.osgl.Osgl;
import org.osgl.cache.CacheService;
import org.osgl.cache.CacheServiceProvider;
import org.osgl.exception.ConfigurationException;
import org.osgl.exception.NotAppliedException;
import org.osgl.http.H;
import org.osgl.logging.L;
import org.osgl.logging.Logger;
import org.osgl.mvc.MvcConfig;
import org.osgl.util.*;
import org.osgl.web.util.UserAgent;
import javax.inject.Provider;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import static act.conf.AppConfigKey.*;
public class AppConfig<T extends AppConfigurator> extends Config<AppConfigKey> implements AppHolder<AppConfig<T>> {
protected static Logger logger = L.get(AppConfig.class);
public static final String CONF_FILE_NAME = "app.conf";
public static final String PORT_CLI_OVER_HTTP = "__admin__";
private App app;
static {
MvcConfig.errorPageRenderer(new ActErrorPageRender());
MvcConfig.beforeCommitResultHandler(ResultEvent.BEFORE_COMMIT_HANDLER);
MvcConfig.afterCommitResultHandler(ResultEvent.AFTER_COMMIT_HANDLER);
MvcConfig.messageTranslater(new $.Transformer<String, String>() {
@Override
public String transform(String message) {
if (Act.appConfig().i18nEnabled()) {
String translated = I18n.i18n(true, I18n.locale(), I18n.DEF_RESOURCE_BUNDLE_NAME, message);
if (message == translated) {
translated = I18n.i18n(true, I18n.locale(), MvcConfig.class.getName(), message);
message = translated;
}
return message;
}
return message;
}
});
}
/**
* Construct a <code>AppConfig</code> with a map. The map is copied to
* the original map of the configuration instance
*
* @param configuration
*/
public AppConfig(Map<String, ?> configuration) {
super(configuration);
}
public AppConfig() {
this((Map) System.getProperties());
}
public AppConfig<T> app(App app) {
E.NPE(app);
this.app = app;
AppConfigKey.onApp(app);
return this;
}
public void preloadConfigurations() {
// preload frequently used configurations so
// that we do not need to synchronize on them
// and avoid the NPE
basicAuthenticationEnabled();
corsEnabled();
sessionCookieName();
cookiePrefix();
encryptSession();
sessionMapper();
sessionKeyUsername();
sessionSecure();
sessionTtl();
MvcConfig.renderJsonOutputCharset(renderJsonOutputCharset());
Osgl.Func0<H.Format> jsonContentProvider = jsonContentTypeProvider();
if (null != jsonContentTypeProvider) {
MvcConfig.jsonMediaTypeProvider(jsonContentProvider);
}
}
public App app() {
return app;
}
@Override
protected ConfigKey keyOf(String s) {
return AppConfigKey.valueOfIgnoreCase(s);
}
private Boolean basicAuth;
protected T enableBasicAuthentication(boolean b) {
this.basicAuth = b;
return me();
}
public boolean basicAuthenticationEnabled() {
if (null == basicAuth) {
Boolean B = get(BASIC_AUTHENTICATION);
if (null == B) {
B = Act.isDev();
}
this.basicAuth = B;
}
return this.basicAuth;
}
private void _mergeBasicAuthentication(AppConfig conf) {
if (!hasConfiguration(BASIC_AUTHENTICATION)) {
this.basicAuth = conf.basicAuth;
}
}
private Boolean cors;
protected T enableCors(boolean b) {
this.cors = b;
return me();
}
public boolean corsEnabled() {
if (null == cors) {
Boolean B = get(CORS);
if (null == B) {
B = false;
}
this.cors = B;
}
return this.cors;
}
private void _mergeCors(AppConfig conf) {
if (!hasConfiguration(CORS)) {
this.cors = conf.cors;
}
}
private String corsOrigin;
protected T corsAllowOrigin(String s) {
this.corsOrigin = s;
return me();
}
public String corsAllowOrigin() {
if (null == corsOrigin) {
String s = get(CORS_ORIGIN);
if (S.blank(s)) {
s = "*";
}
corsOrigin = s;
}
return corsOrigin;
}
private void _mergeCorsOrigin(AppConfig conf) {
if (!hasConfiguration(CORS_ORIGIN)) {
corsOrigin = conf.corsOrigin;
}
}
private String corsHeaders;
protected T corsHeaders(String s) {
this.corsHeaders = s;
return me();
}
private String corsHeaders() {
if (null == corsHeaders) {
String s = get(CORS_HEADERS);
if (null == s) {
s = "Content-Type, X-HTTP-Method-Override, X-Requested-With";
}
corsHeaders = s;
}
return corsHeaders;
}
private void _mergeCorsHeaders(AppConfig conf) {
if (!hasConfiguration(CORS_HEADERS)) {
corsHeaders = conf.corsHeaders;
}
}
private String corsHeadersExpose;
protected T corsHeadersExpose(String s) {
this.corsHeadersExpose = s;
return me();
}
public String corsExposeHeaders() {
if (null == corsHeadersExpose) {
String s = get(CORS_HEADERS_EXPOSE);
if (null == s) {
s = corsHeaders();
}
corsHeadersExpose = s;
}
return corsHeadersExpose;
}
private void _mergeCorsHeadersExpose(AppConfig conf) {
if (!hasConfiguration(CORS_HEADERS_EXPOSE)) {
corsHeadersExpose = conf.corsHeadersExpose;
}
}
private Boolean corsOptionCheck;
protected T corsOptionCheck(Boolean b) {
this.corsOptionCheck = b;
return me();
}
public Boolean corsOptionCheck() {
if (null == corsOptionCheck) {
Boolean b = get(CORS_CHECK_OPTION_METHOD);
corsOptionCheck = null == b ? true : b;
}
return corsOptionCheck;
}
private void _mergeCorsOptionCheck(AppConfig conf) {
if (!hasConfiguration(CORS_CHECK_OPTION_METHOD)) {
corsOptionCheck = conf.corsOptionCheck;
}
}
private String corsHeadersAllowed;
protected T corsAllowHeaders(String s) {
this.corsHeadersExpose = s;
return me();
}
public String corsAllowHeaders() {
if (null == corsHeadersAllowed) {
String s = get(CORS_HEADERS_ALLOWED);
if (null == s) {
s = corsHeaders();
}
corsHeadersAllowed = s;
}
return corsHeadersAllowed;
}
private void _mergeCorsHeadersAllowed(AppConfig conf) {
if (!hasConfiguration(CORS_HEADERS_EXPOSE)) {
corsHeadersAllowed = conf.corsHeadersAllowed;
}
}
private Integer corsMaxAge;
protected T corsMaxAge(int corsMaxAge) {
this.corsMaxAge = corsMaxAge;
return me();
}
public int corsMaxAge() {
if (null == corsMaxAge) {
Integer I = getInteger(CORS_MAX_AGE);
if (null == I) {
I = 30 * 60;
}
corsMaxAge = I;
}
return corsMaxAge;
}
private void _mergeCorsMaxAge(AppConfig conf) {
if (!hasConfiguration(CORS_MAX_AGE)) {
corsMaxAge = conf.corsMaxAge;
}
}
private Boolean corsAllowCredentials;
protected T corsAllowCredentials(boolean b) {
this.corsAllowCredentials = b;
return me();
}
public boolean corsAllowCredentials() {
if (null == corsAllowCredentials) {
corsAllowCredentials = get(CORS_ALLOW_CREDENTIALS);
if (null == corsAllowCredentials) {
corsAllowCredentials = false;
}
}
return corsAllowCredentials;
}
private void _mergeCorsAllowCredential(AppConfig conf) {
if (!hasConfiguration(CORS_ALLOW_CREDENTIALS)) {
corsAllowCredentials = conf.corsAllowCredentials;
}
}
private Boolean csrf;
protected T enableCsrf(boolean b) {
this.csrf = b;
return me();
}
public boolean csrfEnabled() {
if (null == csrf) {
Boolean B = get(CSRF);
if (null == B) {
B = false;
}
this.csrf = B;
}
return this.csrf;
}
private void _mergeCsrf(AppConfig conf) {
if (!hasConfiguration(CSRF)) {
this.csrf = conf.csrf;
}
}
private String csrfParamName;
protected T csrfParamName(String s) {
this.csrfParamName = s;
return me();
}
public String csrfParamName() {
if (null == csrfParamName) {
String s = get(CSRF_PARAM_NAME);
if (S.blank(s)) {
s = ActionContext.ATTR_CSRF_TOKEN;
}
csrfParamName = s;
}
return csrfParamName;
}
private void _mergeCsrfParamName(AppConfig conf) {
if (!hasConfiguration(CSRF_PARAM_NAME)) {
csrfParamName = conf.csrfParamName;
}
}
private CSRFProtector csrfProtector;
protected T csrfProtector(CSRFProtector protector) {
this.csrfProtector = $.notNull(protector);
return me();
}
public CSRFProtector csrfProtector() {
if (null == csrfProtector) {
try {
csrfProtector = get(CSRF_PROTECTOR);
if (null == csrfProtector) {
csrfProtector = CSRFProtector.Predefined.HMAC;
}
} catch (ConfigurationException e) {
Object obj = helper.getValFromAliases(raw, CSRF_PROTECTOR.key(), "impl", null);
if (null != obj) {
this.csrfProtector = CSRFProtector.Predefined.valueOfIgnoreCase(obj.toString());
if (null != csrfProtector) {
return this.csrfProtector;
}
}
throw e;
}
}
return csrfProtector;
}
private void _mergeCsrfProtector(AppConfig config) {
if (!hasConfiguration(CSRF_PROTECTOR)) {
csrfProtector = config.csrfProtector;
}
}
private String csrfCookieName;
protected T csrfCookieName(String s) {
this.csrfCookieName = s;
return me();
}
public String csrfCookieName() {
if (null == csrfCookieName) {
String s = get(CSRF_COOKIE_NAME);
if (S.blank(s)) {
s = cookieName("xsrf-token");
}
csrfCookieName = s;
}
return csrfCookieName;
}
private void _mergeCsrfCookieName(AppConfig conf) {
if (!hasConfiguration(CSRF_COOKIE_NAME)) {
csrfCookieName = conf.csrfCookieName;
}
}
private String csrfHeaderName;
protected T csrfHeaderName(String s) {
this.csrfHeaderName = s;
return me();
}
public String csrfHeaderName() {
if (null == csrfHeaderName) {
String s = get(CSRF_HEADER_NAME);
if (S.blank(s)) {
s = H.Header.Names.X_XSRF_TOKEN;
}
csrfHeaderName = s;
}
return csrfHeaderName;
}
private void _mergeCsrfHeaderName(AppConfig conf) {
if (!hasConfiguration(CSRF_HEADER_NAME)) {
csrfHeaderName = conf.csrfHeaderName;
}
}
private Boolean cliEnabled;
protected T cliEnable(boolean enable) {
cliEnabled = enable;
return me();
}
public boolean cliEnabled() {
if (null == cliEnabled) {
cliEnabled = get(CLI_ENABLED);
if (null == cliEnabled) {
cliEnabled = true;
}
}
return cliEnabled;
}
private void _mergeCliEnabled(AppConfig conf) {
if (!hasConfiguration(CLI_ENABLED)) {
cliEnabled = conf.cliEnabled;
}
}
private int cliTablePageSz = -1;
protected T cliTablePageSz(int sz) {
E.illegalArgumentIf(sz < 1, "CLI table page size not valid: %s", sz);
this.cliTablePageSz = sz;
return me();
}
public int cliTablePageSize() {
if (-1 == cliTablePageSz) {
Integer I = getInteger(CLI_PAGE_SIZE_TABLE);
if (null == I) {
I = 22;
}
cliTablePageSz = I;
}
return cliTablePageSz;
}
private void _mergeCliTablePageSz(AppConfig conf) {
if (!hasConfiguration(CLI_PAGE_SIZE_TABLE)) {
cliTablePageSz = conf.cliTablePageSz;
}
}
private int cliJSONPageSz = -1;
protected T cliJSONPageSz(int sz) {
E.illegalArgumentIf(sz < 1, "CLI JSON page size not valid: %s", sz);
this.cliJSONPageSz = sz;
return me();
}
public int cliJSONPageSize() {
if (-1 == cliJSONPageSz) {
Integer I = getInteger(CLI_PAGE_SIZE_TABLE);
if (null == I) {
I = 22;
}
cliJSONPageSz = I;
}
return cliJSONPageSz;
}
private void _mergeCliJSONPageSz(AppConfig conf) {
if (!hasConfiguration(CLI_PAGE_SIZE_TABLE)) {
cliJSONPageSz = conf.cliJSONPageSz;
}
}
private Boolean cliOverHttp;
protected T cliOverHttp(boolean enabled) {
this.cliOverHttp = enabled;
return me();
}
public boolean cliOverHttp() {
if (null == cliOverHttp) {
Boolean B = get(CLI_OVER_HTTP);
if (null == B) {
B = false;
}
cliOverHttp = B;
}
return cliOverHttp;
}
private void _mergeCliOverHttp(AppConfig config) {
if (!hasConfiguration(CLI_OVER_HTTP)) {
cliOverHttp = config.cliOverHttp;
}
}
private CliOverHttpAuthority cliOverHttpAuthority;
protected T cliOverHttpAuthority(CliOverHttpAuthority authority) {
this.cliOverHttpAuthority = authority;
return me();
}
public CliOverHttpAuthority cliOverHttpAuthority() {
if (null == cliOverHttpAuthority) {
cliOverHttpAuthority = get(CLI_OVER_HTTP_AUTHORITY);
if (null == cliOverHttpAuthority) {
cliOverHttpAuthority = new CliOverHttpAuthority.AllowAll();
}
}
return cliOverHttpAuthority;
}
private void _mergeCliOverHttpAuthority(AppConfig config) {
if (!hasConfiguration(CLI_OVER_HTTP_AUTHORITY)) {
cliOverHttpAuthority = config.cliOverHttpAuthority;
}
}
Integer cliOverHttpPort;
protected T cliOverHttpPort(int port) {
this.cliOverHttpPort = port;
return me();
}
public int cliOverHttpPort() {
if (null == cliOverHttpPort) {
String s = get(CLI_OVER_HTTP_PORT);
cliOverHttpPort = null == s ? 5462 : Integer.parseInt(s);
}
return cliOverHttpPort;
}
private void _mergeCliOverHttpPort(AppConfig config) {
if (!hasConfiguration(CLI_OVER_HTTP_PORT)) {
cliOverHttpPort = config.cliOverHttpPort;
}
}
String cliOverHttpTitle;
protected T cliOverHttpTitle(String title) {
this.cliOverHttpTitle = title;
return me();
}
public String cliOverHttpTitle() {
if (null == cliOverHttpTitle) {
cliOverHttpTitle = get(CLI_OVER_HTTP_TITLE);
if (null == cliOverHttpTitle) {
cliOverHttpTitle = "Cli Over Http";
}
}
return cliOverHttpTitle;
}
private void _mergeCliOverHttpTitle(AppConfig config) {
if (!hasConfiguration(CLI_OVER_HTTP_TITLE)) {
cliOverHttpTitle = config.cliOverHttpTitle;
}
}
Boolean cliOverHttpSysCmd;
protected T cliOverHttpSysCmd(boolean enabled) {
this.cliOverHttpSysCmd = enabled;
return me();
}
public boolean cliOverHttpSysCmdEnabled() {
if (null == cliOverHttpSysCmd) {
cliOverHttpSysCmd = get(CLI_OVER_HTTP_SYS_CMD);
if (null == cliOverHttpSysCmd) {
cliOverHttpSysCmd = true;
}
}
return cliOverHttpSysCmd;
}
private void _mergeCliOverHttpSysCmd(AppConfig config) {
if (!hasConfiguration(CLI_OVER_HTTP_SYS_CMD)) {
cliOverHttpSysCmd = config.cliOverHttpSysCmd;
}
}
private Integer cliPort;
protected T cliPort(int port) {
E.illegalArgumentIf(port < 1, "port value not valid: %s", port);
this.cliPort = port;
return me();
}
public int cliPort() {
if (null == cliPort) {
String s = get(CLI_PORT);
cliPort = null == s ? 5461 : Integer.parseInt(s);
}
return cliPort;
}
private void _mergeCliPort(AppConfig conf) {
if (!hasConfiguration(CLI_PORT)) {
cliPort = conf.cliPort;
}
}
private int cliSessionExpiration = -1;
protected T cliSessionExpiration(int expire) {
E.illegalArgumentIf(expire < 1, "cli session expire not valid: %s", expire);
this.cliSessionExpiration = expire;
return me();
}
public int cliSessionExpiration() {
if (-1 == cliSessionExpiration) {
Integer I = getInteger(CLI_SESSION_EXPIRATION);
if (null == I) {
I = 300;
}
cliSessionExpiration = I;
}
return cliSessionExpiration;
}
private void _mergeCliSessionExpiration(AppConfig conf) {
if (!hasConfiguration(CLI_SESSION_EXPIRATION)) {
cliSessionExpiration = conf.cliSessionExpiration;
}
}
private String dspToken;
protected T dspToken(final String tokenName) {
this.dspToken = tokenName;
return me();
}
public String dspToken() {
if (null == dspToken) {
dspToken = get(DOUBLE_SUBMISSION_PROTECT_TOKEN);
if (null == dspToken) {
dspToken = "act_dsp_token";
}
}
return dspToken;
}
private void _mergeDspToken(AppConfig conf) {
if (!hasConfiguration(DOUBLE_SUBMISSION_PROTECT_TOKEN)) {
dspToken = conf.dspToken;
}
}
private Provider<String> cookieDomainProvider;
protected T cookieDomain(final String domain) {
this.cookieDomainProvider = new Provider<String>() {
@Override
public String get() {
return domain;
}
};
return me();
}
protected T cookieDomainProvider(Provider<String> provider) {
this.cookieDomainProvider = $.notNull(provider);
return me();
}
public String cookieDomain() {
String domain = cookieDomainProvider().get();
return "localhost".equals(domain) ? null : domain;
}
private Provider<String> cookieDomainProvider() {
if (null == cookieDomainProvider) {
try {
cookieDomainProvider = get(COOKIE_DOMAIN_PROVIDER);
} catch (ConfigurationException e) {
Object obj = helper.getValFromAliases(raw, COOKIE_DOMAIN_PROVIDER.key(), "impl", null);
String s = obj.toString();
if ("dynamic".equalsIgnoreCase(s) || "flexible".equalsIgnoreCase(s) || "contextual".equalsIgnoreCase(s)) {
cookieDomainProvider = new Provider<String>() {
@Override
public String get() {
H.Request req = ActionContext.current().req();
return req.domain();
}
};
return cookieDomainProvider;
}
throw e;
}
if (null == cookieDomainProvider) {
cookieDomainProvider = new Provider<String>() {
@Override
public String get() {
return host();
}
};
}
}
return cookieDomainProvider;
}
private void _mergeCookieDomain(AppConfig config) {
if (!hasConfiguration(COOKIE_DOMAIN_PROVIDER)) {
cookieDomainProvider = config.cookieDomainProvider;
}
}
private int maxCliSession = -1;
protected T maxCliSession(int size) {
E.illegalArgumentIf(size < 1, "max cli session number cannot be zero or negative number: %s", size);
this.maxCliSession = size;
return me();
}
public int maxCliSession() {
if (-1 == maxCliSession) {
Integer I = getInteger(CLI_SESSION_MAX);
if (null == I) {
I = 3;
}
maxCliSession = I;
}
return maxCliSession;
}
private void _mergeMaxCliSession(AppConfig conf) {
if (!hasConfiguration(CLI_SESSION_MAX)) {
maxCliSession = conf.maxCliSession;
}
}
private Boolean enumResolvingCaseSensitive;
protected T enumResolvingCaseSensitive(boolean b) {
enumResolvingCaseSensitive = b;
return me();
}
public boolean enumResolvingCaseSensitive() {
synchronized (ENUM_RESOLVING_CASE_SENSITIVE) {
if (null == enumResolvingCaseSensitive) {
enumResolvingCaseSensitive = get(ENUM_RESOLVING_CASE_SENSITIVE);
if (null == enumResolvingCaseSensitive) {
enumResolvingCaseSensitive = false;
}
}
return enumResolvingCaseSensitive;
}
}
private void _mergeEnumResolvingCaseSensitive(AppConfig conf) {
if (!hasConfiguration(ENUM_RESOLVING_CASE_SENSITIVE)) {
enumResolvingCaseSensitive = conf.enumResolvingCaseSensitive;
}
}
private String defViewName = null;
private View defView = null;
protected T defaultView(View view) {
E.NPE(view);
defView = view;
return me();
}
public View defaultView() {
if (null == defViewName) {
defViewName = get(AppConfigKey.VIEW_DEFAULT);
if (null == defViewName) {
defViewName = "rythm";
}
defView = Act.viewManager().view(defViewName);
}
return defView;
}
private void _mergeDefaultView(AppConfig conf) {
if (!hasConfiguration(AppConfigKey.VIEW_DEFAULT)) {
defViewName = conf.defViewName;
defView = conf.defView;
}
}
private String xForwardedProtocol = null;
protected T forceHttps() {
xForwardedProtocol = "https";
return me();
}
public String xForwardedProtocol() {
if (null == xForwardedProtocol) {
xForwardedProtocol = get(X_FORWARD_PROTOCOL);
if (null == xForwardedProtocol) {
xForwardedProtocol = "http";
}
}
return xForwardedProtocol;
}
private void _mergeXForwardedProtocol(AppConfig conf) {
if (!hasConfiguration(X_FORWARD_PROTOCOL)) {
xForwardedProtocol = conf.xForwardedProtocol;
}
}
private Boolean contentSuffixAware = null;
protected T contentSuffixAware(boolean b) {
contentSuffixAware = b;
return me();
}
public Boolean contentSuffixAware() {
if (null == contentSuffixAware) {
contentSuffixAware = get(CONTENT_SUFFIX_AWARE);
if (null == contentSuffixAware) {
contentSuffixAware = false;
}
}
return contentSuffixAware;
}
private void _mergeContentSuffixAware(AppConfig conf) {
if (!hasConfiguration(CONTENT_SUFFIX_AWARE)) {
contentSuffixAware = conf.contentSuffixAware;
}
}
private _SequenceNumberGenerator seqGen = null;
protected T sequenceNumberGenerator(_SequenceNumberGenerator seqGen) {
this.seqGen = seqGen;
return me();
}
public _SequenceNumberGenerator sequenceNumberGenerator() {
if (null == seqGen) {
seqGen = get(DB_SEQ_GENERATOR);
if (null == seqGen) {
javax.inject.Provider<_SequenceNumberGenerator> provider = app().getInstance(SequenceNumberGenerator.Provider.class);
seqGen = provider.get();
logger.debug("Sequence number generator loaded: %s", seqGen.getClass().getName());
}
}
return seqGen;
}
private void _mergeSequenceNumberGenerator(AppConfig conf) {
if (!hasConfiguration(DB_SEQ_GENERATOR)) {
seqGen = conf.seqGen;
}
}
private ErrorTemplatePathResolver errorTemplatePathResolver = null;
protected T errorTemplatePathResolver(ErrorTemplatePathResolver resolver) {
errorTemplatePathResolver = resolver;
return me();
}
public ErrorTemplatePathResolver errorTemplatePathResolver() {
if (null == errorTemplatePathResolver) {
errorTemplatePathResolver = get(RESOLVER_ERROR_TEMPLATE_PATH);
if (null == errorTemplatePathResolver) {
errorTemplatePathResolver = new ErrorTemplatePathResolver.DefaultErrorTemplatePathResolver();
}
}
return errorTemplatePathResolver;
}
private void _mergeErrorTemplatePathResolver(AppConfig conf) {
if (!hasConfiguration(RESOLVER_ERROR_TEMPLATE_PATH)) {
errorTemplatePathResolver = conf.errorTemplatePathResolver;
}
}
private String host = null;
protected T host(String hostname) {
hostname = hostname.trim();
E.illegalArgumentIf(hostname.length() == 0, "hostname cannot be empty");
host = hostname;
return me();
}
public String host() {
if (null == host) {
host = get(HOST);
if (null == host) {
logger.warn("host is not configured. Use localhost as hostname");
host = "localhost";
}
}
return host;
}
private void _mergeHost(AppConfig conf) {
if (!hasConfiguration(HOST)) {
host = conf.host;
}
}
private Boolean i18nEnabled;
protected T i18n(boolean enabled) {
i18nEnabled = enabled;
return me();
}
public boolean i18nEnabled() {
if (null == i18nEnabled) {
Boolean b = get(I18N);
if (null == b) {
b = false;
}
i18nEnabled = b;
}
return i18nEnabled;
}
private void _mergeI18nEnabled(AppConfig conf) {
if (!hasConfiguration(I18N)) {
i18nEnabled = conf.i18nEnabled;
}
}
private String localeParamName;
protected T localeParamName(String name) {
E.illegalArgumentIf(S.blank(name), "locale param name must not be empty");
localeParamName = name;
return me();
}
public String localeParamName() {
if (null == localeParamName) {
String s = get(I18N_LOCALE_PARAM_NAME);
if (S.blank(s)) {
s = "act_locale";
}
localeParamName = s;
}
return localeParamName;
}
private void _mergeLocaleParamName(AppConfig conf) {
if (!hasConfiguration(I18N_LOCALE_PARAM_NAME)) {
localeParamName = conf.localeParamName;
}
}
private String localeCookieName;
protected T localeCookieName(String name) {
E.illegalArgumentIf(S.blank(name), "locale Cookie name must not be empty");
localeCookieName = name;
return me();
}
public String localeCookieName() {
if (null == localeCookieName) {
String s = get(I18N_LOCALE_COOKIE_NAME);
if (S.blank(s)) {
s = cookieName("locale");
}
localeCookieName = s;
}
return localeCookieName;
}
private void _mergeLocaleCookieName(AppConfig conf) {
if (!hasConfiguration(I18N_LOCALE_COOKIE_NAME)) {
localeCookieName = conf.localeCookieName;
}
}
Integer ipEffectiveBytes;
protected T ipEffectiveBytes(int n) {
E.illegalArgumentIf(n < 1 || n > 4, "integer from 1 to 4 (inclusive) expected");
ipEffectiveBytes = n;
return me();
}
public int ipEffectiveBytes() {
if (null == ipEffectiveBytes) {
ipEffectiveBytes = getInteger(ID_GEN_NODE_ID_EFFECTIVE_IP_BYTES);
if (null == ipEffectiveBytes) {
ipEffectiveBytes = 4;
}
}
return ipEffectiveBytes;
}
private void _mergeIpEffectiveBytes(AppConfig conf) {
if (!hasConfiguration(ID_GEN_NODE_ID_EFFECTIVE_IP_BYTES)) {
ipEffectiveBytes = conf.ipEffectiveBytes;
}
}
private IdGenerator.NodeIdProvider nodeIdProvider;
protected T nodeIdProvider(IdGenerator.NodeIdProvider provider) {
this.nodeIdProvider = $.NPE(provider);
return me();
}
public IdGenerator.NodeIdProvider nodeIdProvider() {
if (null == nodeIdProvider) {
nodeIdProvider = get(ID_GEN_NODE_ID_PROVIDER);
if (null == nodeIdProvider) {
nodeIdProvider = new IdGenerator.NodeIdProvider.IpProvider(ipEffectiveBytes());
}
}
return nodeIdProvider;
}
private void _mergeNodeIdProvider(AppConfig conf) {
if (!hasConfiguration(ID_GEN_NODE_ID_PROVIDER)) {
nodeIdProvider = conf.nodeIdProvider;
}
}
private String startIdFile;
protected T startIdFile(String file) {
E.illegalArgumentIf(S.blank(file));
startIdFile = file;
return me();
}
public String startIdFile() {
if (null == startIdFile) {
startIdFile = get(ID_GEN_START_ID_FILE);
if (null == startIdFile) {
startIdFile = ".act.id-app";
}
}
return startIdFile;
}
private void _mergeStartIdFile(AppConfig conf) {
if (!hasConfiguration(ID_GEN_START_ID_FILE)) {
startIdFile = conf.startIdFile;
}
}
private IdGenerator.StartIdProvider startIdProvider;
protected T startIdProvider(IdGenerator.StartIdProvider provider) {
startIdProvider = $.NPE(provider);
return me();
}
public IdGenerator.StartIdProvider startIdProvider() {
if (null == startIdProvider) {
startIdProvider = get(ID_GEN_START_ID_PROVIDER);
if (null == startIdProvider) {
startIdProvider = new IdGenerator.StartIdProvider.DefaultStartIdProvider(startIdFile());
}
}
return startIdProvider;
}
private void _mergeStartIdProvider(AppConfig conf) {
if (!hasConfiguration(ID_GEN_START_ID_PROVIDER)) {
startIdProvider = conf.startIdProvider;
}
}
private IdGenerator.SequenceProvider sequenceProvider;
protected T sequenceProvider(IdGenerator.SequenceProvider provider) {
this.sequenceProvider = $.NPE(provider);
return me();
}
public IdGenerator.SequenceProvider sequenceProvider() {
if (null == sequenceProvider) {
sequenceProvider = get(ID_GEN_SEQ_ID_PROVIDER);
if (null == sequenceProvider) {
sequenceProvider = new IdGenerator.SequenceProvider.AtomicLongSeq();
}
}
return sequenceProvider;
}
private void _mergeSequenceProvider(AppConfig conf) {
if (!hasConfiguration(ID_GEN_SEQ_ID_PROVIDER)) {
sequenceProvider = conf.sequenceProvider;
}
}
private IdGenerator.LongEncoder longEncoder;
protected T longEncoder(IdGenerator.LongEncoder longEncoder) {
this.longEncoder = $.NPE(longEncoder);
return me();
}
public IdGenerator.LongEncoder longEncoder() {
if (null == longEncoder) {
longEncoder = get(ID_GEN_LONG_ENCODER);
if (null == longEncoder) {
longEncoder = IdGenerator.SAFE_ENCODER;
}
}
return longEncoder;
}
private void _mergeLongEncoder(AppConfig conf) {
if (!hasConfiguration(ID_GEN_LONG_ENCODER)) {
longEncoder = conf.longEncoder;
}
}
private String loginUrl = null;
protected T loginUrl(String url) {
E.illegalArgumentIf(!url.startsWith("/"), "login URL shall start with '/'");
this.loginUrl = url;
return me();
}
public String loginUrl() {
if (null == loginUrl) {
loginUrl = get(URL_LOGIN);
if (null == loginUrl) {
loginUrl = "/login";
}
}
ActionContext context = ActionContext.current();
if (null != context && context.isAjax()) {
return ajaxLoginUrl();
}
return loginUrl;
}
private void _mergeLoginUrl(AppConfig conf) {
if (!hasConfiguration(URL_LOGIN)) {
loginUrl = conf.loginUrl;
}
}
private String ajaxLoginUrl = null;
protected T ajaxLoginUrl(String url) {
E.illegalArgumentIf(!url.startsWith("/"), "login URL shall start with '/'");
this.ajaxLoginUrl = url;
return me();
}
public String ajaxLoginUrl() {
if (null == ajaxLoginUrl) {
ajaxLoginUrl = get(URL_LOGIN_AJAX);
if (null == ajaxLoginUrl) {
ajaxLoginUrl = loginUrl;
}
if (null == ajaxLoginUrl) {
ajaxLoginUrl = get(URL_LOGIN);
}
if (null == ajaxLoginUrl) {
ajaxLoginUrl = "/login";
}
}
return ajaxLoginUrl;
}
private void _mergeAjaxLoginUrl(AppConfig conf) {
if (!hasConfiguration(URL_LOGIN_AJAX)) {
ajaxLoginUrl = conf.ajaxLoginUrl;
}
}
private boolean urlContextInitialized;
private String urlContext;
protected T urlContext(String context) {
this.urlContext = context;
urlContextInitialized = S.notBlank(context);
return me();
}
public String urlContext() {
if (!urlContextInitialized) {
urlContext = get(URL_CONTEXT);
if (null != urlContext) {
urlContext = urlContext.trim();
if (urlContext.length() == 0) {
urlContext = null;
} else {
while (urlContext.endsWith("/")) {
urlContext = urlContext.substring(0, urlContext.length() - 1);
}
if (urlContext.length() == 0) {
urlContext = null;
} else if (!urlContext.startsWith("/")) {
urlContext = S.concat("/", urlContext);
}
}
if (null != urlContext && urlContext.contains(" ")) {
throw E.invalidConfiguration("url context shall not contains white space");
}
}
urlContextInitialized = true;
}
return urlContext;
}
private void _mergeUrlContext(AppConfig conf) {
if (!hasConfiguration(URL_CONTEXT)) {
urlContext = conf.urlContext;
urlContextInitialized = conf.urlContextInitialized;
}
}
private int httpMaxParams = -1;
protected T httpMaxParams(int max) {
E.illegalArgumentIf(max < 0, "max params cannot be negative number: %s", max);
this.httpMaxParams = max;
return me();
}
public int httpMaxParams() {
if (-1 == httpMaxParams) {
Integer I = getInteger(HTTP_MAX_PARAMS);
if (null == I) {
I = 128;
}
if (I < 0) {
throw new ConfigurationException("http.params.max setting cannot be negative number. Found: %s", I);
}
httpMaxParams = I;
}
return httpMaxParams;
}
private void _mergeHttpMaxParams(AppConfig conf) {
if (!hasConfiguration(HTTP_MAX_PARAMS)) {
httpMaxParams = conf.httpMaxParams;
}
}
private int jobPoolSize = -1;
protected T jobPoolSize(int size) {
E.illegalArgumentIf(size < 1, "job pool size cannot be zero or negative number: %s", size);
this.jobPoolSize = size;
return me();
}
public int jobPoolSize() {
if (-1 == jobPoolSize) {
Integer I = getInteger(JOB_POOL_SIZE);
if (null == I) {
I = 10;
}
jobPoolSize = I;
}
return jobPoolSize;
}
private void _mergeJobPoolSize(AppConfig conf) {
if (!hasConfiguration(JOB_POOL_SIZE)) {
jobPoolSize = conf.jobPoolSize;
}
}
private int httpExternalPort = -1;
protected T httpExternalPort(int port) {
E.illegalArgumentIf(port < 1, "port value not valid: %s", port);
this.httpExternalPort = port;
return me();
}
public int httpExternalPort() {
if (-1 == httpExternalPort) {
String s = get(HTTP_EXTERNAL_PORT);
httpExternalPort = null == s ? httpExternal() ? 80 : httpPort() : Integer.parseInt(s);
}
return httpExternalPort;
}
private void _mergeHttpExternalPort(AppConfig conf) {
if (!hasConfiguration(HTTP_EXTERNAL_PORT)) {
this.httpExternalPort = conf.httpExternalPort();
}
}
private Boolean httpExternal = null;
protected T httpExternal(boolean setting) {
this.httpExternal = setting;
return me();
}
public boolean httpExternal() {
if (null == httpExternal) {
Boolean b = get(HTTP_EXTERNAL_SERVER);
httpExternal = null == b ? Act.mode().isProd() : b;
}
return httpExternal;
}
private void _mergeHttpExternal(AppConfig conf) {
if (!hasConfiguration(HTTP_EXTERNAL_SERVER)) {
httpExternal = conf.httpExternal;
}
}
private int httpExternalSecurePort = -1;
protected T httpExternalSecurePort(int port) {
E.illegalArgumentIf(port < 1, "port value not valid: %s", port);
this.httpExternalSecurePort = port;
return me();
}
public int httpExternalSecurePort() {
if (-1 == httpExternalSecurePort) {
String s = get(HTTP_EXTERNAL_SECURE_PORT);
httpExternalSecurePort = null == s ? httpExternal() ? 443 : httpPort() : Integer.parseInt(s);
}
return httpExternalSecurePort;
}
private void _mergeHttpExternalSecurePort(AppConfig conf) {
if (!hasConfiguration(HTTP_EXTERNAL_PORT)) {
this.httpExternalSecurePort = conf.httpExternalSecurePort;
}
}
private int httpPort = -1;
protected T httpPort(int port) {
E.illegalArgumentIf(port < 1, "port value not valid: %s", port);
this.httpPort = port;
return me();
}
public int httpPort() {
if (-1 == httpPort) {
String s = get(HTTP_PORT);
httpPort = null == s ? 5460 : Integer.parseInt(s);
}
return httpPort;
}
private void _mergeHttpPort(AppConfig conf) {
if (!hasConfiguration(HTTP_PORT)) {
httpPort = conf.httpPort;
}
}
private Boolean httpSecure = null;
protected T httpSecure(boolean secure) {
this.httpSecure = secure;
return me();
}
public boolean httpSecure() {
if (null == httpSecure) {
Boolean B = get(HTTP_SECURE);
if (null == B) {
B = !Act.isDev() && S.neq(Act.profile(), "dev", S.IGNORECASE);
}
httpSecure = B;
}
return httpSecure;
}
private void _mergeHttpSecure(AppConfig conf) {
if (!hasConfiguration(HTTP_SECURE)) {
httpSecure = conf.httpSecure;
}
}
private MissingAuthenticationHandler mah = null;
protected T missingAuthenticationHandler(MissingAuthenticationHandler handler) {
E.NPE(handler);
mah = handler;
return me();
}
public MissingAuthenticationHandler missingAuthenticationHandler() {
if (null == mah) {
mah = get(HANDLER_MISSING_AUTHENTICATION);
if (null == mah) {
mah = app.getInstance(RedirectToLoginUrl.class);
}
}
return mah;
}
private void _mergeMissingAuthenticationHandler(AppConfig config) {
if (!hasConfiguration(HANDLER_MISSING_AUTHENTICATION)) {
mah = config.mah;
}
}
private MissingAuthenticationHandler ajaxMah = null;
protected T ajaxMissingAuthenticationHandler(MissingAuthenticationHandler handler) {
E.NPE(handler);
ajaxMah = handler;
return me();
}
public MissingAuthenticationHandler ajaxMissingAuthenticationHandler() {
if (null == ajaxMah) {
ajaxMah = get(HANDLER_MISSING_AUTHENTICATION_AJAX);
if (null == ajaxMah) {
ajaxMah = missingAuthenticationHandler();
}
}
return ajaxMah;
}
private void _mergeAjaxMissingAuthenticationHandler(AppConfig config) {
if (!hasConfiguration(HANDLER_MISSING_AUTHENTICATION_AJAX)) {
ajaxMah = config.ajaxMah;
}
}
private MissingAuthenticationHandler csrfCheckFailureHandler = null;
protected T csrfCheckFailureHandler(MissingAuthenticationHandler handler) {
E.NPE(handler);
csrfCheckFailureHandler = handler;
return me();
}
public MissingAuthenticationHandler csrfCheckFailureHandler() {
if (null == csrfCheckFailureHandler) {
csrfCheckFailureHandler = get(HANDLER_CSRF_CHECK_FAILURE);
if (null == csrfCheckFailureHandler) {
csrfCheckFailureHandler = missingAuthenticationHandler();
}
}
return csrfCheckFailureHandler;
}
private void _mergeCsrfCheckFailureHandler(AppConfig config) {
if (!hasConfiguration(HANDLER_CSRF_CHECK_FAILURE)) {
csrfCheckFailureHandler = config.csrfCheckFailureHandler;
}
}
private MissingAuthenticationHandler ajaxCsrfCheckFailureHandler = null;
protected T ajaxCsrfCheckFailureHandler(MissingAuthenticationHandler handler) {
E.NPE(handler);
ajaxCsrfCheckFailureHandler = handler;
return me();
}
public MissingAuthenticationHandler ajaxCsrfCheckFailureHandler() {
if (null == ajaxCsrfCheckFailureHandler) {
ajaxCsrfCheckFailureHandler = get(HANDLER_AJAX_CSRF_CHECK_FAILURE);
if (null == ajaxCsrfCheckFailureHandler) {
ajaxCsrfCheckFailureHandler = csrfCheckFailureHandler();
}
}
return ajaxCsrfCheckFailureHandler;
}
private void _mergeAjaxCsrfCheckFailureHandler(AppConfig config) {
if (!hasConfiguration(HANDLER_AJAX_CSRF_CHECK_FAILURE)) {
csrfCheckFailureHandler = config.csrfCheckFailureHandler;
}
}
private List<NamedPort> namedPorts = null;
protected T namedPorts(NamedPort... namedPorts) {
this.namedPorts = C.listOf(namedPorts);
return me();
}
public List<NamedPort> namedPorts() {
if (null == namedPorts) {
String s = get(NAMED_PORTS);
if (null == s) {
namedPorts = cliOverHttp() ? C.list(new NamedPort(PORT_CLI_OVER_HTTP, cliOverHttpPort())) : C.<NamedPort>list();
} else {
String[] sa = (s.split("[,;]+"));
ListBuilder<NamedPort> builder = ListBuilder.create();
for (String s0 : sa) {
String[] sa0 = s0.split(":");
E.invalidConfigurationIf(2 != sa0.length, "Unknown named port configuration: %s", s);
String name = sa0[0].trim();
String val = sa0[1].trim();
NamedPort port = new NamedPort(name, Integer.parseInt(val));
if (!builder.contains(port)) {
builder.add(port);
} else {
throw E.invalidConfiguration("port[%s] already configured", name);
}
}
if (cliOverHttp()) {
builder.add(new NamedPort(PORT_CLI_OVER_HTTP, cliOverHttpPort()));
}
namedPorts = builder.toList();
}
}
return namedPorts;
}
public NamedPort namedPort(String portId) {
for (NamedPort np : namedPorts()) {
if (np.name().equalsIgnoreCase(portId)) {
return np;
}
}
return null;
}
private void _mergePorts(AppConfig config) {
if (!hasConfiguration(NAMED_PORTS)) {
namedPorts = config.namedPorts;
}
}
private String encoding = null;
protected T encoding(String encoding) {
encoding = encoding.trim();
E.illegalArgumentIf(encoding.length() == 0, "encoding cannot be empty");
this.encoding = encoding;
return me();
}
public String encoding() {
if (null == encoding) {
encoding = get(ENCODING);
if (null == encoding) {
encoding = StandardCharsets.UTF_8.name();
}
}
return encoding;
}
private void _mergeEncoding(AppConfig conf) {
if (!hasConfiguration(ENCODING)) {
encoding = conf.encoding;
}
}
private String dateFmt = null;
protected T dateFormat(String fmt) {
E.illegalArgumentIf(S.blank(fmt), "Date format cannot be empty");
this.dateFmt = fmt;
return me();
}
public String dateFormat() {
if (null == dateFmt) {
dateFmt = get(FORMAT_DATE);
if (null == dateFmt) {
DateFormat formatter = DateFormat.getDateInstance();
dateFmt = ((SimpleDateFormat) formatter).toPattern();
}
}
return dateFmt;
}
private void _mergeDateFmt(AppConfig conf) {
if (!hasConfiguration(FORMAT_DATE)) {
dateFmt = conf.dateFmt;
}
}
private String timeFmt = null;
protected T timeFormat(String fmt) {
E.illegalArgumentIf(S.blank(fmt), "Time format cannot be empty");
this.timeFmt = fmt;
return me();
}
public String timeFormat() {
if (null == timeFmt) {
timeFmt = get(FORMAT_TIME);
if (null == timeFmt) {
DateFormat formatter = DateFormat.getTimeInstance();
timeFmt = ((SimpleDateFormat) formatter).toPattern();
}
}
return timeFmt;
}
private void _mergeTimeFmt(AppConfig conf) {
if (!hasConfiguration(FORMAT_TIME)) {
timeFmt = conf.timeFmt;
}
}
private String dateDateTimeFmt = null;
protected T dateTimeFormat(String fmt) {
E.illegalArgumentIf(S.blank(fmt), "Date time format cannot be empty");
this.dateDateTimeFmt = fmt;
return me();
}
public String dateTimeFormat() {
if (null == dateDateTimeFmt) {
dateDateTimeFmt = get(FORMAT_DATE_TIME);
if (null == dateDateTimeFmt) {
DateFormat formatter = DateFormat.getDateTimeInstance();
dateDateTimeFmt = ((SimpleDateFormat) formatter).toPattern();
}
}
return dateDateTimeFmt;
}
private void _mergeDateTimeFmt(AppConfig conf) {
if (!hasConfiguration(FORMAT_DATE_TIME)) {
dateDateTimeFmt = conf.dateDateTimeFmt;
}
}
private Locale locale = null;
protected T locale(Locale locale) {
E.NPE(locale);
this.locale = locale;
return me();
}
public Locale locale() {
if (null == locale) {
locale = get(LOCALE);
if (null == locale) {
locale = Locale.getDefault();
}
}
return locale;
}
private void _mergeLocale(AppConfig conf) {
if (!hasConfiguration(LOCALE)) {
locale = conf.locale;
}
}
private String sourceVersion = null;
protected T sourceVersion(JavaVersion version) {
sourceVersion = FastStr.of(version.name()).substr(1).replace('_', '.').toString();
return me();
}
public String sourceVersion() {
if (null == sourceVersion) {
sourceVersion = get(AppConfigKey.SOURCE_VERSION);
if (null == sourceVersion) {
sourceVersion = "1." + $.JAVA_VERSION;
} else if (sourceVersion.startsWith("1.")) {
sourceVersion = sourceVersion.substring(0, 3);
}
}
return sourceVersion;
}
private void _mergeSourceVersion(AppConfig conf) {
if (!hasConfiguration(SOURCE_VERSION)) {
sourceVersion = conf.sourceVersion;
}
}
private String targetVersion = null;
protected T targetVersion(JavaVersion version) {
targetVersion = FastStr.of(version.name()).substr(1).replace('_', '.').toString();
return me();
}
public String targetVersion() {
if (null == targetVersion) {
targetVersion = get(TARGET_VERSION);
if (null == targetVersion) {
targetVersion = "1." + $.JAVA_VERSION;
} else if (targetVersion.startsWith("1.")) {
targetVersion = targetVersion.substring(0, 3);
}
}
return targetVersion;
}
private void _mergeTargetVersion(AppConfig conf) {
if (!hasConfiguration(TARGET_VERSION)) {
targetVersion = conf.targetVersion;
}
}
private $.Predicate<String> APP_CLASS_TESTER = null;
private final $.Predicate<String> SYSTEM_SCAN_LIST = new $.Predicate<String>() {
@Override
public boolean test(String s) {
final Set<String> scanList = app().scanList();
if (scanList.contains(s)) {
return true;
}
for (String scan: scanList) {
if (s.matches(scan)) {
return true;
}
}
return false;
}
};
public $.Predicate<String> appClassTester() {
if (null == APP_CLASS_TESTER) {
String scanPackage = get(AppConfigKey.SCAN_PACKAGE);
if (S.isBlank(scanPackage)) {
APP_CLASS_TESTER = SYSTEM_SCAN_LIST;
} else {
final String[] sp = scanPackage.trim().split(Constants.LIST_SEPARATOR);
final int len = sp.length;
if (1 == len) {
APP_CLASS_TESTER = S.F.startsWith(sp[0]).or(SYSTEM_SCAN_LIST);
} else {
APP_CLASS_TESTER = new $.Predicate<String>() {
@Override
public boolean test(String className) {
for (int i = 0; i < len; ++i) {
if (className.startsWith(sp[i])) {
return true;
}
}
return false;
}
}.or(SYSTEM_SCAN_LIST);
}
}
}
return APP_CLASS_TESTER;
}
public boolean needEnhancement(String className) {
return appClassTester().test(className) || controllerNameTester().test(className);
}
private $.Predicate<String> CONTROLLER_CLASS_TESTER = null;
private $.Predicate<String> controllerNameTester() {
if (null == CONTROLLER_CLASS_TESTER) {
$.Predicate<String> f = $.F.no();
CONTROLLER_CLASS_TESTER = f.or(app().router().f.IS_CONTROLLER);
}
return CONTROLLER_CLASS_TESTER;
}
private TemplatePathResolver templatePathResolver = null;
protected T templatePathResolver(TemplatePathResolver resolver) {
E.NPE(resolver);
templatePathResolver = resolver;
return me();
}
public TemplatePathResolver templatePathResolver() {
if (null == templatePathResolver) {
templatePathResolver = get(AppConfigKey.RESOLVER_TEMPLATE_PATH);
if (null == templatePathResolver) {
templatePathResolver = new TemplatePathResolver();
}
}
return templatePathResolver;
}
private void _mergeTemplatePathResolver(AppConfig conf) {
if (!hasConfiguration(AppConfigKey.RESOLVER_TEMPLATE_PATH)) {
templatePathResolver = conf.templatePathResolver;
}
}
private String templateHome = null;
protected T templateHome(String home) {
home = home.trim();
E.illegalArgumentIf(home.length() == 0, "template home cannot be empty");
templateHome = home;
return me();
}
public String templateHome() {
if (null == templateHome) {
templateHome = get(AppConfigKey.TEMPLATE_HOME);
if (null == templateHome) {
templateHome = "default";
}
}
return templateHome;
}
private void _mergeTemplateHome(AppConfig conf) {
if (!hasConfiguration(AppConfigKey.TEMPLATE_HOME)) {
templateHome = conf.templateHome;
}
}
private boolean pingPathResolved = false;
private String pingPath = null;
protected T pingPath(String path) {
pingPathResolved = true;
pingPath = path.trim();
return me();
}
public String pingPath() {
if (!pingPathResolved) {
pingPath = get(AppConfigKey.PING_PATH);
pingPathResolved = true;
}
return pingPath;
}
private void _mergePingPath(AppConfig config) {
if (!hasConfiguration(AppConfigKey.PING_PATH)) {
pingPath = config.pingPath;
pingPathResolved = config.pingPathResolved;
}
}
private Osgl.Func0<H.Format> jsonContentTypeProvider = null;
private Boolean renderJsonIeFix = null;
private H.Format jsonIE;
protected T renderJsonContentTypeIE(final String contentType) {
setRenderJsonContenTypeIE(contentType);
return me();
}
private void setRenderJsonContenTypeIE(final String contentType) {
if (H.Format.JSON.contentType().equalsIgnoreCase(contentType)) {
renderJsonIeFix = false;
return;
}
renderJsonIeFix = true;
jsonIE = H.Format.of("json_ie", contentType);
jsonContentTypeProvider = new Osgl.Func0<H.Format>() {
@Override
public H.Format apply() throws NotAppliedException, Osgl.Break {
ActionContext context = ActionContext.current();
if (null != context) {
UserAgent ua = context.userAgent();
if (ua.isIE()) {
return jsonIE;
}
}
return H.Format.JSON;
}
};
}
public Osgl.Func0<H.Format> jsonContentTypeProvider() {
if (null == renderJsonIeFix) {
String contentType = get(RENDER_JSON_CONTENT_TYPE_IE);
if (null != contentType) {
setRenderJsonContenTypeIE(contentType);
} else {
renderJsonIeFix = false;
}
}
return renderJsonIeFix ? jsonContentTypeProvider : null;
}
private void _mergeRenderJsonContentTypeIE(AppConfig conf) {
if (!hasConfiguration(RENDER_JSON_CONTENT_TYPE_IE)) {
jsonContentTypeProvider = conf.jsonContentTypeProvider;
renderJsonIeFix = conf.renderJsonIeFix;
jsonIE = conf.jsonIE;
}
}
private Boolean renderJsonOutputCharset;
protected T renderJsonOutputCharset(boolean outputCharset) {
this.renderJsonOutputCharset = outputCharset;
return me();
}
public boolean renderJsonOutputCharset() {
if (null == renderJsonOutputCharset) {
renderJsonOutputCharset = get(RENDER_JSON_OUTPUT_CHARSET);
if (null == renderJsonOutputCharset) {
renderJsonOutputCharset = false;
}
}
return renderJsonOutputCharset;
}
private void _mergeRenderJsonOutputCharset(AppConfig config) {
if (!hasConfiguration(RENDER_JSON_OUTPUT_CHARSET)) {
renderJsonOutputCharset = config.renderJsonOutputCharset;
}
}
private String serverHeader;
protected T serverHeader(String header) {
serverHeader = header;
return me();
}
public String serverHeader() {
if (null == serverHeader) {
serverHeader = get(AppConfigKey.SERVER_HEADER);
if (null == serverHeader) {
serverHeader = "act";
}
}
return serverHeader;
}
private void _mergeServerHeader(AppConfig config) {
if (!hasConfiguration(AppConfigKey.SERVER_HEADER)) {
serverHeader = config.serverHeader;
}
}
private String sessionKeyUsername = null;
protected T sessionKeyUsername(String name) {
name = name.trim().toLowerCase();
E.illegalArgumentIf(name.length() == 0, "session cookie name cannot be blank");
sessionKeyUsername = name;
return me();
}
public String sessionKeyUsername() {
if (null == sessionKeyUsername) {
String username = get(SESSION_KEY_USERNAME);
if (S.blank(username)) {
username = "username";
}
sessionKeyUsername = username;
}
return sessionKeyUsername;
}
private void _mergeSessionKeyUsername(AppConfig config) {
if (!hasConfiguration(SESSION_KEY_USERNAME)) {
sessionKeyUsername = config.sessionKeyUsername;
}
}
private String cookiePrefix;
protected T cookiePrefix(String prefix) {
prefix = prefix.trim().toLowerCase();
E.illegalArgumentIf(prefix.length() == 0, "cookie prefix cannot be blank");
cookiePrefix = prefix;
return me();
}
private String cookiePrefix() {
if (null == cookiePrefix) {
cookiePrefix = get(COOKIE_PREFIX);
if (null == cookiePrefix) {
cookiePrefix = S.concat(app().id(), "-");
}
cookiePrefix = cookiePrefix.trim().toLowerCase();
}
return cookiePrefix;
}
private void _mergeCookiePrefix(AppConfig config) {
if (!hasConfiguration(COOKIE_PREFIX)) {
cookiePrefix = config.cookiePrefix;
}
}
private String sessionCookieName = null;
protected T sessionCookieName(String name) {
name = name.trim().toLowerCase();
E.illegalArgumentIf(name.length() == 0, "session cookie name cannot be blank");
E.illegalArgumentIf(S.eq(name, flashCookieName), "session cookie name cannot be the same with flash cookie name");
sessionCookieName = name;
return me();
}
public String sessionCookieName() {
if (null == sessionCookieName) {
sessionCookieName = cookieName("session");
}
return sessionCookieName;
}
private void _mergeSessionCookieName(AppConfig config) {
if (null != config.sessionCookieName) {
sessionCookieName = config.sessionCookieName;
}
}
private String flashCookieName = null;
protected T flashCookieName(String name) {
name = name.trim().toLowerCase();
E.illegalArgumentIf(name.length() == 0, "flash cookie name cannot be blank");
E.illegalArgumentIf(S.eq(name, sessionCookieName), "flash cookie name cannot be the same with session cookie name");
flashCookieName = name;
return me();
}
public String flashCookieName() {
if (null == flashCookieName) {
flashCookieName = cookieName("flash");
}
return flashCookieName;
}
private void _mergeFlashCookieName(AppConfig config) {
if (null != config.flashCookieName) {
flashCookieName = config.flashCookieName;
}
}
private Integer sessionTtl = null;
protected T sessionTtl(int seconds) {
sessionTtl = seconds;
return me();
}
public int sessionTtl() {
if (null == sessionTtl) {
sessionTtl = getInteger(AppConfigKey.SESSION_TTL);
if (null == sessionTtl) {
sessionTtl = 60 * 30;
}
}
return sessionTtl;
}
private void _mergeSessionTtl(AppConfig conf) {
if (!hasConfiguration(AppConfigKey.SESSION_TTL)) {
sessionTtl = conf.sessionTtl;
}
}
private Boolean sessionPersistent = null;
protected T sessionPersistent(boolean persistenSession) {
sessionPersistent = persistenSession;
return me();
}
public boolean persistSession() {
if (null == sessionPersistent) {
sessionPersistent = get(AppConfigKey.SESSION_PERSISTENT_ENABLED);
if (null == sessionPersistent) {
sessionPersistent = false;
}
}
return sessionPersistent;
}
private void _mergeSessionPersistent(AppConfig config) {
if (!hasConfiguration(AppConfigKey.SESSION_PERSISTENT_ENABLED)) {
sessionPersistent = config.sessionPersistent;
}
}
private Boolean sessionEncrypt = null;
protected T sessionEncrypt(boolean encryptSession) {
sessionEncrypt = encryptSession;
return me();
}
public boolean encryptSession() {
if (null == sessionEncrypt) {
sessionEncrypt = get(AppConfigKey.SESSION_ENCRYPT_ENABLED);
if (null == sessionEncrypt) {
sessionEncrypt = false;
}
}
return sessionEncrypt;
}
private void _mergeSessionEncrpt(AppConfig config) {
if (!hasConfiguration(AppConfigKey.SESSION_ENCRYPT_ENABLED)) {
sessionEncrypt = config.sessionEncrypt;
}
}
private SessionMapper sessionMapper = null;
protected T sessionMapper(SessionMapper sessionMapper) {
this.sessionMapper = sessionMapper;
return me();
}
public SessionMapper sessionMapper() {
if (null == sessionMapper) {
Object o = get(SESSION_MAPPER);
sessionMapper = SessionMapper.DefaultSessionMapper.wrap((SessionMapper) o);
}
return sessionMapper;
}
private void _mergeSessionMapper(AppConfig config) {
if (!hasConfiguration(AppConfigKey.SESSION_MAPPER)) {
sessionMapper = config.sessionMapper;
}
}
private Boolean sessionSecure = null;
protected T sessionSecure(boolean secure) {
sessionSecure = secure;
return me();
}
public boolean sessionSecure() {
if (null == sessionSecure) {
sessionSecure = get(AppConfigKey.SESSION_SECURE);
if (null == sessionSecure) {
sessionSecure = httpSecure();
}
}
return sessionSecure;
}
private void _mergeSessionSecure(AppConfig config) {
if (!hasConfiguration(AppConfigKey.SESSION_SECURE)) {
sessionSecure = config.sessionSecure;
}
}
private String secret = null;
protected T secret(String secret) {
E.illegalArgumentIf(S.blank(secret));
this.secret = secret;
return me();
}
public String secret() {
if (null == secret) {
secret = get(AppConfigKey.SECRET);
if (null == secret) {
secret = "myawesomeapp";
logger.warn("Application secret key not set! You are in the dangerous zone!!!");
}
}
return secret;
}
private void _mergeSecret(AppConfig config) {
if (!hasConfiguration(AppConfigKey.SECRET)) {
secret = config.secret;
}
}
private List<File> moduleBases;
public List<File> moduleBases() {
if (null == moduleBases) {
String v = get(AppConfigKey.MODULES);
moduleBases = processModules(v);
}
return moduleBases;
}
private List<File> processModules(String v) {
if (S.blank(v)) {
return C.list();
} else {
List<File> files = C.newList();
File base = app.base();
for (String s: v.trim().split("[;:]+")) {
s = s.trim();
File file;
if (s.startsWith("/") || s.startsWith("\\")) {
file = new File(s);
} else {
file = ProjectLayout.Utils.file(base, s);
}
if (!file.isDirectory()) {
logger.warn("Cannot locate extra source dir: %s", s);
} else {
files.add(file);
}
}
return C.list(files);
}
}
private Boolean metricEnabled;
protected T metricEnable(boolean enable) {
this.metricEnabled = enable;
return me();
}
public boolean metricEnabled() {
if (null == metricEnabled) {
metricEnabled = get(METRIC_ENABLED);
if (null == metricEnabled) {
metricEnabled = true;
}
}
return metricEnabled;
}
private void _mergeMetricEnabled(AppConfig conf) {
if (!hasConfiguration(METRIC_ENABLED)) {
metricEnabled = conf.metricEnabled;
}
}
public boolean possibleControllerClass(String className) {
return appClassTester().test(className);
}
private CacheServiceProvider csp = null;
protected T cacheService(CacheServiceProvider csp) {
E.NPE(csp);
this.csp = csp;
return me();
}
protected T cacheService(Class<? extends CacheServiceProvider> csp) {
this.csp = $.newInstance(csp);
return me();
}
public CacheService cacheService(String name) {
if (null == csp) {
try {
csp = get(AppConfigKey.CACHE_IMPL);
} catch (ConfigurationException e) {
Object obj = helper.getValFromAliases(raw, AppConfigKey.CACHE_IMPL.toString(), "impl", null);
csp = CacheServiceProvider.Impl.valueOfIgnoreCase(obj.toString());
if (null != csp) {
return csp.get(name);
}
throw e;
}
if (null == csp) {
csp = CacheServiceProvider.Impl.Auto;
}
}
return csp.get(name);
}
private void _mergeCacheServiceProvider(AppConfig config) {
if (!hasConfiguration(AppConfigKey.CACHE_IMPL)) {
csp = config.csp;
}
}
private String _cacheName;
protected T cacheName(String name) {
this._cacheName = name;
return me();
}
public String cacheName() {
if (null == _cacheName) {
_cacheName = get(AppConfigKey.SESSION_KEY_USERNAME);
if (null == _cacheName) {
_cacheName = "_act_app_";
}
}
return _cacheName;
}
private void _mergeCacheName(AppConfig config) {
if (!hasConfiguration(AppConfigKey.CACHE_NAME)) {
_cacheName = config._cacheName;
}
}
private String _cacheNameSession;
protected T cacheNameSession(String name) {
this._cacheNameSession = name;
return me();
}
public String cacheNameSession() {
if (null == _cacheNameSession) {
_cacheNameSession = get(AppConfigKey.CACHE_NAME_SESSION);
if (null == _cacheNameSession) {
_cacheNameSession = cacheName();
}
}
return _cacheNameSession;
}
private UnknownHttpMethodProcessor _unknownHttpMethodProcessor = null;
protected T unknownHttpMethodProcessor(UnknownHttpMethodProcessor handler) {
this._unknownHttpMethodProcessor = $.notNull(handler);
return me();
}
public UnknownHttpMethodProcessor unknownHttpMethodProcessor() {
if (null == _unknownHttpMethodProcessor) {
_unknownHttpMethodProcessor = get(AppConfigKey.HANDLER_UNKNOWN_HTTP_METHOD);
if (null == _unknownHttpMethodProcessor) {
_unknownHttpMethodProcessor = UnknownHttpMethodProcessor.METHOD_NOT_ALLOWED;
}
}
return _unknownHttpMethodProcessor;
}
private void _mergeUnknownHttpMethodHandler(AppConfig config) {
if (!hasConfiguration(AppConfigKey.HANDLER_UNKNOWN_HTTP_METHOD)) {
this._unknownHttpMethodProcessor = config._unknownHttpMethodProcessor;
}
}
private Integer resourcePreloadSizeLimit;
protected T resourcePreloadSizeLimit(int limit) {
resourcePreloadSizeLimit = limit;
return me();
}
public int resourcePreloadSizeLimit() {
if (null == resourcePreloadSizeLimit) {
resourcePreloadSizeLimit = getInteger(RESOURCE_PRELOAD_SIZE_LIMIT);
if (null == resourcePreloadSizeLimit) {
resourcePreloadSizeLimit = 1024 * 10;
} else if (resourcePreloadSizeLimit <= 0) {
logger.warn("resource.preload.size.limit is set to zero or below, resource preload is disabled!");
}
}
return resourcePreloadSizeLimit;
}
private void _mergeResourcePreloadSizeLimit(AppConfig conf) {
if (!hasConfiguration(RESOURCE_PRELOAD_SIZE_LIMIT)) {
this.resourcePreloadSizeLimit = conf.resourcePreloadSizeLimit;
}
}
private Boolean uploadFileDownload;
protected T enableUploadFileDownload(boolean b) {
uploadFileDownload = b;
return me();
}
public boolean allowDownloadUploadFile() {
if (null == uploadFileDownload) {
uploadFileDownload = get(UPLOAD_FILE_DOWNLOAD);
if (null == uploadFileDownload) {
uploadFileDownload = false;
}
}
return uploadFileDownload;
}
private void _mergeUploadFileDownload(AppConfig config) {
if (!hasConfiguration(UPLOAD_FILE_DOWNLOAD)) {
uploadFileDownload = config.uploadFileDownload;
}
}
private Set<AppConfigurator> mergeTracker = C.newSet();
public void loadJarProperties(Map<String, Properties> jarProperties) {
// load common properties
Properties p0 = jarProperties.remove("common");
// load app env properties
Properties p1 = jarProperties.remove(ConfLoader.confSetName());
if (null != p1) {
if (null != p0) {
p0.putAll(p1);
} else {
p0 = p1;
}
}
if (null != p0) {
loadJarProperties(p0);
}
}
private void loadJarProperties(Properties p) {
Enumeration<?> keys = p.propertyNames();
while (keys.hasMoreElements()) {
String key = S.string(keys.nextElement());
if (!raw.containsKey(key)) {
raw.put(key, p.getProperty(key));
}
}
}
/**
* Merge application configurator settings. Note application configurator
* settings has lower priority as it's hardcoded thus only when configuration file
* does not provided the settings, the app configurator will take effect
*
* @param conf the application configurator
*/
public void _merge(AppConfigurator conf) {
app.eventBus().trigger(AppEventId.CONFIG_PREMERGE);
if (mergeTracker.contains(conf)) {
return;
}
mergeTracker.add(conf);
_mergeBasicAuthentication(conf);
_mergeCacheName(conf);
_mergeCors(conf);
_mergeCorsOrigin(conf);
_mergeCorsHeaders(conf);
_mergeCorsHeadersExpose(conf);
_mergeCorsHeadersAllowed(conf);
_mergeCorsMaxAge(conf);
_mergeCorsAllowCredential(conf);
_mergeCorsOptionCheck(conf);
_mergeCliEnabled(conf);
_mergeCliJSONPageSz(conf);
_mergeCliTablePageSz(conf);
_mergeCliOverHttp(conf);
_mergeCliOverHttpAuthority(conf);
_mergeCliOverHttpPort(conf);
_mergeCliOverHttpTitle(conf);
_mergeCliOverHttpSysCmd(conf);
_mergeCliPort(conf);
_mergeCliSessionExpiration(conf);
_mergeCsrf(conf);
_mergeCsrfParamName(conf);
_mergeCsrfHeaderName(conf);
_mergeCsrfCookieName(conf);
_mergeCsrfProtector(conf);
_mergeCsrfCheckFailureHandler(conf);
_mergeAjaxCsrfCheckFailureHandler(conf);
_mergeCookieDomain(conf);
_mergeMaxCliSession(conf);
_mergeDspToken(conf);
_mergeEnumResolvingCaseSensitive(conf);
_mergeXForwardedProtocol(conf);
_mergeHost(conf);
_mergeLoginUrl(conf);
_mergeAjaxLoginUrl(conf);
_mergeUrlContext(conf);
_mergeHttpMaxParams(conf);
_mergeJobPoolSize(conf);
_mergeMissingAuthenticationHandler(conf);
_mergeAjaxMissingAuthenticationHandler(conf);
_mergeHttpExternal(conf);
_mergeHttpExternalPort(conf);
_mergeHttpExternalSecurePort(conf);
_mergeHttpPort(conf);
_mergeHttpSecure(conf);
_mergePorts(conf);
_mergeContentSuffixAware(conf);
_mergeSequenceNumberGenerator(conf);
_mergeErrorTemplatePathResolver(conf);
_mergeDateFmt(conf);
_mergeDateTimeFmt(conf);
_mergeMetricEnabled(conf);
_mergeTimeFmt(conf);
_mergeEncoding(conf);
_mergeNodeIdProvider(conf);
_mergeI18nEnabled(conf);
_mergeLocaleParamName(conf);
_mergeLocaleCookieName(conf);
_mergeIpEffectiveBytes(conf);
_mergeStartIdFile(conf);
_mergeStartIdProvider(conf);
_mergeSequenceProvider(conf);
_mergeLongEncoder(conf);
_mergeLocale(conf);
_mergeResourcePreloadSizeLimit(conf);
_mergeSourceVersion(conf);
_mergeTargetVersion(conf);
_mergeTemplatePathResolver(conf);
_mergeTemplateHome(conf);
_mergeDefaultView(conf);
_mergePingPath(conf);
_mergeRenderJsonContentTypeIE(conf);
_mergeRenderJsonOutputCharset(conf);
_mergeServerHeader(conf);
_mergeCookiePrefix(conf);
_mergeSessionCookieName(conf);
_mergeFlashCookieName(conf);
_mergeSessionTtl(conf);
_mergeSessionPersistent(conf);
_mergeSessionEncrpt(conf);
_mergeSessionSecure(conf);
_mergeSessionKeyUsername(conf);
_mergeSessionMapper(conf);
_mergeSecret(conf);
_mergeCacheServiceProvider(conf);
_mergeUnknownHttpMethodHandler(conf);
_mergeUploadFileDownload(conf);
Set<String> keys = conf.propKeys();
if (!keys.isEmpty()) {
for (String k : keys) {
if (!raw.containsKey(k)) {
raw.put(k, conf.propVal(k));
}
}
}
}
@Override
protected void releaseResources() {
app = null;
super.releaseResources();
}
protected T me() {
return $.cast(this);
}
private String cookieName(String suffix) {
return S.concat(cookiePrefix(), suffix);
}
}