Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
act.conf.AppConfig Maven / Gradle / Ivy
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 static act.conf.AppConfigKey.*;
import static java.util.ResourceBundle.Control.FORMAT_DEFAULT;
import static org.osgl.http.H.Header.Names.X_XSRF_TOKEN;
import act.Act;
import act.Constants;
import act.act_messages;
import act.app.*;
import act.app.conf.AppConfigurator;
import act.app.event.AppClassLoaderInitialized;
import act.app.event.SysEventId;
import act.app.util.NamedPort;
import act.cli.CliOverHttpAuthority;
import act.crypto.HMAC;
import act.crypto.RotateSecretHMAC;
import act.data.DateTimeStyle;
import act.data.DateTimeType;
import act.db.util.SequenceNumberGenerator;
import act.db.util._SequenceNumberGenerator;
import act.event.EventBus;
import act.event.SysEventListenerBase;
import act.handler.*;
import act.handler.event.ResultEvent;
import act.i18n.I18n;
import act.internal.util.StrBufRetentionLimitCalculator;
import act.route.Router;
import act.security.CSRFProtector;
import act.session.*;
import act.util.*;
import act.validation.Password;
import act.validation.PasswordSpec;
import act.view.TemplatePathResolver;
import act.view.View;
import act.ws.DefaultSecureTicketCodec;
import act.ws.SecureTicketCodec;
import act.ws.UsernameSecureTicketCodec;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.ParserConfig;
import me.tongfei.progressbar.ProgressBarStyle;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.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.mvc.MvcConfig;
import org.osgl.util.*;
import org.osgl.util.converter.TypeConverterRegistry;
import org.osgl.web.util.UserAgent;
import org.rythmengine.utils.Time;
import osgl.version.Version;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.ServerSocket;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Pattern;
import javax.inject.Provider;
public class AppConfig extends Config implements AppHolder> {
public static final String CONF_FILE_NAME = "app.conf";
public static final String CSRF_TOKEN_NAME = "__csrf__";
public static final String PORT_CLI_OVER_HTTP = Router.PORT_CLI_OVER_HTTP;
public static final String PORT_ADMIN = Router.PORT_ADMIN;
public static final String PORT_SYS = Router.PORT_SYS;
private App app;
static {
MvcConfig.registerAlarmListener(MvcConfig.ALARM_BIG_CONTENT_ENCOUNTERED, new $.Func0() {
@Override
public Object apply() throws NotAppliedException, $.Break {
ActionContext ctx = ActionContext.current();
if (null != ctx) {
ctx.setLargeResponseHint();
}
return null;
}
});
TypeConverterRegistry.INSTANCE.register(new Lang.TypeConverter() {
@Override
public Class convert(String s) {
return Act.appClassForName(s);
}
});
MvcConfig.errorPageRenderer(new ActErrorPageRender());
MvcConfig.beforeCommitResultHandler(ResultEvent.BEFORE_COMMIT_HANDLER);
MvcConfig.afterCommitResultHandler(ResultEvent.AFTER_COMMIT_HANDLER);
MvcConfig.messageTranslater(new $.Transformer() {
@Override
public String transform(String message) {
String translated = I18n.i18n(message);
if (message == translated) {
translated = I18n.i18n(MvcConfig.class, message);
}
if (message == translated) {
translated = I18n.i18n(act_messages.class, message);
}
return translated;
}
});
// Refer https://cloud.tencent.com/announce/detail/1112
ParserConfig.getGlobalInstance().setSafeMode(true);
}
private RouterRegexMacroLookup routerRegexMacroLookup;
/**
* Construct a AppConfig
with a map. The map is copied to
* the original map of the configuration instance
*
* @param configuration
*/
public AppConfig(Map configuration) {
super(configuration);
loadFromConfServer();
raw.putAll(extendedConfigurations());
}
// for unit test
public AppConfig() {
this((Map) System.getProperties());
this.routerRegexMacroLookup = new RouterRegexMacroLookup(this);
}
private void loadFromConfServer() {
String confServerEndpoint = get(CONF_SERVER_ENDPOINT, "");
if (S.blank(confServerEndpoint)) {
return;
}
E.invalidConfigurationIf(!confServerEndpoint.startsWith("http"), "conf-server.endpoint must be full URL, found: %s", confServerEndpoint);
String privateKey = confPrivateKey();
E.invalidConfigurationIf(S.blank(privateKey), "conf.private-key not configured for conf-server: " + confServerEndpoint);
String confId = confId();
E.invalidConfigurationIf(S.blank(confId), "conf.id not configured correctly for conf-server: " + confServerEndpoint);
OkHttpClient http = new OkHttpClient.Builder().build();
String url = S.concat(confServerEndpoint, "?id=", confId);
Request req = new Request.Builder().url(url).get().addHeader("Accept", "application/json").build();
try {
Response resp = http.newCall(req).execute();
if (!resp.isSuccessful()) {
warn("Error fetching configuration from conf-server. Response code: %s; Respond body: %s", resp.code(), resp.body().string());
} else {
String data = Crypto.decryptRSA(resp.body().string(), privateKey);
JSONObject json = JSON.parseObject(data);
raw.putAll(json);
}
} catch (IOException e) {
warn(e, "Error fetching configuration from conf-server: " + confServerEndpoint);
}
}
public AppConfig app(App app) {
E.NPE(app);
this.app = app;
AppConfigKey.onApp(app);
EventBus eventBus = app.eventBus();
if (null != eventBus) {
eventBus.bind(SysEventId.CLASS_LOADER_INITIALIZED, new SysEventListenerBase() {
@Override
public void on(AppClassLoaderInitialized event) throws Exception {
routerRegexMacroLookup = new RouterRegexMacroLookup(AppConfig.this);
}
});
} // else - must be in routing benchmark unit test
return this;
}
public void preloadConfigurations() {
long ms = $.ms();
// ensure JWT get evaluated first to set
// default value for dependency settings
jwtEnabled();
for (Method method : AppConfig.class.getDeclaredMethods()) {
boolean isPublic = Modifier.isPublic(method.getModifiers());
if (!isPublic || method.isAnnotationPresent(Lazy.class)) {
continue;
}
if (0 == method.getParameterTypes().length && !"preloadConfigurations".equals(method.getName())) {
$.invokeVirtual(this, method);
}
}
MvcConfig.renderJsonOutputCharset(renderJsonOutputCharset());
$.Func0 jsonContentProvider = jsonContentTypeProvider();
if (null != jsonContentTypeProvider) {
MvcConfig.jsonMediaTypeProvider(jsonContentProvider);
}
OsglConfig.setXmlRootTag(xmlRootTag());
OsglConfig.setThreadLocalBufferLimit(threadLocalBufRetentionLimit());
OsglConfig.registerGlobalInstanceFactory(new $.Function() {
final App app = Act.app();
@Override
public Object apply(Class aClass) throws NotAppliedException, $.Break {
return app.getInstance(aClass);
}
});
OsglConfig.setSingletonChecker(new $.Predicate() {
@Override
public boolean test(Object o) {
return app.isSingleton(o);
}
});
app().cache().setDefaultTTL(cacheTtl());
Map cacheSettings = subSet("cache");
for (Map.Entry entry : cacheSettings.entrySet()) {
String key = entry.getKey();
if (key.endsWith(".ttl")) {
String s = S.string(entry.getValue());
int ttl;
if (S.isInt(s)) {
ttl = Integer.parseInt(s);
} else if (s.contains("*")) {
List sl = S.fastSplit(s, "*");
int n = 1;
for (String sn : sl) {
n *= Integer.parseInt(sn.trim());
}
ttl = n;
} else {
throw new ConfigurationException("Invalid cache ttl configuration: " + key);
}
key = S.cut(key.substring(6)).beforeLast(".");
app().cache(key).setDefaultTTL(ttl);
}
}
logger.trace("Preload Config takes: %sms", $.ms() - ms);
}
public App app() {
return app;
}
public RouterRegexMacroLookup routerRegexMacroLookup() {
return routerRegexMacroLookup;
}
@Override
protected ConfigKey keyOf(String s) {
return AppConfigKey.valueOfIgnoreCase(s);
}
private Boolean apiDoc;
protected T enableApiDoc(boolean b) {
this.apiDoc = b;
return me();
}
public boolean apiDocEnabled() {
if (null == apiDoc) {
this.apiDoc = get(API_DOC_ENABLED, Act.isDev());
}
return this.apiDoc;
}
private void _mergeApiDocEnabled(AppConfig conf) {
if (!hasConfiguration(API_DOC_ENABLED)) {
this.apiDoc = conf.apiDoc;
}
}
private Boolean apiDocBuiltInHide;
protected T hideBuiltInEndpointsInApiDoc(boolean b) {
this.apiDocBuiltInHide = b;
return me();
}
public boolean isHideBuiltInEndpointsInApiDoc() {
if (null == apiDocBuiltInHide) {
apiDocBuiltInHide = get(API_DOC_HIDE_BUILT_IN_ENDPOINTS, true);
}
return apiDocBuiltInHide;
}
private void _mergeHideBuiltInEndpointsInApiDoc(AppConfig conf) {
if (!hasConfiguration(API_DOC_HIDE_BUILT_IN_ENDPOINTS)) {
this.apiDocBuiltInHide = conf.apiDocBuiltInHide;
}
}
private String appName;
protected T appName(String name) {
this.appName = S.requireNotBlank(name);
return me();
}
public String appName() {
if (S.blank(appName)) {
// - `app` not initialized yet: appName = get(APP_NAME, app.name());
appName = get(APP_NAME, Act.app().name());
}
return appName;
}
private void _mergeAppName(AppConfig conf) {
if (!hasConfiguration(APP_NAME)) {
this.appName = conf.appName;
}
}
private Boolean basicAuth;
protected T enableBasicAuthentication(boolean b) {
this.basicAuth = b;
return me();
}
public boolean basicAuthenticationEnabled() {
if (null == basicAuth) {
this.basicAuth = get(BASIC_AUTHENTICATION, Act.isDev());
}
return this.basicAuth;
}
private void _mergeBasicAuthentication(AppConfig conf) {
if (!hasConfiguration(BASIC_AUTHENTICATION)) {
this.basicAuth = conf.basicAuth;
}
}
private Boolean builtInReqHandlerEnabled;
protected T disableBuiltInReqHandler() {
builtInReqHandlerEnabled = false;
return me();
}
public boolean builtInReqHandlerEnabled() {
if (null == builtInReqHandlerEnabled) {
builtInReqHandlerEnabled = get(BUILT_IN_REQ_HANDLER_ENABLED, true);
}
return builtInReqHandlerEnabled;
}
private void _mergeBuiltInReqHandler(AppConfig conf) {
if (!hasConfiguration(BUILT_IN_REQ_HANDLER_ENABLED)) {
this.builtInReqHandlerEnabled = conf.builtInReqHandlerEnabled;
}
}
private Boolean cacheForOnDev;
protected T enableCacheForOnDevMode() {
cacheForOnDev = false;
return me();
}
public boolean cacheForOnDevMode() {
if (null == cacheForOnDev) {
cacheForOnDev = get(CACHE_FOR_ON_DEV, false);
}
return cacheForOnDev;
}
private void _mergeCacheForOnDev(AppConfig config) {
if (!hasConfiguration(CACHE_FOR_ON_DEV)) {
cacheForOnDev = config.cacheForOnDev;
}
}
private Integer captchaWidth;
protected T captchaWidth(int w) {
this.captchaWidth = w;
return me();
}
public int captchaWidth() {
if (null == captchaWidth) {
captchaWidth = getInteger(CAPTCHA_WIDTH, 200);
}
return captchaWidth;
}
private void _mergeCaptchaWidth(AppConfig config) {
if (!hasConfiguration(CAPTCHA_WIDTH)) {
captchaWidth = config.captchaWidth;
}
}
private Integer captchaHeight;
protected T captchaHeight(int h) {
this.captchaHeight = h;
return me();
}
public int captchaHeight() {
if (null == captchaHeight) {
captchaHeight = getInteger(CAPTCHA_HEIGHT, 70);
}
return captchaHeight;
}
private void _mergeCaptchaHeight(AppConfig config) {
if (!hasConfiguration(CAPTCHA_HEIGHT)) {
captchaHeight = config.captchaHeight;
}
}
private Color captchaBgColor;
protected T captchaBgColor(Color color) {
this.captchaBgColor = color;
return me();
}
public Color captchaBgColor() {
if (null == captchaBgColor) {
String s = get(CAPTCHA_BG_COLOR, "white");
Field f = $.fieldOf(Color.class, s, false);
if (null == f) {
warn("Invalid captcha.background.color found: " + s);
info("will use white as captcha.background.color");
captchaBgColor = Color.WHITE;
} else {
captchaBgColor = $.getFieldValue(null, f);
}
}
return captchaBgColor;
}
private void _mergeCaptchaBgColor(AppConfig config) {
if (!hasConfiguration(CAPTCHA_BG_COLOR)) {
captchaBgColor = config.captchaBgColor;
}
}
private String reCaptchaSecret;
protected T reCaptchaSecret(String secret) {
this.reCaptchaSecret = secret;
return me();
}
public String reCaptchaSecret() {
if (null != reCaptchaSecret) {
reCaptchaSecret = get(CAPTCHA_RECAPTCHA_SECRET, "");
}
return reCaptchaSecret;
}
public boolean reCaptchaActivated() {
return S.notBlank(reCaptchaSecret());
}
private void _mergeReCaptchaSecret(AppConfig config) {
if (!hasConfiguration(CAPTCHA_RECAPTCHA_SECRET)) {
reCaptchaSecret = config.reCaptchaSecret;
}
}
private Map extendedConfigurations;
protected T extendedConfigurations(Map conf) {
this.extendedConfigurations = conf;
return me();
}
private Map extendedConfigurations() {
if (null == extendedConfigurations) {
try {
Object confLoader = get(CONF_LOADER, new ExtendedAppConfLoader.DumbLoader());
this.extendedConfigurations = $.invokeVirtual(confLoader, "loadConfigurations");
} catch (Exception e) {
warn(e, "Error loading extended configurations");
this.extendedConfigurations = C.Map();
}
}
return extendedConfigurations;
}
private void _mergeExtendedAppConfLoader(AppConfig conf) {
if (!hasConfiguration(CONF_LOADER)) {
extendedConfigurations = conf.extendedConfigurations;
}
}
private String confId;
protected T confId(String key) {
this.confId = S.requireNotBlank(key);
return me();
}
public String confId() {
if (S.blank(confId)) {
confId = get(CONF_ID, S.concat(appName(), "-", Act.profile()));
}
return confId;
}
private void _mergeConfId(AppConfig conf) {
if (!hasConfiguration(CONF_ID)) {
this.confId = conf.confId;
}
}
private String confPrivateKey;
protected T confPrivateKey(String key) {
this.confPrivateKey = key;
return me();
}
private String confPrivateKey() {
if (S.blank(confPrivateKey)) {
confPrivateKey = get(CONF_PRIVATE_KEY, "");
}
return confPrivateKey;
}
private void _mergeConfPrivateId(AppConfig conf) {
if (!hasConfiguration(CONF_PRIVATE_KEY)) {
confPrivateKey = conf.confPrivateKey;
}
}
private Boolean cors;
protected T enableCors(boolean b) {
this.cors = b;
return me();
}
public boolean corsEnabled() {
if (null == cors) {
this.cors = get(CORS, false);
}
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) {
corsOrigin = get(CORS_ORIGIN, "*");
}
return corsOrigin;
}
private void _mergeCorsOrigin(AppConfig conf) {
if (!hasConfiguration(CORS_ORIGIN)) {
corsOrigin = conf.corsOrigin;
}
}
private String corsHeaders;
@Deprecated
protected T corsHeaders(String s) {
this.corsHeaders = s;
return me();
}
private String corsHeaders() {
if (null == corsHeaders) {
corsHeaders = get(CORS_HEADERS, "");
}
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) {
corsHeadersExpose = get(CORS_HEADERS_EXPOSE, "");
if (S.blank(corsHeadersExpose)) {
corsHeadersExpose = corsHeaders();
if (S.notBlank(corsHeadersExpose)) {
warn("`cors.headers` is deprecated. Please use `cors.headers.expose` instead");
} else {
corsHeadersExpose = "Act-Session-Expires, Authorization, X-XSRF-Token, X-CSRF-Token, Location, Link, Content-Disposition, Content-Length";
}
}
}
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) {
corsOptionCheck = get(CORS_CHECK_OPTION_METHOD, true);
}
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.corsHeadersAllowed = s;
return me();
}
public String corsAllowHeaders() {
if (null == corsHeadersAllowed) {
corsHeadersAllowed = get(CORS_HEADERS_ALLOWED, "");
if (S.isBlank(corsHeadersAllowed)) {
corsHeadersAllowed = corsHeaders();
if (S.notBlank(corsHeadersAllowed)) {
warn("`cors.headers` is deprecated. Please use `cors.headers.allowed` instead");
} else {
corsHeadersAllowed = "X-HTTP-Method-Override, X-Requested-With, Authorization, X-XSRF-Token, X-CSRF-Token";
}
}
}
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) {
corsMaxAge = getInteger(CORS_MAX_AGE, 30 * 60);
}
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, false);
}
return corsAllowCredentials;
}
private void _mergeCorsAllowCredential(AppConfig conf) {
if (!hasConfiguration(CORS_ALLOW_CREDENTIALS)) {
corsAllowCredentials = conf.corsAllowCredentials;
}
}
private String contentSecurityPolicy;
private boolean cspSet;
protected T contentSecurityPolicy(String policy) {
this.contentSecurityPolicy = policy;
cspSet = null != policy;
return me();
}
public String contentSecurityPolicy() {
if (!cspSet) {
contentSecurityPolicy = get(CONTENT_SECURITY_POLICY, null);
cspSet = true;
}
return contentSecurityPolicy;
}
private void _mergeCsp(AppConfig conf) {
if (!hasConfiguration(CONTENT_SECURITY_POLICY)) {
contentSecurityPolicy = conf.contentSecurityPolicy;
cspSet = null != contentSecurityPolicy;
}
}
private Boolean csrf;
protected T enableCsrf(boolean b) {
this.csrf = b;
return me();
}
public boolean csrfEnabled() {
if (null == csrf) {
this.csrf = get(CSRF, false);
}
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) {
csrfParamName = get(CSRF_PARAM_NAME, CSRF_TOKEN_NAME);
}
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 = $.requireNotNull(protector);
return me();
}
public CSRFProtector csrfProtector() {
if (null == csrfProtector) {
try {
csrfProtector = get(CSRF_PROTECTOR, 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) {
set(CSRF_PROTECTOR, 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) {
csrfCookieName = get(CSRF_COOKIE_NAME, "XSRF-TOKEN");
}
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) {
csrfHeaderName = get(CSRF_HEADER_NAME, X_XSRF_TOKEN);
}
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, 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) {
cliTablePageSz = getInteger(CLI_PAGE_SIZE_TABLE, 22);
}
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) {
cliJSONPageSz = getInteger(CLI_PAGE_SIZE_TABLE, 22);
}
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) {
cliOverHttp = get(CLI_OVER_HTTP, true);
}
return cliOverHttp;
}
private void _mergeCliOverHttp(AppConfig config) {
if (!hasConfiguration(CLI_OVER_HTTP)) {
cliOverHttp = config.cliOverHttp;
}
}
private ProgressBarStyle cliProgressBarStyle;
protected T cliProgressBarStyle(ProgressBarStyle style) {
this.cliProgressBarStyle = style;
return me();
}
public ProgressBarStyle cliProgressBarStyle() {
if (null == cliProgressBarStyle) {
String s = get(CLI_PROGRESS_BAR_STYLE, "unicode");
cliProgressBarStyle = S.eq("ascii", s) ? ProgressBarStyle.ASCII : ProgressBarStyle.UNICODE_BLOCK;
}
return cliProgressBarStyle;
}
private void _mergeCliProgressBarStyle(AppConfig config) {
if (!hasConfiguration(CLI_PROGRESS_BAR_STYLE)) {
cliProgressBarStyle = config.cliProgressBarStyle;
}
}
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, 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) {
cliOverHttpPort = get(CLI_OVER_HTTP_PORT, httpPort() + 2);
}
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, "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, 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) {
cliPort = get(CLI_PORT, httpPort() + 1);
}
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) {
cliSessionExpiration = get(CLI_SESSION_TTL, 300);
}
return cliSessionExpiration;
}
private void _mergeCliSessionExpiration(AppConfig conf) {
if (!hasConfiguration(CLI_SESSION_TTL)) {
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, "act_dsp_token");
}
return dspToken;
}
private void _mergeDspToken(AppConfig conf) {
if (!hasConfiguration(DOUBLE_SUBMISSION_PROTECT_TOKEN)) {
dspToken = conf.dspToken;
}
}
private Provider cookieDomainProvider;
protected T cookieDomain(final String domain) {
this.cookieDomainProvider = new Provider() {
@Override
public String get() {
return domain;
}
};
return me();
}
protected T cookieDomainProvider(Provider provider) {
this.cookieDomainProvider = $.requireNotNull(provider);
return me();
}
public String cookieDomain() {
String domain = cookieDomainProvider().get();
return "localhost".equals(domain) ? null : domain;
}
private Provider cookieDomainProvider() {
if (null == cookieDomainProvider) {
try {
cookieDomainProvider = get(COOKIE_DOMAIN_PROVIDER, new Provider() {
@Override
public String get() {
return host();
}
});
} 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() {
@Override
public String get() {
H.Request req = ActionContext.current().req();
return req.domain();
}
};
return cookieDomainProvider;
}
throw e;
}
}
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) {
maxCliSession = get(CLI_SESSION_MAX, 3);
}
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();
}
@Deprecated
public boolean enumResolvingCaseSensitive() {
synchronized (ENUM_RESOLVING_CASE_SENSITIVE) {
if (null == enumResolvingCaseSensitive) {
enumResolvingCaseSensitive = get(ENUM_RESOLVING_CASE_SENSITIVE, false);
}
return enumResolvingCaseSensitive;
}
}
private void _mergeEnumResolvingCaseSensitive(AppConfig conf) {
if (!hasConfiguration(ENUM_RESOLVING_CASE_SENSITIVE)) {
enumResolvingCaseSensitive = conf.enumResolvingCaseSensitive;
}
}
private Boolean enumResolvingExactMatch;
protected T enumResolvingExactMatch(boolean b) {
enumResolvingExactMatch = b;
return me();
}
public boolean enumResolvingExactMatch() {
synchronized (ENUM_RESOLVING_EXACT_MATCH) {
if (null == enumResolvingExactMatch) {
enumResolvingExactMatch = get(ENUM_RESOLVING_EXACT_MATCH, enumResolvingCaseSensitive());
}
return enumResolvingExactMatch;
}
}
private void _mergeEnumResolvingExactMatch(AppConfig config) {
if (!hasConfiguration(ENUM_RESOLVING_EXACT_MATCH)) {
enumResolvingExactMatch = config.enumResolvingExactMatch;
}
}
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, "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, "http");
}
return xForwardedProtocol;
}
private void _mergeXForwardedProtocol(AppConfig conf) {
if (!hasConfiguration(X_FORWARD_PROTOCOL)) {
xForwardedProtocol = conf.xForwardedProtocol;
}
}
private String xmlRootTag;
protected T xmlRootTag(String tag) {
this.xmlRootTag = tag;
return me();
}
public String xmlRootTag() {
if (null == xmlRootTag) {
xmlRootTag = get(XML_ROOT, "xml");
}
return xmlRootTag;
}
private void _mergeXmlRootTag(AppConfig conf) {
if (!hasConfiguration(XML_ROOT)) {
this.xmlRootTag = conf.xmlRootTag;
}
}
private ReturnValueAdvice globalReturnValueAdvice;
private Boolean globalReturnValueAdviceSet;
protected T globalReturnValueAdvice(ReturnValueAdvice advice) {
this.globalReturnValueAdvice = $.requireNotNull(advice);
this.globalReturnValueAdviceSet = true;
return me();
}
public ReturnValueAdvice globalReturnValueAdvice() {
if (null != globalReturnValueAdviceSet) {
return globalReturnValueAdvice;
}
String s = get(GLOBAL_RETURN_VALUE_ADVICE, null);
if (null != s) {
try {
globalReturnValueAdvice = app.getInstance(s);
} catch (Exception e) {
throw new ConfigurationException("Error loading global returnValueAdvice: " + s);
}
}
globalReturnValueAdviceSet = true;
return globalReturnValueAdvice;
}
private void _mergeGlobalReturnValueAdvice(AppConfig conf) {
if (!hasConfiguration(GLOBAL_RETURN_VALUE_ADVICE)) {
globalReturnValueAdvice = conf.globalReturnValueAdvice;
globalReturnValueAdviceSet = conf.globalReturnValueAdviceSet;
}
}
private ValidateViolationAdvice globalValidateViolationAdvice;
private Boolean globalValidateViolationAdviceSet;
protected T globalValidateViolationAdvice(ValidateViolationAdvice advice) {
this.globalValidateViolationAdvice = $.requireNotNull(advice);
this.globalValidateViolationAdviceSet = true;
return me();
}
public ValidateViolationAdvice globalValidateViolationAdvice() {
if (null != globalValidateViolationAdviceSet) {
return globalValidateViolationAdvice;
}
String s = get(GLOBAL_VALIDATE_VIOLATION_ADVICE, null);
if (null != s) {
try {
globalValidateViolationAdvice = app.getInstance(s);
} catch (Exception e) {
throw new ConfigurationException("Error loading global returnValueAdvice: " + s);
}
}
globalValidateViolationAdviceSet = true;
return globalValidateViolationAdvice;
}
private void _mergeGlobalValidateViolationAdvice(AppConfig conf) {
if (!hasConfiguration(GLOBAL_VALIDATE_VIOLATION_ADVICE)) {
globalValidateViolationAdvice = conf.globalValidateViolationAdvice;
globalValidateViolationAdviceSet = conf.globalValidateViolationAdviceSet;
}
}
private Boolean contentSuffixAware = null;
protected T contentSuffixAware(boolean b) {
contentSuffixAware = b;
return me();
}
public Boolean contentSuffixAware() {
if (null == contentSuffixAware) {
contentSuffixAware = get(CONTENT_SUFFIX_AWARE, 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) {
javax.inject.Provider<_SequenceNumberGenerator> provider = app().getInstance(SequenceNumberGenerator.Provider.class);
seqGen = get(DB_SEQ_GENERATOR, provider.get());
}
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, new ErrorTemplatePathResolver.DefaultErrorTemplatePathResolver());
}
return errorTemplatePathResolver;
}
private void _mergeErrorTemplatePathResolver(AppConfig conf) {
if (!hasConfiguration(RESOLVER_ERROR_TEMPLATE_PATH)) {
errorTemplatePathResolver = conf.errorTemplatePathResolver;
}
}
private Boolean headerOverwrite;
protected T allowHeaderOverwrite(boolean b) {
headerOverwrite = b;
return me();
}
public boolean allowHeaderOverwrite() {
if (null == headerOverwrite) {
headerOverwrite = get(HEADER_OVERWRITE, false);
}
return headerOverwrite;
}
private void _mergeHeaderOverwrite(AppConfig config) {
if (!hasConfiguration(HEADER_OVERWRITE)) {
headerOverwrite = config.headerOverwrite;
}
}
private String headerSessionExpiration;
protected T headerSessionExpiration(String headerName) {
headerSessionExpiration = headerName.trim();
return me();
}
public String headerSessionExpiration() {
if (null == headerSessionExpiration) {
headerSessionExpiration = get(AppConfigKey.HEADER_SESSION_EXPIRATION, "Act-Session-Expires");
}
return headerSessionExpiration;
}
private void _mergeHeaderSessionExpiration(AppConfig config) {
if (!hasConfiguration(HEADER_SESSION_EXPIRATION)) {
headerSessionExpiration = config.headerSessionExpiration;
}
}
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, "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) {
i18nEnabled = get(I18N, false);
}
return i18nEnabled;
}
private void _mergeI18nEnabled(AppConfig conf) {
if (!hasConfiguration(I18N)) {
i18nEnabled = conf.i18nEnabled;
}
}
private Boolean jwtEnabled;
protected T jwtEnabled(boolean enabled) {
jwtEnabled = enabled;
return me();
}
public boolean jwtEnabled() {
if (null == jwtEnabled) {
jwtEnabled = get(JWT, false);
if (jwtEnabled) {
if (!hasConfiguration(SESSION_HEADER)) {
sessionHeader("Authorization");
}
if (!hasConfiguration(SESSION_HEADER_PAYLOAD_PREFIX)) {
sessionHeaderPayloadPrefix("Bearer ");
}
if (!hasConfiguration(SESSION_MAPPER)) {
sessionMapper(new HeaderTokenSessionMapper(this));
}
if (!hasConfiguration(SESSION_CODEC)) {
sessionCodec(app().getInstance(JsonWebTokenSessionCodec.class));
}
}
}
return jwtEnabled;
}
private void _mergeJWT(AppConfig config) {
if (!hasConfiguration(JWT)) {
jwtEnabled = config.jwtEnabled;
}
}
private HMAC jwtAlgo;
protected T jwtArgo(HMAC.Algorithm algo) {
jwtAlgo = new HMAC(secret(), algo);
return me();
}
public HMAC jwtAlgo() {
if (null == jwtAlgo) {
String algoKey = get(JWT_ALGO, "SHA256");
if (rotateSecret()) {
jwtAlgo = new RotateSecretHMAC(algoKey, app.getInstance(RotationSecretProvider.class));
} else {
jwtAlgo = new HMAC(secret(), algoKey);
}
}
return jwtAlgo;
}
private void _mergeJWTAlgo(AppConfig config) {
if (!hasConfiguration(JWT_ALGO)) {
jwtAlgo = config.jwtAlgo;
}
}
private String jwtIssuer;
protected T jwtIssuer(String issuer) {
E.illegalArgumentIf(S.blank(issuer), "issuer cannot be empty");
jwtIssuer = issuer;
return me();
}
public String jwtIssuer() {
if (null == jwtIssuer) {
jwtIssuer = get(AppConfigKey.JWT_ISSUER, cookiePrefix().substring(0, cookiePrefix().length() - 1));
}
return jwtIssuer;
}
private void _mergeJwtIssuer(AppConfig config) {
if (!hasConfiguration(JWT_ISSUER)) {
jwtIssuer = config.jwtIssuer;
}
}
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) {
localeParamName = get(I18N_LOCALE_PARAM_NAME, "act_locale");
}
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) {
localeCookieName = get(I18N_LOCALE_COOKIE_NAME, "locale");
}
return localeCookieName;
}
private void _mergeLocaleCookieName(AppConfig conf) {
if (!hasConfiguration(I18N_LOCALE_COOKIE_NAME)) {
localeCookieName = conf.localeCookieName;
}
}
private Boolean mockServer;
protected T mockServer(boolean enabled) {
mockServer = enabled;
return me();
}
public boolean mockServer() {
if (null == mockServer) {
mockServer = get(MOCK_SERVER_ENABLED, app.isDev());
}
return mockServer;
}
private void _mergeMockServer(AppConfig config) {
if (!hasConfiguration(MOCK_SERVER_ENABLED)) {
mockServer = config.mockServer;
}
}
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, 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, 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, ".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, 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, 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, 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() {
ActionContext context = ActionContext.current();
if (null != context && context.isAjax()) {
return ajaxLoginUrl();
}
return loginUrl0();
}
private String loginUrl0() {
if (null == loginUrl) {
loginUrl = get(URL_LOGIN, "/login");
}
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, loginUrl0());
}
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, null);
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) {
httpMaxParams = getInteger(HTTP_MAX_PARAMS, 128);
if (httpMaxParams < 0) {
throw new ConfigurationException("http.params.max setting cannot be negative number. Found: %s", httpMaxParams);
}
}
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) {
jobPoolSize = getInteger(JOB_POOL_SIZE, 10);
}
return jobPoolSize;
}
private void _mergeJobPoolSize(AppConfig conf) {
if (!hasConfiguration(JOB_POOL_SIZE)) {
jobPoolSize = conf.jobPoolSize;
}
}
private Boolean jsonBodyPatch;
protected T jsonBodyPatch(boolean enabled) {
jsonBodyPatch = enabled;
return me();
}
public boolean allowJsonBodyPatch() {
if (null == jsonBodyPatch) {
jsonBodyPatch = get(JSON_BODY_PATCH, true);
}
return jsonBodyPatch;
}
private void _mergeJsonBodyPatch(AppConfig conf) {
if (!hasConfiguration(JSON_BODY_PATCH)) {
jsonBodyPatch = conf.jsonBodyPatch;
}
}
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) {
httpExternalPort = getInteger(HTTP_EXTERNAL_PORT, httpExternal() ? 80 : httpPort());
}
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) {
httpExternal = get(HTTP_EXTERNAL_SERVER, Act.isProd());
}
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) {
httpExternalSecurePort = get(HTTP_EXTERNAL_SECURE_PORT, httpExternal() ? 443 : httpPort());
}
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) {
if (Act.isTest()) {
httpPort = chooseRandomDefaultHttpPort();
} else {
httpPort = get(HTTP_PORT, 5460);
}
}
return httpPort;
}
private void _mergeHttpPort(AppConfig conf) {
if (!hasConfiguration(HTTP_PORT)) {
httpPort = conf.httpPort;
}
}
private static void clearRandomServerSockets() {
for (ServerSocket ss : randomServerSockets.values()) {
IO.close(ss);
}
randomServerSockets.clear();
}
public static void clearRandomServerSocket(int port) {
ServerSocket ss = randomServerSockets.remove(port);
IO.close(ss);
}
private static Map randomServerSockets = new HashMap<>();
private static int chooseRandomDefaultHttpPort() {
int maxTry = 10;
while (maxTry-- > 0) {
clearRandomServerSockets();
boolean ok = true;
int httpPort = randomPort();
Act.LOGGER.debug("Random port detected: " + httpPort);
for (int i = 1; i < 4; ++i) {
int port = httpPort + i;
ServerSocket ss = null;
try {
ss = new ServerSocket(port);
randomServerSockets.put(port, ss);
Act.LOGGER.debug("Successfully bind to port: " + port);
} catch (IOException e) {
ok = false;
break;
}
}
if (ok) {
Act.LOGGER.info("Default port allocated for testing: " + httpPort);
return httpPort;
}
}
throw new IllegalStateException("Unable to find random HTTP port");
}
private static int randomPort() {
ServerSocket ss = null;
try {
ss = new ServerSocket(0);
return ss.getLocalPort();
} catch (IOException e) {
throw E.ioException(e);
} finally {
IO.close(ss);
}
}
private Boolean httpSecure = null;
protected T httpSecure(boolean secure) {
this.httpSecure = secure;
return me();
}
public boolean httpSecure() {
if (null == httpSecure) {
httpSecure = get(HTTP_SECURE, !Act.isDev() && S.neq(Act.profile(), "dev", S.IGNORECASE));
}
return httpSecure;
}
private void _mergeHttpSecure(AppConfig conf) {
if (!hasConfiguration(HTTP_SECURE)) {
httpSecure = conf.httpSecure;
}
}
private int httpsPort = -1;
protected T httpsPort(int port) {
E.illegalArgumentIf(port < 1, "port value not valid: %s", port);
this.httpsPort = port;
return me();
}
public int httpsPort() {
if (-1 == httpsPort) {
httpsPort = get(HTTPS_PORT, 5443);
}
return httpsPort;
}
private void _mergeHttpsPort(AppConfig conf) {
if (!hasConfiguration(HTTPS_PORT)) {
httpsPort = conf.httpsPort;
}
}
private MissingAuthenticationHandler mah = null;
protected T missingAuthenticationHandler(MissingAuthenticationHandler handler) {
E.NPE(handler);
mah = handler;
return me();
}
public MissingAuthenticationHandler missingAuthenticationHandler() {
if (null == mah) {
RedirectToLoginUrl redirectToLoginUrl = app.getInstance(RedirectToLoginUrl.class);
MissingAuthenticationHandler defHandler = redirectToLoginUrl.hasLoginUrl() ? redirectToLoginUrl : app.getInstance(ReturnUnauthorized.class);
mah = get(HANDLER_MISSING_AUTHENTICATION, defHandler);
}
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, 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, 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, csrfCheckFailureHandler());
}
return ajaxCsrfCheckFailureHandler;
}
private void _mergeAjaxCsrfCheckFailureHandler(AppConfig config) {
if (!hasConfiguration(HANDLER_AJAX_CSRF_CHECK_FAILURE)) {
csrfCheckFailureHandler = config.csrfCheckFailureHandler;
}
}
private Integer threadlocalBufRetentionLimit;
protected T threadLocalBufRetentionLimit(int limit) {
threadlocalBufRetentionLimit = limit;
return me();
}
public int threadLocalBufRetentionLimit() {
if (null == threadlocalBufRetentionLimit) {
StrBufRetentionLimitCalculator calc = new StrBufRetentionLimitCalculator();
threadlocalBufRetentionLimit = get(OSGL_THREADLOCAL_BUF_LIMIT, 1024 * calc.calculate());
}
return threadlocalBufRetentionLimit;
}
private void _mergeStrBufRetentionLimit(AppConfig config) {
if (!hasConfiguration(OSGL_THREADLOCAL_BUF_LIMIT)) {
threadlocalBufRetentionLimit = config.threadlocalBufRetentionLimit;
}
}
private Password.Validator defPasswordValidator;
protected T defPasswordValidator(Password.Validator validator) {
defPasswordValidator = $.requireNotNull(validator);
return me();
}
protected T defPasswordSpec(String spec) {
_defPasswordSpec(spec);
return me();
}
public Password.Validator defPasswordValidator() {
if (null == defPasswordValidator) {
String s = get(PASSWORD_DEF_SPEC, Act.isDev() ? "a[3,]" : "aA0[6,]");
_defPasswordSpec(s);
}
return defPasswordValidator;
}
private void _defPasswordSpec(String spec) {
try {
defPasswordValidator = PasswordSpec.parse(spec);
} catch (IllegalArgumentException e) {
// try to check if the spec is a PasswordValidator
try {
defPasswordValidator = app.getInstance(spec);
} catch (Exception e2) {
throw new ConfigurationException("Password spec unrecognized: " + spec);
}
}
}
private Boolean monitorEnabled;
protected T enableMonitor(boolean enable) {
this.monitorEnabled = enable;
return me();
}
public boolean monitorEnabled() {
if (null == monitorEnabled) {
monitorEnabled = $.bool(get(MONITOR, false));
}
return monitorEnabled;
}
private void _mergeMonitorEnabled(AppConfig config) {
if (!hasConfiguration(MONITOR)) {
this.monitorEnabled = config.monitorEnabled;
}
}
private Map namedPorts = null;
protected T namedPorts(NamedPort... namedPorts) {
this.namedPorts = new HashMap<>();
for (NamedPort port : namedPorts) {
this.namedPorts.put(port.name(), port);
}
return me();
}
public Collection namedPorts() {
if (null == namedPorts) {
String s = get(NAMED_PORTS, null);
if (null == s) {
namedPorts = new HashMap<>();
} else {
String[] sa = (s.split("[,;]+"));
Map builder = new HashMap<>();
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.containsKey(port.name())) {
builder.put(port.name(), port);
} else {
throw E.invalidConfiguration("port[%s] already configured", name);
}
}
namedPorts = builder;
}
if (cliOverHttp() && !namedPorts.containsKey(PORT_CLI_OVER_HTTP)) {
namedPorts.put(PORT_CLI_OVER_HTTP, new NamedPort(PORT_CLI_OVER_HTTP, cliOverHttpPort()));
}
if (!namedPorts.containsKey(PORT_SYS)) {
namedPorts.put(PORT_SYS, new NamedPort(PORT_SYS, httpPort() + 3));
}
}
return namedPorts.values();
}
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, StandardCharsets.UTF_8.name());
}
return encoding;
}
private void _mergeEncoding(AppConfig conf) {
if (!hasConfiguration(ENCODING)) {
encoding = conf.encoding;
}
}
private volatile String datePattern = null;
private SimpleDateFormat dateFormat = null;
private final ThreadLocal dateFormatThreadLocal = new ThreadLocal() {
@Override
protected SimpleDateFormat initialValue() {
if (null == dateFormat) {
String pattern = datePattern();
if (null == dateFormat) {
dateFormat = new SimpleDateFormat(pattern);
}
}
return (SimpleDateFormat) dateFormat.clone();
}
};
protected T datePattern(String fmt) {
E.illegalArgumentIf(S.blank(fmt), "Date format pattern cannot be empty");
this.datePattern = fmt;
return me();
}
public SimpleDateFormat dateFormat() {
return dateFormatThreadLocal.get();
}
public String datePattern() {
if (null == datePattern) {
synchronized (this) {
if (null == datePattern) {
dateStyle = DateTimeStyle.MEDIUM;
datePattern = get(FORMAT_DATE, null);
if (null == datePattern) {
dateFormat = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.DEFAULT, locale());
} else if (S.eq(datePattern, "long", S.IGNORECASE)) {
dateStyle = DateTimeStyle.LONG;
dateFormat = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.LONG, locale());
} else if (S.eq(datePattern, "medium", S.IGNORECASE)) {
dateStyle = DateTimeStyle.MEDIUM;
dateFormat = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.MEDIUM, locale());
} else if (S.eq(datePattern, "short", S.IGNORECASE)) {
dateStyle = DateTimeStyle.SHORT;
dateFormat = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, locale());
}
if (null != dateFormat) {
datePattern = dateFormat.toPattern();
}
}
}
}
return datePattern;
}
private void _mergeDatePattern(AppConfig conf) {
if (!hasConfiguration(FORMAT_DATE)) {
datePattern = conf.datePattern;
dateStyle = conf.dateStyle;
}
}
private Map localizedDatePatterns = new HashMap<>();
public String localizedDatePattern(Locale locale) {
String s = localizedDatePatterns.get(locale);
if (null == s) {
s = getLocalizedDateTimePattern(locale, DateTimeType.DATE);
localizedDatePatterns.put(locale, s);
}
return s;
}
private volatile String timePattern = null;
private SimpleDateFormat timeFormat = null;
private final ThreadLocal timeFormatThreadLocal = new ThreadLocal() {
@Override
protected SimpleDateFormat initialValue() {
if (null == timeFormat) {
String pattern = timePattern();
if (null == timeFormat) {
timeFormat = new SimpleDateFormat(pattern);
}
}
return (SimpleDateFormat) timeFormat.clone();
}
};
protected T timePattern(String pattern) {
E.illegalArgumentIf(S.blank(pattern), "Time format pattern cannot be empty");
this.timePattern = pattern;
return me();
}
public SimpleDateFormat timeFormat() {
return timeFormatThreadLocal.get();
}
public String timePattern() {
if (null == timePattern) {
synchronized (this) {
if (null == timePattern) {
timeStyle = DateTimeStyle.MEDIUM;
timePattern = get(FORMAT_TIME, null);
if (null == timePattern) {
timeFormat = (SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.DEFAULT, locale());
} else if (S.eq(timePattern, "long", S.IGNORECASE)) {
timeStyle = DateTimeStyle.LONG;
timeFormat = (SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.LONG, locale());
} else if (S.eq(timePattern, "medium", S.IGNORECASE)) {
timeStyle = DateTimeStyle.MEDIUM;
timeFormat = (SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.MEDIUM, locale());
} else if (S.eq(timePattern, "short", S.IGNORECASE)) {
timeStyle = DateTimeStyle.SHORT;
timeFormat = (SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.SHORT, locale());
}
if (null != timeFormat) {
timePattern = timeFormat.toPattern();
}
}
}
}
return timePattern;
}
private void _mergeTimePattern(AppConfig conf) {
if (!hasConfiguration(FORMAT_TIME)) {
timePattern = conf.timePattern;
timeStyle = conf.timeStyle;
}
}
private Map localizedTimePattern = new HashMap<>();
public String localizedTimePattern(Locale locale) {
String s = localizedTimePattern.get(locale);
if (null == s) {
s = getLocalizedDateTimePattern(locale, DateTimeType.TIME);
localizedTimePattern.put(locale, s);
}
return s;
}
private volatile String dateTimePattern = null;
private SimpleDateFormat dateTimeFormat = null;
private final ThreadLocal dateTimeFormatThreadLocal = new ThreadLocal() {
@Override
protected SimpleDateFormat initialValue() {
if (null == dateTimeFormat) {
String pattern = dateTimePattern();
if (null == dateTimeFormat) {
dateTimeFormat = new SimpleDateFormat(pattern);
}
}
return (SimpleDateFormat) dateTimeFormat.clone();
}
};
protected T dateTimePattern(String pattern) {
E.illegalArgumentIf(S.blank(pattern), "Date time format pattern cannot be empty");
this.dateTimePattern = pattern;
return me();
}
public SimpleDateFormat dateTimeFormat() {
return dateTimeFormatThreadLocal.get();
}
public String dateTimePattern() {
if (null == dateTimePattern) {
synchronized (this) {
if (null == dateTimePattern) {
dateTimeStyle = DateTimeStyle.MEDIUM;
dateTimePattern = get(FORMAT_DATE_TIME, null);
if (null == dateTimePattern) {
dateTimeFormat = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, locale());
} else if (S.eq(dateTimePattern, "long", S.IGNORECASE)) {
dateTimeStyle = DateTimeStyle.LONG;
dateTimeFormat = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale());
} else if (S.eq(dateTimePattern, "medium", S.IGNORECASE)) {
dateTimeStyle = DateTimeStyle.MEDIUM;
dateTimeFormat = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, locale());
} else if (S.eq(dateTimePattern, "short", S.IGNORECASE)) {
dateTimeStyle = DateTimeStyle.SHORT;
dateTimeFormat = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale());
}
if (null != dateTimeFormat) {
dateTimePattern = dateTimeFormat.toPattern();
}
}
}
}
return dateTimePattern;
}
private void _mergeDateTimeFmt(AppConfig conf) {
if (!hasConfiguration(FORMAT_DATE_TIME)) {
dateTimePattern = conf.dateTimePattern;
}
}
private Map localizedDateTimePatterns = new HashMap<>();
public String localizedDateTimePattern(Locale locale) {
String s = localizedDateTimePatterns.get(locale);
if (null == s) {
s = getLocalizedDateTimePattern(locale, DateTimeType.DATE_TIME);
localizedDateTimePatterns.put(locale, s);
}
return s;
}
private boolean isLocaleMatchesDefault(Locale locale) {
return locale().equals(locale) || baseLocale.equals(locale);
}
private Locale locale = null;
private Locale baseLocale = null;
protected T locale(Locale locale) {
this.baseLocale = baseLocaleOf(locale);
this.locale = locale;
return me();
}
public Locale locale() {
if (null == locale) {
locale(get(LOCALE, Locale.getDefault()));
}
return locale;
}
private void _mergeLocale(AppConfig conf) {
if (!hasConfiguration(LOCALE)) {
locale = conf.locale;
baseLocale = conf.baseLocale;
}
}
private Locale baseLocaleOf(Locale locale) {
return new Locale.Builder().setLanguage(locale.getLanguage()).build();
}
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(SOURCE_VERSION, S.string($.JAVA_VERSION));
// sourceVersion = get(AppConfigKey.SOURCE_VERSION, null);
// if (null == sourceVersion) {
// int n = $.JAVA_VERSION;
// if (n > 8) {
// warn("ActFramework support compiling source code up to Java 8 only");
// n = 8;
// }
// sourceVersion = S.string(n);
// } else {
// if (sourceVersion.contains("1.")) {
// sourceVersion = sourceVersion.substring(2);
// }
// if (Integer.parseInt(sourceVersion) > 8) {
// warn("ActFramework support compiling source code up to Java 8 only");
// sourceVersion = "8";
// }
// }
}
return sourceVersion;
}
private void _mergeSourceVersion(AppConfig conf) {
if (!hasConfiguration(SOURCE_VERSION)) {
sourceVersion = conf.sourceVersion;
}
}
private Boolean selfHealing;
protected T selfHealing(boolean on) {
selfHealing = on;
return me();
}
public boolean selfHealing() {
if (null == selfHealing) {
selfHealing = get(SYS_SELF_HEALING, false);
}
return selfHealing;
}
private void _mergeSelfHealing(AppConfig conf) {
if (!hasConfiguration(SYS_SELF_HEALING)) {
selfHealing = conf.selfHealing;
}
}
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, null);
if (null == targetVersion) {
int n = $.JAVA_VERSION;
if (n > 8) {
warn("ActFramework support compiling source code up to Java 8 only");
n = 8;
}
targetVersion = S.string(n);
} else {
if (targetVersion.contains("1.")) {
targetVersion = targetVersion.substring(2);
}
if (Integer.parseInt(targetVersion) > 8) {
warn("ActFramework support compiling source code up to Java 8 only");
targetVersion = "8";
}
}
}
return targetVersion;
}
private void _mergeTargetVersion(AppConfig conf) {
if (!hasConfiguration(TARGET_VERSION)) {
targetVersion = conf.targetVersion;
}
}
private $.Predicate APP_CLASS_TESTER = null;
private final $.Predicate SYSTEM_SCAN_LIST = new $.Predicate() {
@Override
public boolean test(String s) {
final Set scanList = app().scanList();
if (scanList.contains(s)) {
return true;
}
if (s.startsWith("java.") || s.startsWith("javax.")) {
return false;
}
if (s.contains("$")) {
for (String pkg : scanList) {
if (s.startsWith(pkg + "$")) {
return true;
}
}
}
boolean shouldCheckPattern = false;
Set prefixList = app().scanPrefixList();
for (String prefix : prefixList) {
if (s.startsWith(prefix)) {
shouldCheckPattern = true;
break;
}
}
if (!shouldCheckPattern) {
return false;
}
shouldCheckPattern = false;
Set suffixList = app().scanSuffixList();
for (String suffix : suffixList) {
if (s.endsWith(suffix)) {
shouldCheckPattern = true;
break;
}
}
if (!shouldCheckPattern) {
return false;
}
for (Pattern pattern : app().scanPattern()) {
if (pattern.matcher(s).matches()) {
return true;
}
}
return false;
}
};
public $.Predicate appClassTester() {
if (null == APP_CLASS_TESTER) {
String scanPackage = get(AppConfigKey.SCAN_PACKAGE, null);
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;
for (int i = 0; i < len; ++i) {
String pkg = sp[i];
if (pkg.startsWith("act.") || "act".equals(pkg)) {
throw new ConfigurationException("Scan package cannot be 'act' or starts with 'act.'");
}
}
if (1 == len) {
APP_CLASS_TESTER = S.F.startsWith(sp[0]).or(SYSTEM_SCAN_LIST);
} else {
APP_CLASS_TESTER = new $.Predicate() {
@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 CONTROLLER_CLASS_TESTER = null;
private $.Predicate controllerNameTester() {
if (null == CONTROLLER_CLASS_TESTER) {
$.Predicate f = $.F.no();
CONTROLLER_CLASS_TESTER = f.or(app().router().f.IS_CONTROLLER);
}
return CONTROLLER_CLASS_TESTER;
}
private Integer testTimeout;
protected T testTimeout(int timeout) {
if (timeout < 10) {
logger.warn("test.timeout reset to minimum value: 10");
timeout = 10;
}
testTimeout = timeout;
return me();
}
public int testTimeout() {
if (null == testTimeout) {
int defTimeout = ("e2e".equalsIgnoreCase(Act.profile()) || "test".equalsIgnoreCase(Act.profile())) ? 10 : 60 * 60;
testTimeout = get(TEST_TIMEOUT, defTimeout);
this.testTimeout(testTimeout); // make sure we have a valid number
}
return testTimeout;
}
private void _mergeTestTimeout(AppConfig conf) {
if (!hasConfiguration(TEST_TIMEOUT)) {
testTimeout = conf.testTimeout;
}
}
private TemplatePathResolver templatePathResolver;
protected T templatePathResolver(TemplatePathResolver resolver) {
E.NPE(resolver);
templatePathResolver = resolver;
return me();
}
public TemplatePathResolver templatePathResolver() {
if (null == templatePathResolver) {
templatePathResolver = get(AppConfigKey.RESOLVER_TEMPLATE_PATH, 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, "default");
}
return templateHome;
}
private void _mergeTemplateHome(AppConfig conf) {
if (!hasConfiguration(AppConfigKey.TEMPLATE_HOME)) {
templateHome = conf.templateHome;
}
}
private Boolean paramBindingKeywordMatching;
protected T paramBindingKeywordMatching(boolean enabled) {
paramBindingKeywordMatching = enabled;
return me();
}
public boolean paramBindingKeywordMatching() {
if (null == paramBindingKeywordMatching) {
paramBindingKeywordMatching = get(PARAM_BINDING_KEYWORD_MATCHING, false);
}
return paramBindingKeywordMatching;
}
private void _mergeParamBindingKeywordMatching(AppConfig config) {
if (!hasConfiguration(PARAM_BINDING_KEYWORD_MATCHING)) {
paramBindingKeywordMatching = config.paramBindingKeywordMatching;
}
}
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, null);
pingPathResolved = true;
}
return pingPath;
}
private void _mergePingPath(AppConfig config) {
if (!hasConfiguration(AppConfigKey.PING_PATH)) {
pingPath = config.pingPath;
pingPathResolved = config.pingPathResolved;
}
}
private Integer reqThrottle;
protected T requestThrottle(final int throttle) {
E.illegalArgumentIf(throttle < 1, "request throttle must be positive integer");
this.reqThrottle = throttle;
return me();
}
public int requestThrottle() {
if (null == reqThrottle) {
reqThrottle = get(REQUEST_THROTTLE, 2);
}
return reqThrottle;
}
private void _mergeReqThrottle(AppConfig config) {
if (!hasConfiguration(REQUEST_THROTTLE)) {
this.reqThrottle = config.reqThrottle;
}
}
private Boolean reqThrottleExpireScale;
protected T requestThrottleExpireScale(final boolean enabled) {
this.reqThrottleExpireScale = enabled;
return me();
}
public boolean requestThrottleExpireScale() {
if (null == reqThrottleExpireScale) {
reqThrottleExpireScale = get(REQUEST_THROTTLE_EXPIRE_SCALE, false);
}
return reqThrottleExpireScale;
}
private void _mergeReqThrottleExpireScale(AppConfig config) {
if (!hasConfiguration(REQUEST_THROTTLE_EXPIRE_SCALE)) {
this.reqThrottleExpireScale = config.reqThrottleExpireScale;
}
}
private $.Func0 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 $.Func0() {
@Override
public H.Format apply() throws NotAppliedException, $.Break {
ActionContext context = ActionContext.current();
if (null != context) {
UserAgent ua = context.userAgent();
if (ua.isIE()) {
return jsonIE;
}
}
return H.Format.JSON;
}
};
}
public $.Func0 jsonContentTypeProvider() {
if (null == renderJsonIeFix) {
String contentType = get(RENDER_JSON_CONTENT_TYPE_IE, null);
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, false);
}
return renderJsonOutputCharset;
}
private void _mergeRenderJsonOutputCharset(AppConfig config) {
if (!hasConfiguration(RENDER_JSON_OUTPUT_CHARSET)) {
renderJsonOutputCharset = config.renderJsonOutputCharset;
}
}
private String serverHeader;
private static final String DEF_SERVER_HEADER = "act/" + Act.VERSION.getProjectVersion();
private static String DEF_APP_SERVER_HEADER = appServerHeader();
private static String appServerHeader() {
App app = Act.app();
if (null == app) {
return "app/1.0";
}
String shortId = app.shortId();
if (null == shortId) {
shortId = "app";
}
Version version = app.version();
return shortId + "/" + (null == version ? "1.0" : version.getProjectVersion());
}
protected T serverHeader(String header) {
serverHeader = header;
return me();
}
public String serverHeader() {
if (null == serverHeader) {
serverHeader = get(AppConfigKey.SERVER_HEADER, serverHeaderUseApp() ? DEF_APP_SERVER_HEADER : DEF_SERVER_HEADER);
}
return serverHeader;
}
private void _mergeServerHeader(AppConfig config) {
if (!hasConfiguration(AppConfigKey.SERVER_HEADER)) {
serverHeader = config.serverHeader;
}
}
private Boolean serverHeaderUseApp;
protected T serverHeaderUseApp(boolean b) {
serverHeaderUseApp = b;
return me();
}
private boolean serverHeaderUseApp() {
if (null == serverHeaderUseApp) {
serverHeaderUseApp = get(AppConfigKey.SERVER_HEADER_USE_APP, true);
}
return serverHeaderUseApp;
}
private void _mergeServerHeaderUseApp(AppConfig config) {
if (!hasConfiguration(SERVER_HEADER_USE_APP)) {
serverHeaderUseApp = config.serverHeaderUseApp;
}
}
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) {
sessionKeyUsername = get(SESSION_KEY_USERNAME, "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) {
String profile = Act.profile();
S.Buffer buf = S.buffer(app().shortId());
if (S.neq("prod", profile, S.IGNORECASE)) {
buf.a("-").a(profile);
}
buf.a("-");
cookiePrefix = get(COOKIE_PREFIX, buf.toString());
cookiePrefix = cookiePrefix.trim().toLowerCase();
set(COOKIE_PREFIX, cookiePrefix);
}
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 = get(AppConfigKey.SESSION_TTL, 60 * 30);
}
return sessionTtl;
}
private void _mergeSessionTtl(AppConfig conf) {
if (!hasConfiguration(AppConfigKey.SESSION_TTL)) {
sessionTtl = conf.sessionTtl;
}
}
private boolean sessionPassThrough;
private boolean sessionPassThroughSet; // use this to save auto-box of sessionPassThrough flag
protected T sessionPassThrough(boolean b) {
sessionPassThrough = b;
return me();
}
public boolean sessionPassThrough() {
if (!sessionPassThroughSet) {
sessionPassThrough = get(SESSION_PASS_THROUGH, false);
}
return sessionPassThrough;
}
private void _mergeSessionPassThrough(AppConfig config) {
if (!hasConfiguration(SESSION_PASS_THROUGH)) {
sessionPassThrough = config.sessionPassThrough;
}
}
private Boolean sessionPersistent;
protected T sessionPersistent(boolean persistenSession) {
sessionPersistent = persistenSession;
return me();
}
public boolean persistSession() {
if (null == sessionPersistent) {
sessionPersistent = get(AppConfigKey.SESSION_PERSISTENT_ENABLED, 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, false);
}
return sessionEncrypt;
}
private void _mergeSessionEncrpt(AppConfig config) {
if (!hasConfiguration(AppConfigKey.SESSION_ENCRYPT_ENABLED)) {
sessionEncrypt = config.sessionEncrypt;
}
}
private act.session.SessionMapper sessionMapper = null;
protected void sessionMapper(act.session.SessionMapper sessionMapper) {
this.sessionMapper = sessionMapper;
}
@Lazy
public act.session.SessionMapper sessionMapper() {
if (null == sessionMapper && null != app.injector()) {
sessionMapper = get(SESSION_MAPPER, app().getInstance(CookieSessionMapper.class));
}
return sessionMapper;
}
private void _mergeSessionMapper(AppConfig config) {
if (!hasConfiguration(AppConfigKey.SESSION_MAPPER)) {
sessionMapper = config.sessionMapper;
}
}
private SessionCodec sessionCodec = null;
protected void sessionCodec(SessionCodec codec) {
this.sessionCodec = $.requireNotNull(codec);
}
@Lazy
public SessionCodec sessionCodec() {
if (null == sessionCodec) {
if (null == app.injector()) {
// unit testing
sessionCodec = null;
} else {
sessionCodec = get(SESSION_CODEC, app.getInstance(DefaultSessionCodec.class));
}
}
return sessionCodec;
}
private void _mergeSessionCodec(AppConfig config) {
if (!hasConfiguration(AppConfigKey.SESSION_CODEC)) {
sessionCodec = config.sessionCodec;
}
}
private Boolean sessionOutputExpiration;
protected T sessionOutputExpiration(boolean enabled) {
sessionOutputExpiration = enabled;
return me();
}
public boolean sessionOutputExpiration() {
if (null == sessionOutputExpiration) {
sessionOutputExpiration = get(SESSION_OUTPUT_EXPIRATION, true);
}
return sessionOutputExpiration;
}
private String sessionHeader;
private boolean sessionHeaderSet;
protected T sessionHeader(String header) {
this.sessionHeader = header;
this.sessionHeaderSet = true;
return me();
}
public String sessionHeader() {
if (!sessionHeaderSet) {
sessionHeader = get(SESSION_HEADER, S.pathConcat(sessionHeaderPrefix(), '-', "Session"));
sessionHeaderSet = true;
}
return sessionHeader;
}
private void _mergeSessionHeader(AppConfig conf) {
if (!hasConfiguration(SESSION_HEADER)) {
sessionHeader = conf.sessionHeader;
sessionHeaderSet = conf.sessionHeaderSet;
}
}
private String sessionHeaderPrefix;
protected T sessionHeaderPrefix(String prefix) {
this.sessionHeaderPrefix = prefix;
return me();
}
public String sessionHeaderPrefix() {
if (null == sessionHeaderPrefix) {
sessionHeaderPrefix = get(SESSION_HEADER_PREFIX, HeaderTokenSessionMapper.DEF_HEADER_PREFIX);
}
return sessionHeaderPrefix;
}
private String sessionHeaderPayloadPrefix = null;
protected void sessionHeaderPayloadPrefix(String prefix) {
this.sessionHeaderPayloadPrefix = prefix;
}
public String sessionHeaderPayloadPrefix() {
if (null == sessionHeaderPayloadPrefix) {
String s = get(SESSION_HEADER_PAYLOAD_PREFIX, HeaderTokenSessionMapper.DEF_PAYLOAD_PREFIX);
s = S.strip(s).of(S.DOUBLE_QUOTES);
sessionHeaderPayloadPrefix = s;
}
return sessionHeaderPayloadPrefix;
}
private void _mergeSessionHeaderPayloadPrefix(AppConfig config) {
if (!hasConfiguration(AppConfigKey.SESSION_HEADER_PAYLOAD_PREFIX)) {
sessionHeaderPayloadPrefix = config.sessionHeaderPayloadPrefix;
}
}
private String sessionQueryParamName;
protected T sessionQueryParamName(String paramName) {
sessionQueryParamName = paramName;
return me();
}
public String getSessionQueryParamName() {
if (null == sessionQueryParamName) {
sessionQueryParamName = get(SESSION_QUERY_PARAM_NAME, sessionHeader());
}
return sessionQueryParamName;
}
private void _mergeSessionQueryParamName(AppConfig config) {
if (!hasConfiguration(SESSION_QUERY_PARAM_NAME)) {
sessionQueryParamName = config.sessionQueryParamName;
}
}
private Boolean sessionSecure = null;
protected T sessionSecure(boolean secure) {
sessionSecure = secure;
return me();
}
public boolean sessionSecure() {
if (null == sessionSecure) {
sessionSecure = get(AppConfigKey.SESSION_SECURE, httpSecure());
}
return sessionSecure;
}
private void _mergeSessionSecure(AppConfig config) {
if (!hasConfiguration(AppConfigKey.SESSION_SECURE)) {
sessionSecure = config.sessionSecure;
}
}
private volatile 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, "myawesomeapp");
if ("myawesomeapp".equals(secret)) {
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 Boolean secretRotate = null;
protected T secretRotate(boolean enabled) {
secretRotate = enabled;
return me();
}
public boolean rotateSecret() {
if (null == secretRotate) {
secretRotate = get(SECRET_ROTATE, false);
}
return secretRotate;
}
private void _mergeSecretRotate(AppConfig config) {
if (!hasConfiguration(SECRET_ROTATE)) {
secretRotate = config.secretRotate;
}
}
private Integer secretRotatePeriod;
/**
* Set `secret.rotate.period` in terms of minute
*
* @param period the minutes between two secret rotate happening
* @return this config object
* @see AppConfigKey#SECRET_ROTATE_PERIOD
*/
protected T secretRotatePeroid(int period) {
E.illegalArgumentIf(period < 1, "minimum secret.rotate.period is 1 (minute)");
secretRotatePeriod = period;
return me();
}
public int secretRotatePeriod() {
if (null == secretRotatePeriod) {
boolean validSetting = true;
String s = get(SECRET_ROTATE_PERIOD, "30");
int minutes;
if (!N.isInt(s)) {
int seconds = Time.parseDuration(s);
int reminder = seconds % 60;
if (0 != reminder) {
validSetting = false;
seconds += (60 - reminder);
}
minutes = seconds / 60;
} else {
minutes = Integer.parseInt(s);
}
if (minutes <= 0) {
validSetting = false;
minutes = 30;
}
secretRotatePeriod = RotationSecretProvider.roundToPeriod(minutes);
validSetting = validSetting && (secretRotatePeriod == minutes);
if (!validSetting) {
warn("invalid secret.rotate.period setting found: %s, system automatically set it to: %s", s, secretRotatePeriod);
}
}
return secretRotatePeriod;
}
private void _mergeSecretRotatePeriod(AppConfig config) {
if (!hasConfiguration(SECRET_ROTATE_PERIOD)) {
secretRotatePeriod = config.secretRotatePeriod;
}
}
private volatile SecureTicketCodec secureTicketCodec;
private String secureTicketCodecClass;
protected T secureTicketCodec(String secureTicketCodecClass) {
this.secureTicketCodecClass = $.requireNotNull(secureTicketCodecClass);
return me();
}
protected T secureTicketCodec(SecureTicketCodec codec) {
this.secureTicketCodec = $.requireNotNull(codec);
return me();
}
public SecureTicketCodec secureTicketCodec() {
if (null != secureTicketCodec) {
return secureTicketCodec;
}
synchronized (this) {
if (null != secureTicketCodec) {
return secureTicketCodec;
}
if (null == secureTicketCodecClass) {
secureTicketCodecClass = get(SECURE_TICKET_CODEC, null);
if (null == secureTicketCodecClass) {
secureTicketCodec = app().getInstance(DefaultSecureTicketCodec.class);
return secureTicketCodec;
}
if ("username".equalsIgnoreCase(secureTicketCodecClass)) {
secureTicketCodec = app().getInstance(UsernameSecureTicketCodec.class);
return secureTicketCodec;
}
secureTicketCodec = app().getInstance(secureTicketCodecClass);
}
}
return secureTicketCodec;
}
private void _mergeSecureTicketCodec(AppConfig config) {
if (!hasConfiguration(AppConfigKey.SECURE_TICKET_CODEC)) {
secureTicketCodec = config.secureTicketCodec;
secureTicketCodecClass = config.secureTicketCodecClass;
}
}
private Boolean traceHandler;
protected T traceHandler(boolean enabled) {
this.traceHandler = enabled;
return me();
}
public boolean traceHandler() {
if (null == traceHandler) {
traceHandler = get(TRACE_HANDLER_ENABLED, false);
}
return traceHandler;
}
// must be public, otherwise it get IllegalAccessError
public void toggleTraceHandler(boolean enabled) {
traceHandler = enabled;
}
private void _mergeTraceHandler(AppConfig config) {
if (!hasConfiguration(TRACE_HANDLER_ENABLED)) {
this.traceHandler = config.traceHandler;
}
}
private Boolean traceRequest;
protected T traceRequests(boolean enabled) {
this.traceRequest = enabled;
return me();
}
public boolean traceRequests() {
if (null == traceRequest) {
traceRequest = get(TRACE_REQUEST_ENABLED, false);
}
return traceRequest;
}
// must be public, otherwise it get IllegalAccessError
public void toggleTraceRequest(boolean enabled) {
traceRequest = enabled;
}
private void _mergeTraceRequests(AppConfig config) {
if (!hasConfiguration(TRACE_REQUEST_ENABLED)) {
this.traceRequest = config.traceRequest;
}
}
private List moduleBases;
public List moduleBases() {
if (null == moduleBases) {
String v = get(AppConfigKey.MODULES, null);
moduleBases = processModules(v);
}
return moduleBases;
}
private List processModules(String v) {
if (S.blank(v)) {
return C.list();
} else {
List files = new ArrayList<>();
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, 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 cacheServiceProvider = null;
protected T cacheService(CacheServiceProvider provider) {
E.NPE(provider);
this.cacheServiceProvider = provider;
return me();
}
protected T cacheService(Class extends CacheServiceProvider> provider) {
this.cacheServiceProvider = $.newInstance(provider);
return me();
}
public CacheService cacheService(String name) {
CacheService cacheService = cacheServiceProvider().get(name);
E.illegalStateIf(cacheService.state().isShutdown(), "Cache service[%s] already shutdown.", name);
if (!cacheService.state().isStarted()) {
cacheService.startup();
}
return cacheService;
}
public CacheServiceProvider cacheServiceProvider() {
if (null == cacheServiceProvider) {
CacheServiceProvider.Impl.setClassLoader(app().classLoader());
try {
cacheServiceProvider = get(AppConfigKey.CACHE_IMPL, null);
} catch (ConfigurationException e) {
Object obj = helper.getValFromAliases(raw, AppConfigKey.CACHE_IMPL.toString(), "impl", null);
cacheServiceProvider = CacheServiceProvider.Impl.valueOfIgnoreCase(obj.toString());
if (null != cacheServiceProvider) {
set(AppConfigKey.CACHE_IMPL, cacheServiceProvider);
} else {
throw e;
}
}
if (null == cacheServiceProvider) {
cacheServiceProvider = CacheServiceProvider.Impl.Auto;
}
}
return cacheServiceProvider;
}
public void resetCacheServices() {
if (!Act.isDev()) {
return;
}
OsglConfig.internalCache().clear();
}
private void _mergeCacheServiceProvider(AppConfig config) {
if (!hasConfiguration(AppConfigKey.CACHE_IMPL)) {
cacheServiceProvider = config.cacheServiceProvider;
}
}
private String _cacheName;
protected T cacheName(String name) {
this._cacheName = name;
return me();
}
public String cacheName() {
if (null == _cacheName) {
_cacheName = get(AppConfigKey.CACHE_NAME, "_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, cacheName());
}
return _cacheNameSession;
}
private void _mergeCacheNameSession(AppConfig config) {
if (!hasConfiguration(CACHE_NAME_SESSION)) {
_cacheNameSession = config._cacheNameSession;
}
}
private Integer cacheTtl;
protected T cacheTtl(int ttl) {
cacheTtl = ttl;
return me();
}
public int cacheTtl() {
if (null == cacheTtl) {
cacheTtl = getInteger(CACHE_TTL, 60);
}
return cacheTtl;
}
private void _mergeCacheTtl(AppConfig config) {
if (!hasConfiguration(CACHE_TTL)) {
cacheTtl = config.cacheTtl;
}
}
private UnknownHttpMethodProcessor _unknownHttpMethodProcessor = null;
protected T unknownHttpMethodProcessor(UnknownHttpMethodProcessor handler) {
this._unknownHttpMethodProcessor = $.requireNotNull(handler);
return me();
}
public UnknownHttpMethodProcessor unknownHttpMethodProcessor() {
if (null == _unknownHttpMethodProcessor) {
_unknownHttpMethodProcessor = get(AppConfigKey.HANDLER_UNKNOWN_HTTP_METHOD, 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 = get(RESOURCE_PRELOAD_SIZE_LIMIT, 1024 * 10);
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 resourceFiltering;
protected T resourceFiltering(boolean b) {
resourceFiltering = b;
return me();
}
public boolean resourceFiltering() {
if (null == resourceFiltering) {
if (app.isDev()) {
resourceFiltering = get(RESOURCE_FILTERING, true);
} else {
resourceFiltering = false;
}
}
return resourceFiltering;
}
private void _mergeResourceFiltering(AppConfig conf) {
if (!hasConfiguration(RESOURCE_FILTERING)) {
this.resourceFiltering = conf.resourceFiltering;
}
}
private static final ResourceBundle.Control DEF_RBC = ResourceBundle.Control.getControl(FORMAT_DEFAULT);
private String resourceBundleEncoding = null;
protected T resourceBundleEncoding(String encoding) {
resourceBundleEncoding = encoding;
return me();
}
public String resourceBundleEncoding() {
if (null == resourceBundleEncoding) {
resourceBundleEncoding = get(RESOURCE_BUNDLE_ENCODING, "default");
}
return resourceBundleEncoding;
}
private void _mergeResourceBundleEncoding(AppConfig conf) {
if (!hasConfiguration(RESOURCE_BUNDLE_ENCODING)) {
this.resourceBundleEncoding = conf.resourceBundleEncoding;
this.resourceBundleControl = null;
}
}
private ResourceBundle.Control resourceBundleControl;
public ResourceBundle.Control resourceBundleControl() {
synchronized (DEF_RBC) {
if (null != resourceBundleControl) {
return resourceBundleControl;
}
final String encoding = resourceBundleEncoding();
if ("default".equals(encoding)) {
resourceBundleControl = DEF_RBC;
} else {
resourceBundleControl = new ResourceBundle.Control() {
@Override
public ResourceBundle newBundle(
String baseName, Locale locale,
String format, ClassLoader loader,
boolean reload
) throws IllegalAccessException, InstantiationException, IOException {
// The below is a copy of the default implementation.
String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, "properties");
ResourceBundle bundle = null;
InputStream stream = null;
if (reload) {
URL url = loader.getResource(resourceName);
if (url != null) {
URLConnection connection = url.openConnection();
if (connection != null) {
connection.setUseCaches(false);
stream = connection.getInputStream();
}
}
} else {
stream = loader.getResourceAsStream(resourceName);
}
if (stream != null) {
try {
// Only this line is changed to make it to read properties files as UTF-8.
bundle = new PropertyResourceBundle(new InputStreamReader(stream, encoding));
} finally {
stream.close();
}
}
return bundle;
}
};
}
}
return resourceBundleControl;
}
private Integer uploadInMemoryCacheThreshold;
protected T uploadInMemoryCacheThreshold(int l) {
uploadInMemoryCacheThreshold = l;
return me();
}
public int uploadInMemoryCacheThreshold() {
if (null == uploadInMemoryCacheThreshold) {
uploadInMemoryCacheThreshold = get(UPLOAD_IN_MEMORY_CACHE_THRESHOLD, 1024 * 10);
}
return uploadInMemoryCacheThreshold;
}
private void _mergeUploadInMemoryCacheThreshold(AppConfig config) {
if (!hasConfiguration(UPLOAD_IN_MEMORY_CACHE_THRESHOLD)) {
uploadInMemoryCacheThreshold = config.uploadInMemoryCacheThreshold;
}
}
private Boolean ssl;
protected T supportSsl(boolean b) {
ssl = b;
return me();
}
public boolean supportSsl() {
if (null == ssl) {
ssl = get(SSL, false);
}
return ssl;
}
private void _mergeSslSupport(AppConfig config) {
if (!hasConfiguration(SSL)) {
ssl = config.ssl;
}
}
private String wsTicketKey;
protected T wsTicketeKey(String wsTicketKey) {
this.wsTicketKey = wsTicketKey;
return me();
}
public String wsTicketKey() {
if (null == wsTicketKey) {
wsTicketKey = get(WS_KEY_TICKET, "ws_ticket");
}
return wsTicketKey;
}
private void _mergeWsTicketKey(AppConfig config) {
if (!hasConfiguration(WS_KEY_TICKET)) {
wsTicketKey = config.wsTicketKey;
}
}
private Integer wsPurgeClosedConnPeriod;
protected T wsPurgeClosedConnPeriod(int period) {
this.wsPurgeClosedConnPeriod = period;
return me();
}
public int wsPurgeClosedConnPeriod() {
if (null == wsPurgeClosedConnPeriod) {
wsPurgeClosedConnPeriod = get(WS_PURGE_CLOSED_CONN_PERIOD, Act.isDev() ? 1 : 10);
}
return wsPurgeClosedConnPeriod;
}
private void _mergeWsPurgeClosedConnPeroid(AppConfig config) {
if (!hasConfiguration(WS_PURGE_CLOSED_CONN_PERIOD)) {
wsPurgeClosedConnPeriod = config.wsPurgeClosedConnPeriod;
}
}
private Set mergeTracker = C.newSet();
public void loadJarProperties(Map 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.emit(SysEventId.CONFIG_PREMERGE);
if (mergeTracker.contains(conf)) {
return;
}
mergeTracker.add(conf);
for (Method method : AppConfig.class.getDeclaredMethods()) {
boolean isPrivate = Modifier.isPrivate(method.getModifiers());
if (isPrivate && method.getName().startsWith("_merge")) {
method.setAccessible(true);
$.invokeVirtual(this, method, conf);
}
}
Set 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);
}
private ConcurrentMap<$.T2, String> localizedDateTimePatterns0 = new ConcurrentHashMap<>();
private String getLocalizedDateTimePattern(Locale locale, DateTimeType dateTimeType) {
$.T2 key = $.T2(locale, dateTimeType);
String s = localizedDateTimePatterns0.get(key);
if (null != s) {
return s;
}
String localStr = locale.toString().toLowerCase();
String conf = S.concat("fmt.", localStr, dateTimeType.suffix());
s = get(conf);
if (null == s) {
boolean canSplit = localStr.contains("_");
if (canSplit) {
s = get(S.concat("fmt.", S.replace('_').with('-').in(localStr), dateTimeType.suffix()));
if (null == s) {
s = get(S.concat("fmt.", S.cut(localStr).after("_"), dateTimeType.suffix()));
if (null == s) {
s = get(S.concat("fmt.", S.cut(localStr).before("_"), dateTimeType.suffix()));
}
}
}
}
if (null == s) {
if (isLocaleMatchesDefault(locale)) {
s = dateTimeType.defaultPattern(this);
} else {
DateTimeStyle style = dateTimeStyle();
if (dateTimeType == DateTimeType.DATE) {
style = dateStyle();
} else if (dateTimeType == DateTimeType.TIME) {
style = timeStyle();
}
s = dateTimeType.defaultPattern(style, locale);
}
} else {
if (S.eq("long", s, S.IGNORECASE)) {
s = dateTimeType.defaultPattern(DateTimeStyle.LONG, locale);
} else if (S.eq("medium", s, S.IGNORECASE)) {
s = dateTimeType.defaultPattern(DateTimeStyle.MEDIUM, locale);
} else if (S.eq("short", s, S.IGNORECASE)) {
s = dateTimeType.defaultPattern(DateTimeStyle.SHORT, locale);
}
}
localizedDateTimePatterns0.putIfAbsent(key, s);
return s;
}
private volatile DateTimeStyle dateTimeStyle;
public DateTimeStyle dateTimeStyle() {
if (null == dateTimeStyle) {
synchronized (this) {
if (null == dateTimeStyle) {
dateTimePattern();
}
}
}
return dateTimeStyle;
}
private volatile DateTimeStyle dateStyle;
public DateTimeStyle dateStyle() {
if (null == dateStyle) {
synchronized (this) {
if (null == dateStyle) {
datePattern();
}
}
}
return dateStyle;
}
private volatile DateTimeStyle timeStyle;
public DateTimeStyle timeStyle() {
if (null == timeStyle) {
synchronized (this) {
if (null == timeStyle) {
timePattern();
}
}
}
return timeStyle;
}
public void setDefaultTldReloadCron() {
raw.put(canonical(TopLevelDomainList.CRON_TLD_RELOAD), "0 0 2 * * *");
}
}