Exemplo n.º 1
0
  public Type navigateQualified(String name, Type[] qualifiers) throws OclTypeException {
    Type theQualifier = null;

    if (qualifiers != null) {
      if (qualifiers.length == 1) theQualifier = qualifiers[0];
      else throw new OclTypeException("ReflectionFacade can handle one qualifier only");
    }
    // System.out.println("ClassAny.navigateQualified:"+this+" "+name);
    Type ret = Basic.navigateAnyQualified(name, this, qualifiers);
    if (ret != null) return ret;
    String[] javaNames = rf.nameAdapter.getNames(name);
    Field f = null;
    for (int i = 0; i < javaNames.length && f == null; i++) {
      Class nextClass = c;
      while (nextClass != null && f == null) {
        try {
          f = nextClass.getDeclaredField(javaNames[i]);
        } catch (NoSuchFieldException nsf) {
          // try next class
        }
        nextClass = nextClass.getSuperclass();
      }
    }
    if (f == null) {
      throw new OclTypeException(c.getName() + " has no field " + name);
    }
    Class type = f.getType();
    Type modeltype = getTypeForClass(type);

    if (modeltype instanceof Collection) {
      Class elementtype = rf.getElementType(f);

      if (rf.reflAdapter.isMap(type)) {
        if (theQualifier == null) {
          if (elementtype != null)
            return new Collection(
                ((Collection) modeltype).getCollectionKind(), getTypeForClass(elementtype));
          else return modeltype;
        } else {
          Class keytype_class = rf.getKeyType(f);
          Type keytype = null;
          if (keytype_class != null) keytype = getTypeForClass(keytype_class);

          if (keytype != null) {
            if (!theQualifier.equals(keytype))
              throw new OclTypeException(
                  "feature "
                      + name
                      + " in classifier "
                      + c
                      + ": expected qualifier type "
                      + keytype
                      + " found "
                      + theQualifier
                      + ".");
            if (elementtype != null) return getTypeForClass(elementtype);
            else
              throw new OclTypeException(
                  "feature "
                      + name
                      + "["
                      + keytype
                      + "] in classifier "
                      + c
                      + " has no @element-type tag.");
          } else
            throw new OclTypeException(
                "feature "
                    + name
                    + " in classifier "
                    + c
                    + ": qualified with type "
                    + theQualifier
                    + ", but feature has no @keytype tag.");
        }
      } else {
        if (theQualifier != null)
          throw new OclTypeException(
              "feature " + name + " in classifier " + c + " cannot be qualified.");

        if (elementtype != null)
          return new Collection(
              ((Collection) modeltype).getCollectionKind(), getTypeForClass(elementtype));
        else return modeltype;
      }
    } else {
      if (theQualifier != null)
        throw new OclTypeException(
            "feature " + name + " in classifier " + c + " cannot be qualified.");
      return modeltype;
    }
  }
Exemplo n.º 2
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());
  }