package org.xins.server;
import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.xins.common.MandatoryArgumentChecker;
import org.xins.common.Utils;
import org.xins.common.collections.InvalidPropertyValueException;
import org.xins.common.collections.MissingRequiredPropertyException;
import org.xins.common.servlet.ServletToMapConverter;
import org.xins.common.text.TextUtils;
final class EngineStarter {
private static final String API_CLASS_PROPERTY = "org.xins.api.class";
private static final String API_NAME_PROPERTY = "org.xins.api.name";
private static final String API_BUILD_VERSION_PROPERTY = "org.xins.api.build.version";
private ServletConfig _config;
private long _startedTime = System.currentTimeMillis();
EngineStarter(ServletConfig config)
throws IllegalArgumentException {
MandatoryArgumentChecker.check("config", config);
_config = config;
}
static ServletException servletExceptionFor(Throwable t) {
ServletException servletException;
if (t instanceof ServletException) {
servletException = (ServletException) t;
} else if (t != null) {
servletException = new ServletException(t);
} else {
servletException = new ServletException();
}
return servletException;
}
void logBootMessages() {
ServletContext context = _config.getServletContext();
String containerInfo = context.getServerInfo();
if (containerInfo == null) {
throw Utils.logProgrammingError(
"ServletContext.getServerInfo() returned null.");
}
String jvmVendor = System.getProperty("java.vm.vendor");
String jvmName = System.getProperty("java.vm.name");
String jvmVersion = System.getProperty("java.vm.version");
String jvmInfo = jvmVendor + " " + jvmName + " " + jvmVersion;
String osName = System.getProperty("os.name");
String osVersion = System.getProperty("os.version");
String osArch = System.getProperty("os.arch");
String osInfo = osName + " " + osVersion + "/" + osArch;
String serverVersion = Library.getVersion();
Log.log_3200(serverVersion, containerInfo, jvmInfo, osInfo);
String commonVersion = org.xins.common.Library.getVersion();
if (! serverVersion.equals(commonVersion)) {
Log.log_3226(serverVersion, commonVersion);
}
if (! Library.isProductionRelease(serverVersion)) {
Log.log_3227(serverVersion);
}
if (Library.isProductionRelease(serverVersion)) {
String propName = API_BUILD_VERSION_PROPERTY;
String buildVersion = _config.getInitParameter(propName);
if (buildVersion == null) {
Log.log_3232(propName);
}
}
checkSystemVersion();
}
private void checkSystemVersion() {
double javaVersion = Double.parseDouble(System.getProperty("java.vm.specification.version"));
if (javaVersion < 1.7) {
Log.log_3004(javaVersion);
}
int majorServletVersion = _config.getServletContext().getMajorVersion();
if (majorServletVersion < 3) {
Log.log_3005(majorServletVersion + "." + _config.getServletContext().getMinorVersion());
}
}
API constructAPI()
throws ServletException {
String apiClassName = determineAPIClassName();
Class apiClass = loadAPIClass(apiClassName);
API api = createAPI(apiClass);
checkAPIConstruction(apiClass, api);
return api;
}
private void checkAPIConstruction(Class apiClass, API api)
throws ServletException {
if (api == null) {
String detail = "Creation of the API "
+ apiClass.getName()
+ " failed.";
Log.log_3208(API_CLASS_PROPERTY, apiClass.getName(), detail);
throw new ServletException();
}
if (api.getClass() != apiClass) {
String detail = "Incorrect instance of the API created. "
+ api.getClass()
+ " is not an instance of class " + apiClass.getName() + ".";
Log.log_3208(API_CLASS_PROPERTY, apiClass.getName(), detail);
throw new ServletException();
}
}
private API createAPI(Class apiClass)
throws ServletException {
API api;
try {
api = (API) apiClass.newInstance();
} catch (Throwable exception) {
String detail = "Caught unexpected "
+ exception.getClass().getName()
+ " while creating class "
+ apiClass.getName()
+ '.';
Utils.logProgrammingError(detail, exception);
Log.log_3208(API_CLASS_PROPERTY, apiClass.getName(), detail);
throw servletExceptionFor(exception);
}
return api;
}
private Class loadAPIClass(String apiClassName)
throws IllegalArgumentException, ServletException {
MandatoryArgumentChecker.check("apiClassName", apiClassName);
Class apiClass;
try {
apiClass = Class.forName(apiClassName, true, Utils.getContextClassLoader());
} catch (Throwable exception) {
Log.log_3207(exception, API_CLASS_PROPERTY, apiClassName);
throw servletExceptionFor(exception);
}
if (! API.class.isAssignableFrom(apiClass)) {
String detail = "Class "
+ apiClassName
+ " is not derived from "
+ API.class.getName()
+ '.';
Log.log_3208(API_CLASS_PROPERTY, apiClassName, detail);
throw new ServletException();
}
return apiClass;
}
private String determineAPIClassName()
throws ServletException {
String apiClassName = _config.getInitParameter(API_CLASS_PROPERTY);
apiClassName = TextUtils.isEmpty(apiClassName)
? null
: apiClassName.trim();
if (apiClassName == null) {
Log.log_3206(API_CLASS_PROPERTY);
throw new ServletException();
}
return apiClassName;
}
Map<String, String> bootstrap(API api) throws ServletException {
Map<String, String> properties = ServletToMapConverter.servletConfigToMap(_config);
String stackTraceAtMessageLevel = properties.get(ConfigManager.LOG_STACK_TRACE_AT_MESSAGE_LEVEL);
if ("true".equals(stackTraceAtMessageLevel)) {
org.znerd.logdoc.Library.setStackTraceAtMessageLevel(true);
} else if ("false".equals(stackTraceAtMessageLevel)) {
org.znerd.logdoc.Library.setStackTraceAtMessageLevel(false);
} else if (stackTraceAtMessageLevel != null) {
throw new ServletException("Incorrect value for the " + ConfigManager.LOG_STACK_TRACE_AT_MESSAGE_LEVEL + " bootstrap property.");
}
Throwable caught;
try {
api.bootstrap(properties);
caught = null;
} catch (MissingRequiredPropertyException exception) {
Log.log_3209(exception.getPropertyName(), exception.getDetail());
caught = exception;
} catch (InvalidPropertyValueException exception) {
Log.log_3210(exception.getPropertyName(),
exception.getPropertyValue(),
exception.getReason());
caught = exception;
} catch (Throwable exception) {
Log.log_3211(exception);
caught = exception;
}
if (caught != null) {
ServletException se = new ServletException("API bootstrap failed.", caught);
throw se;
}
return properties;
}
void loadLogdoc() throws ServletException {
}
private String determineLogdocName() {
String apiClassName = _config.getInitParameter(API_CLASS_PROPERTY);
String classPrefix;
int lastDot = apiClassName.lastIndexOf('.');
if (lastDot < 0) {
classPrefix = "";
} else {
classPrefix = apiClassName.substring(0, lastDot + 1);
}
String logdocClassName = classPrefix + "Log";
return logdocClassName;
}
String determineAPIName() throws ServletException {
String apiName = _config.getInitParameter(API_NAME_PROPERTY);
if (apiName != null) {
apiName = apiName.trim();
}
if (TextUtils.isEmpty(apiName)) {
Log.log_3232(API_NAME_PROPERTY);
throw new ServletException("The API name is not set.");
} else {
apiName = apiName.trim();
Log.log_3235(apiName);
}
return apiName;
}
void registerMBean(API api) {
try {
APIManager.registerMBean(api);
} catch (Throwable ex) {
Log.log_3249(ex.getMessage());
}
}
long getStartedTime() {
return _startedTime;
}
}