All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.activiti.engine.impl.juel.Builder Maven / Gradle / Ivy

There is a newer version: 7.1.0.M6
Show newest version
/*
 * Based on JUEL 2.2.1 code, 2006-2009 Odysseus Software GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.activiti.engine.impl.juel;

import java.io.PrintWriter;
import java.util.EnumSet;

import org.activiti.engine.impl.javax.el.ELContext;
import org.activiti.engine.impl.javax.el.ELException;
import org.activiti.engine.impl.javax.el.ELResolver;
import org.activiti.engine.impl.javax.el.FunctionMapper;
import org.activiti.engine.impl.javax.el.VariableMapper;
import org.activiti.engine.impl.juel.Parser.ParseException;
import org.activiti.engine.impl.juel.Scanner.ScanException;

/**
 * Tree builder.
 * 
 * @author Christoph Beck
 */
public class Builder implements TreeBuilder {
  private static final long serialVersionUID = 1L;

  /**
   * Feature enumeration type.
   */
  public static enum Feature {
    /**
     * Method invocations as in ${foo.bar(1)} as specified in JSR 245, maintenance release 2. The method to be invoked is resolved at evaluation time by calling
     * {@link ELResolver#invoke(javax.el.ELContext, Object, Object, Class[], Object[])} .
     */
    METHOD_INVOCATIONS,
    /**
     * For some reason we don't understand, the specification does not allow to resolve null property values. E.g. ${map[key]} will always return null if
     * key evaluates to null. Enabling this feature will allow JUEL to pass null to the property resolvers just like any other property value.
     */
    NULL_PROPERTIES,
    /**
     * Allow for use of Java 5 varargs in function calls.
     */
    VARARGS
  }

  protected final EnumSet features;

  public Builder() {
    this.features = EnumSet.noneOf(Feature.class);
  }

  public Builder(Feature... features) {
    if (features == null || features.length == 0) {
      this.features = EnumSet.noneOf(Feature.class);
    } else if (features.length == 1) {
      this.features = EnumSet.of(features[0]);
    } else {
      Feature[] rest = new Feature[features.length - 1];
      for (int i = 1; i < features.length; i++) {
        rest[i - 1] = features[i];
      }
      this.features = EnumSet.of(features[0], rest);
    }
  }

  /**
   * @return true iff the specified feature is supported.
   */
  public boolean isEnabled(Feature feature) {
    return features.contains(feature);
  }

  /**
   * Parse expression.
   */
  public Tree build(String expression) throws TreeBuilderException {
    try {
      return createParser(expression).tree();
    } catch (ScanException e) {
      throw new TreeBuilderException(expression, e.position, e.encountered, e.expected, e.getMessage());
    } catch (ParseException e) {
      throw new TreeBuilderException(expression, e.position, e.encountered, e.expected, e.getMessage());
    }
  }

  protected Parser createParser(String expression) {
    return new Parser(this, expression);
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == null || obj.getClass() != getClass()) {
      return false;
    }
    return features.equals(((Builder) obj).features);
  }

  @Override
  public int hashCode() {
    return getClass().hashCode();
  }

  /**
   * Dump out abstract syntax tree for a given expression
   * 
   * @param args
   *          array with one element, containing the expression string
   */
  public static void main(String[] args) {
    if (args.length != 1) {
      System.err.println("usage: java " + Builder.class.getName() + " ");
      System.exit(1);
    }
    PrintWriter out = new PrintWriter(System.out);
    Tree tree = null;
    try {
      tree = new Builder(Feature.METHOD_INVOCATIONS).build(args[0]);
    } catch (TreeBuilderException e) {
      System.out.println(e.getMessage());
      System.exit(0);
    }
    NodePrinter.dump(out, tree.getRoot());
    if (!tree.getFunctionNodes().iterator().hasNext() && !tree.getIdentifierNodes().iterator().hasNext()) {
      ELContext context = new ELContext() {
        @Override
        public VariableMapper getVariableMapper() {
          return null;
        }

        @Override
        public FunctionMapper getFunctionMapper() {
          return null;
        }

        @Override
        public ELResolver getELResolver() {
          return null;
        }
      };
      out.print(">> ");
      try {
        out.println(tree.getRoot().getValue(new Bindings(null, null), context, null));
      } catch (ELException e) {
        out.println(e.getMessage());
      }
    }
    out.flush();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy