Example #1
0
 private void parseExtends(Clazz clazz) {
   TypeRef[] inherits = clazz.getInterfaces();
   if (inherits != null) {
     if (analyzed == null) {
       analyzed = new HashSet<TypeRef>();
     }
     for (TypeRef typeRef : inherits) {
       if (!typeRef.isJava() && analyzed.add(typeRef)) {
         try {
           Clazz inherit = analyzer.findClass(typeRef);
           if (inherit != null) {
             inherit.parseClassFileWithCollector(this);
             parseExtends(inherit);
           } else {
             analyzer.error(
                 "Could not obtain super class %s of class %s",
                 typeRef.getFQN(), clazz.getClassName().getFQN());
           }
         } catch (Exception e) {
           analyzer.error(
               "Could not obtain super class %s of class %s; exception %s",
               typeRef.getFQN(), clazz.getClassName().getFQN(), e.getMessage());
         }
       }
     }
   }
 }
Example #2
0
 private boolean acceptableType(String rtype) {
   TypeRef ref = analyzer.getTypeRefFromFQN(rtype);
   try {
     Clazz returnType = analyzer.findClass(ref);
     if (returnType.isEnum()) {
       return true;
     }
     // TODO check this is true for interfaces and annotations
     if (!returnType.isAbstract()
         || (returnType.isInterface() && options.contains(Options.nested))) {
       return true;
     }
     if (!returnType.isInterface()) {
       analyzer.error("Abstract classes not allowed as interface method return values: %s", rtype);
     } else {
       analyzer.error("Nested metatype only allowed with option: nested type %s", rtype);
     }
     return false;
   } catch (Exception e) {
     analyzer.error(
         "could not examine class for return type %s, exception message: %s",
         rtype, e.getMessage());
     return false;
   }
 }
Example #3
0
 private boolean identifiableCollection(String type, boolean intface, boolean topLevel) {
   try {
     Clazz clazz = analyzer.findClass(analyzer.getTypeRefFromFQN(type));
     if (clazz != null
         && (!topLevel || !clazz.isAbstract())
         && ((intface && clazz.isInterface()) ^ clazz.hasPublicNoArgsConstructor())) {
       TypeRef[] intfs = clazz.getInterfaces();
       if (intfs != null) {
         for (TypeRef intf : intfs) {
           if (COLLECTION.matcher(intf.getFQN()).matches()
               || identifiableCollection(intf.getFQN(), true, false)) {
             return true;
           }
         }
       }
       TypeRef ext = clazz.getSuper();
       return ext != null && identifiableCollection(ext.getFQN(), false, false);
     }
   } catch (Exception e) {
     return false;
   }
   return false;
 }
Example #4
0
  private void doMethods() throws Exception {
    for (Map.Entry<MethodDef, ADDef> entry : methods.entrySet()) {
      MethodDef defined = entry.getKey();
      if (defined.isConstructor()) {
        analyzer.error(
            "Constructor %s for %s.%s found; only interfaces and annotations allowed for OCDs",
            defined.getName(), clazz.getClassName().getFQN(), defined.getName());
      }
      if (defined.getPrototype().length > 0) {
        analyzer.error(
            "Element %s for %s.%s has parameters; only no-parameter elements in an OCD interface allowed",
            defined.getName(), clazz.getClassName().getFQN(), defined.getName());
        continue;
      }
      ADDef ad = entry.getValue();
      ocd.attributes.add(ad);
      ad.id = fixup(defined.getName());
      ad.name = space(defined.getName());
      String rtype = defined.getGenericReturnType();
      if (rtype.endsWith("[]")) {
        ad.cardinality = Integer.MAX_VALUE;
        rtype = rtype.substring(0, rtype.length() - 2);
      }
      Matcher m = GENERIC.matcher(rtype);
      if (m.matches()) {
        boolean knownCollection = m.group(2) != null;
        boolean collection = knownCollection || identifiableCollection(m.group(3), false, true);
        if (collection) {
          if (ad.cardinality != 0)
            analyzer.error(
                "AD for %s.%s uses an array of collections in return type (%s), Metatype allows either Vector or array",
                clazz.getClassName().getFQN(), defined.getName(), defined.getType().getFQN());
          rtype = Clazz.objectDescriptorToFQN(m.group(4));
          ad.cardinality = Integer.MIN_VALUE;
        }
      }
      if (rtype.indexOf('<') > 0) {
        rtype = rtype.substring(0, rtype.indexOf('<'));
      }
      ad.type = getType(rtype);

      ad.required = true;
      TypeRef typeRef = analyzer.getTypeRefFromFQN(rtype);
      try {
        Clazz c = analyzer.findClass(typeRef);
        if (c != null && c.isEnum()) {
          parseOptionValues(c, ad.options);
        }
      } catch (Exception e) {
        analyzer.error(
            "AD for %s.%s Can not parse option values from type (%s), %s",
            clazz.getClassName().getFQN(),
            defined.getName(),
            defined.getType().getFQN(),
            e.getMessage());
      }
      if (ad.ad != null) {
        doAD(ad);
      }
      if (ad.defaults == null && clazz.isAnnotation() && defined.getConstant() != null) {
        // defaults from annotation default
        Object value = defined.getConstant();
        boolean isClass = false;
        TypeRef type = defined.getType().getClassRef();
        if (!type.isPrimitive()) {
          if (Class.class.getName().equals(type.getFQN())) {
            isClass = true;
          } else {
            try {
              Clazz r = analyzer.findClass(type);
              if (r.isAnnotation()) {
                analyzer.warning(
                    "Nested annotation type found in field % s, %s",
                    defined.getName(), type.getFQN());
                return;
              }
            } catch (Exception e) {
              analyzer.error(
                  "Exception looking at annotation type default for element with descriptor %s,  type %s",
                  e, defined, type);
            }
          }
        }
        if (value != null) {
          if (value.getClass().isArray()) {
            // add element individually
            ad.defaults = new String[Array.getLength(value)];
            for (int i = 0; i < Array.getLength(value); i++) {
              Object element = Array.get(value, i);
              ad.defaults[i] = valueToProperty(element, isClass);
            }
          } else {
            ad.defaults = new String[] {valueToProperty(value, isClass)};
          }
        }
      }
    }
  }