Example #1
0
  /**
   * These are the expensive operations (initStandardObjects and compileReader/exec). We do them
   * once here, and define this provider as a singleton, so it's only done at provider creation or
   * whenever rules are refreshed.
   *
   * @param rulesCurator
   */
  private void compileRules(RulesCurator rulesCurator) {
    scriptLock.writeLock().lock();
    try {
      // XXX: we need a principal to access the rules,
      // but pushing and popping system principal could be a bad idea
      Principal systemPrincipal = new SystemPrincipal();
      ResteasyProviderFactory.pushContext(Principal.class, systemPrincipal);
      // Check to see if we need to recompile. we do this inside the write lock
      // just to avoid race conditions where we might double compile
      Date newUpdated = rulesCurator.getUpdated();
      if (newUpdated.equals(this.updated)) {
        return;
      }

      log.debug("Recompiling rules with timestamp: " + newUpdated);

      Context context = Context.enter();
      context.setOptimizationLevel(9);
      scope = context.initStandardObjects(null, true);
      try {
        script = context.compileString(rulesCurator.getRules().getRules(), "rules", 1, null);
        script.exec(context, scope);
        ((ScriptableObject) scope).sealObject();
        this.updated = newUpdated;
      } finally {
        Context.exit();
      }
    } finally {
      ResteasyProviderFactory.popContextData(Principal.class);
      scriptLock.writeLock().unlock();
    }
  }
Example #2
0
  public JsRunner get() {
    /*
     * Create a new thread/request local javascript scope for the JsRules,
     * based on the preinitialized global one (which contains our js rules).
     */
    // Avoid a write lock if we can
    if (!rulesCurator.getUpdated().equals(this.updated)) {
      compileRules(this.rulesCurator);
    }
    Scriptable rulesScope;
    scriptLock.readLock().lock();
    try {
      Context context = Context.enter();
      rulesScope = context.newObject(scope);
      rulesScope.setPrototype(scope);
      rulesScope.setParentScope(null);
      Context.exit();
    } finally {
      scriptLock.readLock().unlock();
    }

    return new JsRunner(rulesScope);
  }