/**
   * 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());
    }
  }
Example #2
0
 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);
     }
   }
 }
Example #3
0
  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;
  }
Example #4
0
  /**
   * 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();
  }
Example #5
0
  /**
   * 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();
    }
  }
Example #6
0
  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", ",");
  }
Example #7
0
  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;
  }
Example #8
0
  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");
    }
  }
Example #9
0
  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);
    }
  }
Example #10
0
  @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);
      }
    }
  }
Example #11
0
  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;
  }