Beispiel #1
0
  private void createInfrastructure() {
    _classFab.addField("_next", _serviceInterface);
    _classFab.addField("_filter", _filterInterface);

    _classFab.addConstructor(
        new Class[] {_serviceInterface, _filterInterface}, null, "{ _next = $1; _filter = $2; }");

    _classFab.addInterface(_serviceInterface);
  }
Beispiel #2
0
  /**
   * Finds a matching method in filterMethods for the given service method. A matching method has
   * the same signature as the service interface method, but with an additional parameter matching
   * the service interface itself.
   *
   * <p>The matching method signature from the list of filterMethods is removed and code generation
   * strategies for making the two methods call each other are added.
   */
  private void addBridgeMethod(MethodSignature ms, List filterMethods) {
    Iterator i = filterMethods.iterator();

    while (i.hasNext()) {
      MethodSignature fms = (MethodSignature) i.next();

      int position = _filterMethodAnalyzer.findServiceInterfacePosition(ms, fms);

      if (position >= 0) {
        addBridgeMethod(position, ms, fms);
        i.remove();
        return;
      }
    }

    String message = PipelineMessages.unmatchedServiceMethod(ms, _filterInterface);

    _errorLog.error(message, null, null);

    BodyBuilder b = new BodyBuilder();

    b.add("throw new org.ops4j.gaderian.ApplicationRuntimeException(");
    b.addQuoted(message);
    b.addln(");");

    _classFab.addMethod(Modifier.PUBLIC, ms, b.toString());
  }
Beispiel #3
0
  /**
   * Adds a method to the class which bridges from the service method to the corresponding method in
   * the filter interface. The next service (either another Bridge, or the terminator at the end of
   * the pipeline) is passed to the filter).
   */
  private void addBridgeMethod(int position, MethodSignature ms, MethodSignature fms) {
    StringBuffer buffer = new StringBuffer(100);

    if (ms.getReturnType() != void.class) buffer.append("return ");

    buffer.append("_filter.");
    buffer.append(ms.getName());
    buffer.append("(");

    boolean comma = false;
    int filterParameterCount = fms.getParameterTypes().length;

    for (int i = 0; i < position; i++) {
      if (comma) buffer.append(", ");

      buffer.append("$");
      // Add one to the index to get the parameter symbol ($0 is the implicit
      // this parameter).
      buffer.append(i + 1);

      comma = true;
    }

    if (comma) buffer.append(", ");

    // _next is the variable in -this- Bridge that points to the -next- Bridge
    // or the terminator for the pipeline. The filter is expected to reinvoke the
    // method on the _next that's passed to it.

    buffer.append("_next");

    for (int i = position + 1; i < filterParameterCount; i++) {
      buffer.append(", $");
      buffer.append(i);
    }

    buffer.append(");");

    // This should work, unless the exception types turn out to not be compatble. We still
    // don't do a check on that, and not sure that Javassist does either!

    _classFab.addMethod(Modifier.PUBLIC, ms, buffer.toString());
  }
Beispiel #4
0
  private void createClass() {
    List serviceMethods = new ArrayList();
    List filterMethods = new ArrayList();

    createInfrastructure();

    MethodIterator mi = new MethodIterator(_serviceInterface);

    while (mi.hasNext()) {
      serviceMethods.add(mi.next());
    }

    boolean toStringMethodExists = mi.getToString();

    mi = new MethodIterator(_filterInterface);

    while (mi.hasNext()) {
      filterMethods.add(mi.next());
    }

    while (!serviceMethods.isEmpty()) {
      MethodSignature ms = (MethodSignature) serviceMethods.remove(0);

      addBridgeMethod(ms, filterMethods);
    }

    reportExtraFilterMethods(filterMethods);

    if (!toStringMethodExists)
      ClassFabUtils.addToStringMethod(
          _classFab, PipelineMessages.bridgeInstanceDescription(_serviceId, _serviceInterface));

    Class bridgeClass = _classFab.createClass();

    _constructor = bridgeClass.getConstructors()[0];
  }