Search in sources :

Example 31 with Clazz

use of aQute.bnd.osgi.Clazz in project bnd by bndtools.

the class MetaTypeReader method parseAndMergeInheritedMetadata.

private void parseAndMergeInheritedMetadata(TypeRef ref, Clazz child) throws Exception {
    if (ref.isJava())
        return;
    Clazz ec = reporter.findClass(ref);
    if (ec == null) {
        reporter.error("Missing inherited class for Metatype annotations: %s from %s", ref, child.getClassName());
    } else {
        @SuppressWarnings("resource") MetaTypeReader mtr = new MetaTypeReader(ec, reporter);
        mtr.setDesignate(designatePid, factory);
        mtr.finish();
        for (Map.Entry<MethodDef, Meta.AD> entry : mtr.methods.entrySet()) addMethod(entry.getKey(), entry.getValue());
        handleInheritedClasses(ec);
    }
}
Also used : MethodDef(aQute.bnd.osgi.Clazz.MethodDef) Clazz(aQute.bnd.osgi.Clazz) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 32 with Clazz

use of aQute.bnd.osgi.Clazz in project bnd by bndtools.

the class MetaTypeReader method addMethod.

private void addMethod(MethodDef method, Meta.AD ad) throws Exception {
    if (method.isStatic())
        return;
    // Set all the defaults.
    String rtype = method.getGenericReturnType();
    String id = Configurable.mangleMethodName(method.getName());
    String name = Clazz.unCamel(id);
    int cardinality = 0;
    if (rtype.endsWith("[]")) {
        cardinality = Integer.MAX_VALUE;
        rtype = rtype.substring(0, rtype.length() - 2);
    }
    if (rtype.indexOf('<') > 0) {
        if (cardinality != 0)
            reporter.error("AD for %s.%s uses an array of collections in return type (%s), Metatype allows either Vector or array", clazz.getClassName().getFQN(), method.getName(), method.getType().getFQN());
        Matcher m = COLLECTION.matcher(rtype);
        if (m.matches()) {
            rtype = Clazz.objectDescriptorToFQN(m.group(3));
            cardinality = Integer.MIN_VALUE;
        }
    }
    Meta.Type type = getType(rtype);
    boolean required = ad == null || ad.required();
    String deflt = null;
    String max = null;
    String min = null;
    String[] optionLabels = null;
    String[] optionValues = null;
    String description = null;
    TypeRef typeRef = reporter.getTypeRefFromFQN(rtype);
    Clazz c = reporter.findClass(typeRef);
    if (c != null && c.isEnum()) {
        optionValues = parseOptionValues(c);
    }
    if (ad != null) {
        if (ad.id() != null)
            id = ad.id();
        if (ad.name() != null)
            name = ad.name();
        if (ad.cardinality() != 0)
            cardinality = ad.cardinality();
        if (ad.type() != null)
            type = ad.type();
        if (ad.description() != null)
            description = ad.description();
        if (ad.optionLabels() != null)
            optionLabels = ad.optionLabels();
        if (ad.optionValues() != null)
            optionValues = ad.optionValues();
        if (ad.min() != null)
            min = ad.min();
        if (ad.max() != null)
            max = ad.max();
        if (ad.deflt() != null)
            deflt = ad.deflt();
    }
    if (optionValues != null) {
        if (optionLabels == null || optionLabels.length == 0) {
            optionLabels = new String[optionValues.length];
            for (int i = 0; i < optionValues.length; i++) optionLabels[i] = Clazz.unCamel(optionValues[i]);
        }
        if (optionLabels.length != optionValues.length) {
            reporter.error("Option labels and option values not the same length for %s", id);
            optionLabels = optionValues;
        }
    }
    Tag adt = new Tag(this.ocd, "AD");
    adt.addAttribute("name", name);
    adt.addAttribute("id", id);
    adt.addAttribute("cardinality", cardinality);
    adt.addAttribute("required", required);
    adt.addAttribute("default", deflt);
    adt.addAttribute("type", type);
    adt.addAttribute("max", max);
    adt.addAttribute("min", min);
    adt.addAttribute("description", description);
    if (optionLabels != null && optionValues != null) {
        for (int i = 0; i < optionLabels.length; i++) {
            Tag option = new Tag(adt, "Option");
            option.addAttribute("label", optionLabels[i]);
            option.addAttribute("value", optionValues[i]);
        }
    }
}
Also used : Meta(aQute.bnd.annotation.metatype.Meta) Matcher(java.util.regex.Matcher) TypeRef(aQute.bnd.osgi.Descriptors.TypeRef) Clazz(aQute.bnd.osgi.Clazz) Tag(aQute.lib.tag.Tag)

Example 33 with Clazz

use of aQute.bnd.osgi.Clazz in project bnd by bndtools.

the class DSAnnotations method analyzeJar.

public boolean analyzeJar(Analyzer analyzer) throws Exception {
    Parameters header = OSGiHeader.parseHeader(analyzer.getProperty(Constants.DSANNOTATIONS, "*"));
    if (header.size() == 0)
        return false;
    minVersion = AnnotationReader.V1_3;
    Parameters optionsHeader = OSGiHeader.parseHeader(analyzer.mergeProperties(Constants.DSANNOTATIONS_OPTIONS));
    EnumSet<Options> options = EnumSet.noneOf(Options.class);
    for (Map.Entry<String, Attrs> entry : optionsHeader.entrySet()) {
        try {
            Options.parseOption(entry, options, this);
        } catch (IllegalArgumentException e) {
            analyzer.error("Unrecognized %s value %s with attributes %s, expected values are %s", Constants.DSANNOTATIONS_OPTIONS, entry.getKey(), entry.getValue(), EnumSet.allOf(Options.class));
        }
    }
    // obsolete but backwards compatible, use the options instead
    if (Processor.isTrue(analyzer.getProperty("-dsannotations-inherit")))
        options.add(Options.inherit);
    if (Processor.isTrue(analyzer.getProperty("-ds-felix-extensions")))
        options.add(Options.felixExtensions);
    Instructions instructions = new Instructions(header);
    Collection<Clazz> list = analyzer.getClassspace().values();
    String sc = analyzer.getProperty(Constants.SERVICE_COMPONENT);
    List<String> names = new ArrayList<String>();
    if (sc != null && sc.trim().length() > 0)
        names.add(sc);
    TreeSet<String> provides = new TreeSet<String>();
    TreeSet<String> requires = new TreeSet<String>();
    Version maxVersion = AnnotationReader.V1_0;
    XMLAttributeFinder finder = new XMLAttributeFinder(analyzer);
    boolean componentProcessed = false;
    for (Clazz c : list) {
        for (Instruction instruction : instructions.keySet()) {
            if (instruction.matches(c.getFQN())) {
                if (instruction.isNegated())
                    break;
                ComponentDef definition = AnnotationReader.getDefinition(c, analyzer, options, finder, minVersion);
                if (definition != null) {
                    componentProcessed = true;
                    definition.sortReferences();
                    definition.prepare(analyzer);
                    String name = "OSGI-INF/" + analyzer.validResourcePath(definition.name, "Invalid component name") + ".xml";
                    names.add(name);
                    analyzer.getJar().putResource(name, new TagResource(definition.getTag()));
                    if (definition.service != null && !options.contains(Options.nocapabilities)) {
                        String[] objectClass = new String[definition.service.length];
                        for (int i = 0; i < definition.service.length; i++) {
                            Descriptors.TypeRef tr = definition.service[i];
                            objectClass[i] = tr.getFQN();
                        }
                        Arrays.sort(objectClass);
                        addServiceCapability(objectClass, provides);
                    }
                    if (!options.contains(Options.norequirements)) {
                        MergedRequirement serviceReqMerge = new MergedRequirement("osgi.service");
                        for (ReferenceDef ref : definition.references.values()) {
                            addServiceRequirement(ref, serviceReqMerge);
                        }
                        requires.addAll(serviceReqMerge.toStringList());
                    }
                    maxVersion = ComponentDef.max(maxVersion, definition.version);
                }
            }
        }
    }
    if (componentProcessed && (options.contains(Options.extender) || (maxVersion.compareTo(AnnotationReader.V1_3) >= 0))) {
        maxVersion = ComponentDef.max(maxVersion, AnnotationReader.V1_3);
        addExtenderRequirement(requires, maxVersion);
    }
    sc = Processor.append(names.toArray(new String[0]));
    analyzer.setProperty(Constants.SERVICE_COMPONENT, sc);
    updateHeader(analyzer, Constants.REQUIRE_CAPABILITY, requires);
    updateHeader(analyzer, Constants.PROVIDE_CAPABILITY, provides);
    return false;
}
Also used : Attrs(aQute.bnd.header.Attrs) ArrayList(java.util.ArrayList) Instruction(aQute.bnd.osgi.Instruction) XMLAttributeFinder(aQute.bnd.xmlattribute.XMLAttributeFinder) Version(aQute.bnd.version.Version) TreeSet(java.util.TreeSet) Clazz(aQute.bnd.osgi.Clazz) Descriptors(aQute.bnd.osgi.Descriptors) Parameters(aQute.bnd.header.Parameters) Instructions(aQute.bnd.osgi.Instructions) Map(java.util.Map)

Example 34 with Clazz

use of aQute.bnd.osgi.Clazz in project bnd by bndtools.

the class HeaderReader method createComponentTag.

public Tag createComponentTag(String name, String impl, Map<String, String> info) throws Exception {
    final ComponentDef cd = new ComponentDef(null, AnnotationReader.V1_0);
    cd.name = name;
    if (info.get(COMPONENT_ENABLED) != null)
        cd.enabled = Boolean.valueOf(info.get(COMPONENT_ENABLED));
    cd.factory = info.get(COMPONENT_FACTORY);
    if (info.get(COMPONENT_IMMEDIATE) != null)
        cd.immediate = Boolean.valueOf(info.get(COMPONENT_IMMEDIATE));
    if (info.get(COMPONENT_CONFIGURATION_POLICY) != null)
        cd.configurationPolicy = ConfigurationPolicy.valueOf(info.get(COMPONENT_CONFIGURATION_POLICY).toUpperCase());
    cd.activate = checkIdentifier(COMPONENT_ACTIVATE, info.get(COMPONENT_ACTIVATE));
    cd.deactivate = checkIdentifier(COMPONENT_DEACTIVATE, info.get(COMPONENT_DEACTIVATE));
    cd.modified = checkIdentifier(COMPONENT_MODIFIED, info.get(COMPONENT_MODIFIED));
    cd.implementation = analyzer.getTypeRefFromFQN(impl == null ? name : impl);
    String provides = info.get(COMPONENT_PROVIDE);
    if (info.get(COMPONENT_SERVICEFACTORY) != null) {
        if (provides != null)
            cd.scope = Boolean.valueOf(info.get(COMPONENT_SERVICEFACTORY)) ? ServiceScope.BUNDLE : ServiceScope.SINGLETON;
        else
            warning("The servicefactory:=true directive is set but no service is provided, ignoring it");
    }
    if (cd.scope == ServiceScope.BUNDLE && cd.immediate != null && cd.immediate) {
        // TODO can become error() if it is up to me
        warning("For a Service Component, the immediate option and the servicefactory option are mutually exclusive for %s(%s)", name, impl);
    }
    // analyze the class for suitable methods.
    final Map<String, MethodDef> lifecycleMethods = new HashMap<String, MethodDef>();
    final Map<String, MethodDef> bindmethods = new HashMap<String, MethodDef>();
    TypeRef typeRef = analyzer.getTypeRefFromFQN(impl);
    Clazz clazz = analyzer.findClass(typeRef);
    boolean privateAllowed = true;
    boolean defaultAllowed = true;
    String topPackage = typeRef.getPackageRef().getFQN();
    while (clazz != null) {
        final boolean pa = privateAllowed;
        final boolean da = defaultAllowed;
        final Map<String, MethodDef> classLifecyclemethods = new HashMap<String, MethodDef>();
        final Map<String, MethodDef> classBindmethods = new HashMap<String, MethodDef>();
        clazz.parseClassFileWithCollector(new ClassDataCollector() {

            @Override
            public void method(MethodDef md) {
                Set<String> allowedParams = allowed;
                String lifecycleName = null;
                boolean isLifecycle = (cd.activate == null ? "activate" : cd.activate).equals(md.getName()) || md.getName().equals(cd.modified);
                if (!isLifecycle && (cd.deactivate == null ? "deactivate" : cd.deactivate).equals(md.getName())) {
                    isLifecycle = true;
                    allowedParams = allowedDeactivate;
                }
                if (isLifecycle && !lifecycleMethods.containsKey(md.getName()) && (md.isPublic() || md.isProtected() || (md.isPrivate() && pa) || (!md.isPrivate()) && da) && isBetter(md, classLifecyclemethods.get(md.getName()), allowedParams)) {
                    classLifecyclemethods.put(md.getName(), md);
                }
                if (!bindmethods.containsKey(md.getName()) && (md.isPublic() || md.isProtected() || (md.isPrivate() && pa) || (!md.isPrivate()) && da) && isBetterBind(md, classBindmethods.get(md.getName()))) {
                    classBindmethods.put(md.getName(), md);
                }
            }

            private boolean isBetter(MethodDef test, MethodDef existing, Set<String> allowedParams) {
                int testRating = rateLifecycle(test, allowedParams);
                if (existing == null)
                    // ignore invalid methods
                    return testRating < 6;
                if (testRating < rateLifecycle(existing, allowedParams))
                    return true;
                return false;
            }

            private boolean isBetterBind(MethodDef test, MethodDef existing) {
                int testRating = rateBind(test);
                if (existing == null)
                    // ignore invalid methods
                    return testRating < 6;
                if (testRating < rateBind(existing))
                    return true;
                return false;
            }
        });
        lifecycleMethods.putAll(classLifecyclemethods);
        bindmethods.putAll(classBindmethods);
        typeRef = clazz.getSuper();
        if (typeRef == null)
            break;
        clazz = analyzer.findClass(typeRef);
        privateAllowed = false;
        defaultAllowed = defaultAllowed && topPackage.equals(typeRef.getPackageRef().getFQN());
    }
    if (cd.activate != null && !lifecycleMethods.containsKey(cd.activate)) {
        error("in component %s, activate method %s specified but not found", cd.implementation.getFQN(), cd.activate);
        cd.activate = null;
    }
    if (cd.deactivate != null && !lifecycleMethods.containsKey(cd.deactivate)) {
        error("in component %s, deactivate method %s specified but not found", cd.implementation.getFQN(), cd.deactivate);
        cd.activate = null;
    }
    if (cd.modified != null && !lifecycleMethods.containsKey(cd.modified)) {
        error("in component %s, modified method %s specified but not found", cd.implementation.getFQN(), cd.modified);
        cd.activate = null;
    }
    provide(cd, provides, impl);
    properties(cd, info, name);
    reference(info, impl, cd, bindmethods);
    // compute namespace after references, an updated method means ds 1.2.
    getNamespace(info, cd, lifecycleMethods);
    cd.prepare(analyzer);
    return cd.getTag();
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) MethodDef(aQute.bnd.osgi.Clazz.MethodDef) TypeRef(aQute.bnd.osgi.Descriptors.TypeRef) Clazz(aQute.bnd.osgi.Clazz) ClassDataCollector(aQute.bnd.osgi.ClassDataCollector)

Example 35 with Clazz

use of aQute.bnd.osgi.Clazz in project bnd by bndtools.

the class XMLAttributeFinder method getXMLAttribute.

public synchronized XMLAttribute getXMLAttribute(Annotation a) throws Exception {
    TypeRef name = a.getName();
    if (annoCache.containsKey(name))
        return annoCache.get(name);
    Clazz clazz = analyzer.findClass(name);
    if (clazz != null) {
        xmlAttr = null;
        clazz.parseClassFileWithCollector(this);
        annoCache.put(name, xmlAttr);
        return xmlAttr;
    }
    return null;
}
Also used : TypeRef(aQute.bnd.osgi.Descriptors.TypeRef) Clazz(aQute.bnd.osgi.Clazz)

Aggregations

Clazz (aQute.bnd.osgi.Clazz)56 Analyzer (aQute.bnd.osgi.Analyzer)14 ClassDataCollector (aQute.bnd.osgi.ClassDataCollector)14 TypeRef (aQute.bnd.osgi.Descriptors.TypeRef)12 PackageRef (aQute.bnd.osgi.Descriptors.PackageRef)8 InputStream (java.io.InputStream)8 FileResource (aQute.bnd.osgi.FileResource)7 File (java.io.File)7 HashMap (java.util.HashMap)7 FileInputStream (java.io.FileInputStream)6 Resource (aQute.bnd.osgi.Resource)5 MethodDef (aQute.bnd.osgi.Clazz.MethodDef)4 Descriptors (aQute.bnd.osgi.Descriptors)4 Instruction (aQute.bnd.osgi.Instruction)4 Jar (aQute.bnd.osgi.Jar)4 IOException (java.io.IOException)4 ArrayList (java.util.ArrayList)4 Map (java.util.Map)4 TreeSet (java.util.TreeSet)4 Parameters (aQute.bnd.header.Parameters)3