/** * Understands and applies the following integer properties. * * <ul> * <li>max.size - setMaximumSize * <li>max.threads - setMaximumThreads * <li>timeout.idle - setIdleTimeout * <li>timeout.transaction - setTransactionTimeout * <li>tune.size - Automatically tunes queue size when "true" and transaction timeout set. * <li>tune.threads - Automatically tunes maximum thread count. * </ul> */ public synchronized void applyProperties(PropertyMap properties) { if (properties.containsKey("max.size")) { setMaximumSize(properties.getInt("max.size")); } if (properties.containsKey("max.threads")) { setMaximumThreads(properties.getInt("max.threads")); } if (properties.containsKey("timeout.idle")) { setIdleTimeout(properties.getNumber("timeout.idle").longValue()); } if (properties.containsKey("timeout.transaction")) { setTransactionTimeout(properties.getNumber("timeout.transaction").longValue()); } if ("true".equalsIgnoreCase(properties.getString("tune.size"))) { addTransactionQueueListener(new TransactionQueueSizeTuner()); } if ("true".equalsIgnoreCase(properties.getString("tune.threads"))) { addTransactionQueueListener(new TransactionQueueThreadTuner()); } }
private void additiveMerge(PropertyMap properties, String property, String separator) { String merging = properties.getString(property); if (merging != null) { String existing = mProperties.getString(property); if (existing == null || existing.length() == 0) { mProperties.put(property, merging); } else { mProperties.put(property, existing + separator + merging); } } }
private TeaServletEngine createTeaServletEngine() throws ServletException { TeaServletEngineImpl engine; if (mProperties.getBoolean("autocompile", false)) { engine = new TeaServletEngineImplDev(); } else { engine = new TeaServletEngineImpl(); } Object tsea = mServletContext.getAttribute(ENGINE_ATTR); if (tsea == null || !(tsea instanceof TeaServletEngine[])) { tsea = new TeaServletEngine[] {engine}; } else { TeaServletEngine[] old_tsea = (TeaServletEngine[]) tsea; int old_length = old_tsea.length; tsea = new TeaServletEngine[old_length + 1]; int i; for (i = 0; i < old_length; i++) { ((TeaServletEngine[]) tsea)[i + 1] = old_tsea[i]; } ((TeaServletEngine[]) tsea)[0] = engine; } mServletContext.setAttribute(ENGINE_ATTR, tsea); return engine; }
/** * Process the user's http get request. Process the template that maps to the URI that was hit. * * @param request the user's http request * @param response the user's http response */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (processStatus(request, response)) { return; } if (!isRunning()) { int errorCode = mProperties.getInt("startup.codes.error", 503); response.sendError(errorCode); return; } if (mUseSpiderableRequest) { request = new SpiderableRequest(request, mQuerySeparator, mParameterSeparator, mValueSeparator); } // start transaction TeaServletTransaction tsTrans = getEngine().createTransaction(request, response, true); // load associated request/response ApplicationRequest appRequest = tsTrans.getRequest(); ApplicationResponse appResponse = tsTrans.getResponse(); // process template processTemplate(appRequest, appResponse); appResponse.finish(); // flush the output response.flushBuffer(); }
/** * Initializes the TeaServlet. Creates the logger and loads the user's application. * * @param config the servlet config */ public void init(ServletConfig config) throws ServletException { super.init(config); mServletConfig = config; config.getServletContext().log("Initializing TeaServlet..."); String ver = System.getProperty("java.version"); if (ver.startsWith("0.") || ver.startsWith("1.2") || ver.startsWith("1.3")) { config.getServletContext().log("The TeaServlet requires Java 1.4 or higher to run properly"); } mServletContext = setServletContext(config); mServletName = setServletName(config); mProperties = new PropertyMap(); mSubstitutions = SubstitutionFactory.getDefaults(); mResourceFactory = new TeaServletResourceFactory(config.getServletContext(), mSubstitutions); Enumeration<?> e = config.getInitParameterNames(); while (e.hasMoreElements()) { String key = (String) e.nextElement(); String value = SubstitutionFactory.substitute(config.getInitParameter(key)); if (key.equals("debug")) { mDebugEnabled = Boolean.parseBoolean(value); continue; } mProperties.put(key, value); } loadDefaults(); discoverProperties(); createListeners(); createLog(mServletContext); mLog.applyProperties(mProperties.subMap("log")); createMemoryLog(mLog); mInstrumentationEnabled = mProperties.getBoolean("instrumentation.enabled", true); Initializer initializer = new Initializer(); if (mProperties.getBoolean("startup.background", false)) { mInitializer = Executors.newSingleThreadExecutor().submit(initializer); } else { initializer.call(); } }
private void mergeProperties(PropertyMap properties) { // merge in properties w/o overwriting mProperties.putDefaults(properties); // custom merges additiveMerge(properties, "template.path", ";"); additiveMerge(properties, "template.imports", ";"); additiveMerge(properties, "assets.path", ","); }
private PropertyMap loadProperties(PropertyMap factoryProps) throws Exception { String className = null; PropertyMapFactory factory = null; if (factoryProps != null && factoryProps.size() > 0 && (className = factoryProps.getString("class")) != null) { if (mDebugEnabled) { mServletContext.log("Using property factory: " + className); } // Load and use custom PropertyMapFactory. Class<?> factoryClass = Class.forName(className); java.lang.reflect.Constructor<?> ctor = factoryClass.getConstructor(new Class[] {Map.class}); factory = (PropertyMapFactory) ctor.newInstance(new Object[] {factoryProps.subMap("init")}); } else if (factoryProps == null) { if (mDebugEnabled) { mServletContext.log("factoryProps is null."); } } else if (factoryProps.size() == 0) { if (mDebugEnabled) { mServletContext.log("factory props size is 0."); } } else { if (mDebugEnabled) { mServletContext.log("className is null"); } } // return properties PropertyMap result = null; if (factory != null) { result = factory.createProperties(); if (mDebugEnabled) { mServletContext.log("properties: " + result); } } return result; }
private void createMemoryLog(Log log) { if (log != null) { // Create memory log listener. mLogEvents = Collections.synchronizedList(new LinkedList<LogEvent>()); // The maximum number of log events to store in memory. final int logEventsMax = mProperties.getInt("log.max", 100); log.addRootLogListener( new TeaLogListener() { public void logMessage(LogEvent e) { checkSize(); mLogEvents.add(e); } public void logException(LogEvent e) { checkSize(); mLogEvents.add(e); } public void logTeaStackTrace(TeaLogEvent e) { checkSize(); mLogEvents.add(e); } private void checkSize() { while (mLogEvents.size() >= logEventsMax) { mLogEvents.remove(0); } } }); logVersionInfo(TeaServlet.class, "TeaServlet", log); log.info("Copyright (C) 1999-2012 TeaTrove http://teatrove.org"); logVersionInfo(TemplateLoader.class, "Tea", log); log.info("Copyright (C) 1997-2012 TeaTrove http://teatrove.org"); } }
private void createLog(final ServletContext context) { if (mLog == null) { try { mLog = (Log) context.getAttribute("org.teatrove.trove.log.Log"); } catch (ClassCastException e) { } // Log instance may not be provided, so make a Log that passes // messages to standard ServletContext log. if (mLog == null) { mLog = new Log(getServletName(), null); mLog.addLogListener( new LogListener() { public void logMessage(LogEvent e) { String message = e.getMessage(); if (message != null) { context.log(message); } } public void logException(LogEvent e) { String message = e.getMessage(); Throwable t = e.getException(); if (t == null) { context.log(message); } else { context.log(message, t); } } }); } } String fullStackTrace = mProperties.getString("log.fullStackTrace", "false"); if (!fullStackTrace.equals("true")) { mLog = new TeaLog(mLog); } }
@SuppressWarnings("unchecked") private void loadDefaults(PropertyMap properties, Set<String> files) throws Exception { // update substitutions if provided PropertyMap substitutions = properties.subMap("substitutions"); if (substitutions != null && substitutions.size() > 0) { PropertyMap subs = SubstitutionFactory.getSubstitutions(substitutions, mResourceFactory); if (subs != null) { mSubstitutions.putAll(subs); } properties.remove("substitutions"); } // Get file and perform substitution of env variables/system props String fileName = properties.getString("properties.file"); if (mDebugEnabled) { mServletContext.log("properties.file: " + fileName); } if (fileName != null) { fileName = SubstitutionFactory.substitute(fileName, mSubstitutions); } // parse file if not yet parsed if (fileName != null && !files.contains(fileName)) { // Prevent properties file cycle. files.add(fileName); // load properties PropertyMap props = mResourceFactory.getResourceAsProperties(fileName); if (props != null) { properties.putAll(props); } loadDefaults(properties, files); } else { PropertyMap factoryProps = properties.subMap("properties.factory"); if (factoryProps != null && factoryProps.size() > 0) { PropertyMap map = loadProperties(factoryProps); properties.putAll(map); } } }
protected boolean processStatus(HttpServletRequest request, HttpServletResponse response) throws IOException { String path = request.getPathInfo(); // check password String adminKey = mProperties.getString("admin.key"); String adminValue = mProperties.getString("admin.value"); if (AdminApplication.adminCheck( adminKey, adminValue, request, response)) { // check if status request if ("/system/status.json".equals(path)) { printStatus(response); return true; } // once we have initialized, no need to further process if (isRunning()) { return false; } // verify our path matches the expected path String pattern = mProperties.getString("startup.path"); if (pattern != null && path.matches(pattern)) { // verify the startup file that was provided String resource = mProperties.getString("startup.file"); if (resource != null) { InputStream input = TeaServlet.class.getResourceAsStream(resource); // copy the data to the response if valid if (input != null) { int read = 0; byte[] data = new byte[512]; input = new BufferedInputStream(input); ServletOutputStream output = response.getOutputStream(); while ((read = input.read(data)) >= 0) { output.write(data, 0, read); } input.close(); response.flushBuffer(); return true; } } } } // handle error code if not yet initialized if (!isInitialized()) { // request not processed so send uninitialized error code int errorCode = mProperties.getInt("startup.codes.initializing", 503); response.sendError(errorCode); return true; } // nothing to process return false; }