/* * Copyright 2012 The Solmix Project * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.gnu.org/licenses/ * or see the FSF site: http://www.fsf.org. */ package org.solmix.fmk.engine; import static org.osgi.framework.Constants.BUNDLE_VERSION; import java.io.IOException; import java.util.Dictionary; import java.util.Hashtable; import javax.servlet.GenericServlet; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; import org.osgi.framework.Version; import org.osgi.service.http.HttpService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.solmix.api.request.RequestProcessor; import org.solmix.api.servlet.FilterManager; import org.solmix.api.servlet.ServletManager; import org.solmix.fmk.engine.internal.SlxHttpContext; import org.solmix.fmk.engine.internal.SlxServletContext; import org.solmix.fmk.engine.internal.request.SlxRequestProcessor; /** * * @author Administrator * @version 110035 2012-4-12 */ public class MainServlet extends GenericServlet { /** * Gerneration Serial verison UID. */ private static final long serialVersionUID = -3935191639532112181L; public static String ROOT = "/"; public static String PRODUCT_NAME = "solmix"; private volatile BundleContext managedContext; private HttpService httpService; private String productInfo = PRODUCT_NAME; private String serverInfo; private final SlxRequestProcessor requestProcessor = new SlxRequestProcessor(); private final SlxHttpContext httpContext = new SlxHttpContext(); private String paramaterEncoding; /** default log */ private final Logger log = LoggerFactory.getLogger(MainServlet.class); private ServiceRegistration<?> requestProcessorRegistration; private SlxServletContext slxServletContext; /** * {@inheritDoc} * * @see javax.servlet.GenericServlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse) */ @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { res.setCharacterEncoding(paramaterEncoding); if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) { HttpServletRequest request = (HttpServletRequest) req; // set the thread name according to the request String threadName = setThreadName(request); // TODO 发送事项 requestProcessor.processRequest(request, (HttpServletResponse) res); Thread.currentThread().setName(threadName); } else { throw new ServletException("Application Engine must be run in an HTTP servlet environment."); } } /** * Blueprint init-Method. */ public void activate() { // setup server info setProductInfo(managedContext); final Dictionary<String, String> configuration = new Hashtable<String, String>(); // put parameter configuration with services. configuration.put(EngineConstants.PROP_DEFAULT_PARAMETER_ENCODING, this.paramaterEncoding); try { this.httpService.registerServlet(ROOT, this, configuration, httpContext); log.info("{} ready to serve requests", this.getServerInfo()); } catch (Exception e) { log.error("Cannot register " + this.getServerInfo(), e); } slxServletContext = new SlxServletContext(this.managedContext, this); // provide the RequestProcessor service Hashtable<String, String> srpProps = new Hashtable<String, String>(); srpProps.put(Constants.SERVICE_DESCRIPTION, "Solmix Request Processor"); requestProcessorRegistration = managedContext.registerService(RequestProcessor.NAME, requestProcessor, srpProps); } /** * Blueprint destroy-Method. */ public void deactivate() { if (requestProcessorRegistration != null) { requestProcessorRegistration.unregister(); this.requestProcessorRegistration = null; } // if (slxServletContext != null) { slxServletContext.dispose(); slxServletContext = null; } // httpService.unregister(ROOT); log.info(this.getServerInfo() + " shut down"); } @Override public void init() { setServerInfo(); } /** * @return the productInfo */ public String getProductInfo() { return productInfo; } /** * @return the serverInfo */ public String getServerInfo() { return serverInfo; } /** * @param productInfo the productInfo to set */ private void setProductInfo(final BundleContext bundleContext) { final Dictionary<?, ?> props = bundleContext.getBundle().getHeaders(); final Version bundleVersion = Version.parseVersion((String) props.get(BUNDLE_VERSION)); final String productVersion = bundleVersion.getMajor() + "." + bundleVersion.getMinor(); this.productInfo = PRODUCT_NAME + "/" + productVersion; // update the server info this.setServerInfo(); } private void setServerInfo() { final String containerProductInfo; if (getServletConfig() == null || getServletContext() == null) { containerProductInfo = "unregistered"; } else { final String containerInfo = getServletContext().getServerInfo(); if (containerInfo != null && containerInfo.length() > 0) { int lbrace = containerInfo.indexOf('('); if (lbrace < 0) { lbrace = containerInfo.length(); } containerProductInfo = containerInfo.substring(0, lbrace).trim(); } else { containerProductInfo = "unknown"; } } this.serverInfo = String.format("%s (%s, %s %s, %s %s %s)", this.productInfo, containerProductInfo, System.getProperty("java.vm.name"), System.getProperty("java.version"), System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch")); if (this.requestProcessor != null) { this.requestProcessor.setServerInfo(serverInfo); } } public <Type> Type adaptTo(Object object, Class<Type> type) { // AdapterManager adapterManager = this.adapterManager; // if (adapterManager != null) { // return adapterManager.getAdapter(object, type); // } // no adapter manager, nothing to adapt to return null; } /** * @return the managedContext */ public BundleContext getManagedContext() { return managedContext; } /** * @param managedContext the managedContext to set */ public void setManagedContext(BundleContext managedContext) { this.managedContext = managedContext; } /** * @return the httpService */ public HttpService getHttpService() { return httpService; } /** * @param httpService the httpService to set */ public void setHttpService(HttpService httpService) { this.httpService = httpService; } /** * @return the servletManager */ public void unsetServletManager(ServletManager servletManager) { requestProcessor.unsetServletManager(servletManager); } /** * Inject servletManager to {@link org.solmix.fmk.engine.internal.request.SlxRequestProcessor requestProcessor} * * @param servletManager the servletManager to set */ public void setServletManager(ServletManager servletManager) { requestProcessor.setServletManager(servletManager); } /** * @return the paramaterEncoding */ public String getParamaterEncoding() { return paramaterEncoding; } /** * @param paramaterEncoding the paramaterEncoding to set */ public void setParamaterEncoding(String paramaterEncoding) { this.paramaterEncoding = paramaterEncoding; } /** * Sets the name of the current thread to the IP address of the remote client with the current system time and the * first request line consisting of the method, path and protocol. * * @param request The request to extract the remote IP address, method, request URL and protocol from. * @return The name of the current thread before setting the new name. */ private String setThreadName(HttpServletRequest request) { // get the name of the current thread (to be returned) Thread thread = Thread.currentThread(); String oldThreadName = thread.getName(); // construct and set the new thread name of the form: // 127.0.0.1 [1224156108055] GET /system/console/config HTTP/1.1 StringBuffer buf = new StringBuffer(); buf.append(request.getRemoteAddr()); buf.append(" [").append(System.currentTimeMillis()).append("] "); buf.append(request.getMethod()).append(' '); buf.append(request.getRequestURI()).append(' '); buf.append(request.getProtocol()); thread.setName(buf.toString()); // return the previous thread name return oldThreadName; } /** * @param filterManager the filterManager to set */ public void setFilterManager(FilterManager filterManager) { requestProcessor.setFilterManager(filterManager); } }