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)}; } } } } }