Ejemplo n.º 1
0
  public Type navigateParameterized(String name, Type[] params) throws OclTypeException {
    Type ret = Basic.navigateAnyParameterized(name, params);
    if (ret != null) return ret;

    Method foundmethod = null;

    // this is very similar to tudresden.ocl.lib.OclAnyImpl.findMethod
    // if you find a bug here, its probably there as well.

    // suprisingly one has not to go after interfaces since methods
    // inherited from interfaces are automatically included into the
    // implementing class. This does not happen for methods inherited
    // from the superclass, so we have to ascend to all superclasses.

    // unfortunately the above is only true for classes, getSuperclass invoked
    // on an interface returns null, regardless of the interfaces extended by the
    // interface. Therefore, we need to check out getInterfaces() if iclass is
    // an interface
    HashSet hsVisited = new HashSet();
    LinkedList llToVisit = new LinkedList();
    if (c.isInterface()) {
      // as we're dealing with actual instances, it can be assumed that Object is
      // a superclass
      llToVisit.add(java.lang.Object.class);
    }

    classloop:
    for (Class iclass = c; iclass != null; ) // iclass=iclass.getSuperclass())
    {
      Method[] methods = iclass.getDeclaredMethods();
      methodloop:
      for (int i = 0; i < methods.length; i++) {
        if (!name.equals(methods[i].getName())) continue methodloop;
        Class[] methodparams = methods[i].getParameterTypes();
        if (params.length != methodparams.length) continue methodloop;

        System.err.print("Checking method " + name + " (");
        for (int j = 0; j < methodparams.length; j++) {
          if (j != 0) {
            System.err.print(", ");
          }

          System.err.print(methodparams[j]);
        }
        System.err.println(")");

        for (int j = 0; j < params.length; j++)
          if (!params[j].conformsTo(getTypeForClass(methodparams[j]))) {
            System.err.println("No conformance for paramter # " + j);
            continue methodloop;
          }
        if (foundmethod == null) foundmethod = methods[i];
        else throw new OclTypeException("ambigious method " + name + " of " + c + ") queried.");
        break classloop;
      }

      // determine classes to be visited
      if (iclass.isInterface()) {
        Class[] ca = iclass.getInterfaces();
        for (int i = 0; i < ca.length; i++) {
          if (!hsVisited.contains(ca[i])) {
            llToVisit.add(ca[i]);
          }
        }
      } else {
        if (!hsVisited.contains(iclass.getSuperclass())) {
          llToVisit.add(iclass.getSuperclass());
        }
      }

      // mark current class visited
      hsVisited.add(iclass);

      // go to next class
      if (!llToVisit.isEmpty()) {
        iclass = (Class) llToVisit.remove(0);
      } else {
        iclass = null;
      }
    }

    if (foundmethod == null) {
      StringBuffer sb = new StringBuffer();
      sb.append(c.toString() + " has no method " + name + " with parameters (");
      for (int i = 0; i < params.length; i++) {
        if (i != 0) sb.append(", ");
        sb.append(params[i] + "/" + params[i]);
      }
      sb.append(")");
      throw new OclTypeException(sb.toString());
    }

    return getTypeForClass(foundmethod.getReturnType());
  }