Beispiel #1
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;
   }
 }
Beispiel #2
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());
         }
       }
     }
   }
 }
Beispiel #3
0
 private DesignateDef getDef() throws Exception {
   clazz.parseClassFileWithCollector(this);
   if (pid != null && designate != null) {
     if (pids != null && pids.length > 1) {
       analyzer.error(
           "DS Component %s specifies multiple pids %s, and a Designate which requires exactly one pid",
           clazz.getClassName().getFQN(), Arrays.asList(pids));
       return null;
     }
     TypeRef ocdClass = designate.get("ocd");
     // ocdClass = ocdClass.substring(1, ocdClass.length() - 1);
     OCDDef ocd = classToOCDMap.get(ocdClass);
     if (ocd == null) {
       analyzer.error(
           "DS Component %s specifies ocd class %s which cannot be found; known classes %s",
           clazz.getClassName().getFQN(), ocdClass, classToOCDMap.keySet());
       return null;
     }
     String id = ocd.id;
     boolean factoryPid = Boolean.TRUE == designate.get("factory");
     if (def == null) def = new DesignateDef(finder);
     def.ocdRef = id;
     def.pid = pid;
     def.factory = factoryPid;
     ocd.designates.add(def);
     return def;
   }
   return null;
 }
Beispiel #4
0
  private static Map<MethodDef, List<MethodDef>> buildCatalog(Collection<Clazz> sources)
      throws Exception {
    final Map<MethodDef, List<MethodDef>> catalog =
        new TreeMap<MethodDef, List<MethodDef>>(
            new Comparator<MethodDef>() {
              public int compare(MethodDef a, MethodDef b) {
                return a.getName().compareTo(b.getName());
              }
            });
    for (final Clazz clazz : sources) {
      clazz.parseClassFileWithCollector(
          new ClassDataCollector() {

            @Override
            public boolean classStart(int access, TypeRef name) {
              return clazz.isPublic();
            }

            @Override
            public void method(MethodDef source) {
              if (source.isPublic() || source.isProtected())
                catalog.put(source, new ArrayList<MethodDef>());
            }
          });
    }
    return catalog;
  }
Beispiel #5
0
 private void doOCD(ObjectClassDefinition o, Annotation annotation) {
   if (topLevel) {
     if (clazz.isInterface()) {
       if (ocd == null) ocd = new OCDDef(finder);
       ocd.id = o.id() == null ? name.getFQN() : o.id();
       ocd.name = o.name() == null ? space(ocd.id) : o.name();
       ocd.description = o.description() == null ? "" : o.description();
       ocd.localization =
           o.localization() == null ? "OSGI-INF/l10n/" + name.getFQN() : o.localization();
       if (annotation.get("pid") != null) {
         String[] pids = o.pid();
         designates(pids, false);
       }
       if (annotation.get("factoryPid") != null) {
         String[] pids = o.factoryPid();
         designates(pids, true);
       }
       if (annotation.get("icon") != null) {
         Icon[] icons = o.icon();
         for (Icon icon : icons) {
           ocd.icons.add(new IconDef(icon.resource(), icon.size()));
         }
       }
     } else {
       analyzer.error(
           "ObjectClassDefinition applied to non-interface, non-annotation class %s", clazz);
     }
   }
 }
Beispiel #6
0
  private OCDDef getDef() throws Exception {
    clazz.parseClassFileWithCollector(this);
    if (ocd != null) {
      topLevel = false;
      parseExtends(clazz);

      doMethods();
    }
    return ocd;
  }
Beispiel #7
0
 private void doXmlAttribute(Annotation annotation, XMLAttribute xmlAttr) {
   if (current == null) {
     if (clazz.isInterface()) {
       if (ocd == null) ocd = new OCDDef(finder);
       ocd.addExtensionAttribute(xmlAttr, annotation);
     }
   } else {
     current.addExtensionAttribute(xmlAttr, annotation);
   }
 }
Beispiel #8
0
 void doComponent(java.lang.annotation.Annotation a) {
   Component component = (Component) a;
   pids = component.configurationPid();
   if (pids != null) {
     pid = pids[0];
   }
   if (pids == null || "$".equals(pid)) {
     pid = component.name();
     if (pid == null) pid = clazz.getClassName().getFQN();
   }
 }
Beispiel #9
0
  private void parseOptionValues(Clazz c, final List<OptionDef> options) throws Exception {

    c.parseClassFileWithCollector(
        new ClassDataCollector() {
          @Override
          public void field(Clazz.FieldDef def) {
            if (def.isEnum()) {
              OptionDef o = new OptionDef(def.getName(), def.getName());
              options.add(o);
            }
          }
        });
  }
Beispiel #10
0
  private static void crossRef(
      Collection<Clazz> source, final Map<MethodDef, List<MethodDef>> catalog) throws Exception {
    for (final Clazz clazz : source) {
      clazz.parseClassFileWithCollector(
          new ClassDataCollector() {
            //				MethodDef	source;

            @Override
            public void implementsInterfaces(TypeRef names[]) {
              MethodDef def = clazz.getMethodDef(0, "<implements>", "()V");
              // TODO
              for (TypeRef interfaceName : names) {
                for (Map.Entry<MethodDef, List<MethodDef>> entry : catalog.entrySet()) {
                  String catalogClass = entry.getKey().getContainingClass().getFQN();
                  List<MethodDef> references = entry.getValue();

                  if (catalogClass.equals(interfaceName.getFQN())) {
                    references.add(def);
                  }
                }
              }
            }

            // Method definitions
            @Override
            public void method(MethodDef source) {
              //					this.source = source;
            }

            // TODO need to use different reference method
            //				public void reference(MethodDef reference) {
            //					List<MethodDef> references = catalog.get(reference);
            //					if (references != null) {
            //						references.add(source);
            //					}
            //				}
          });
    }
  }
Beispiel #11
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;
 }
Beispiel #12
0
 static String space(String name) {
   return Clazz.unCamel(name);
 }
Beispiel #13
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)};
          }
        }
      }
    }
  }