Search in sources :

Example 31 with TypeRef

use of aQute.bnd.osgi.Descriptors.TypeRef in project bnd by bndtools.

the class Builder method addSources.

/**
	 * @throws IOException
	 */
private void addSources(Jar dot) throws Exception {
    if (!hasSources())
        return;
    Set<PackageRef> packages = Create.set();
    for (TypeRef typeRef : getClassspace().keySet()) {
        PackageRef packageRef = typeRef.getPackageRef();
        String sourcePath = typeRef.getSourcePath();
        String packagePath = packageRef.getPath();
        boolean found = false;
        String[] fixed = { "packageinfo", "package.html", "module-info.java", "package-info.java" };
        for (File root : getSourcePath()) {
            File f = getFile(root, sourcePath);
            if (f.exists()) {
                found = true;
                if (!packages.contains(packageRef)) {
                    packages.add(packageRef);
                    for (int j = 0; j < fixed.length; j++) {
                        for (File sp : getSourcePath()) {
                            File bdir = getFile(sp, packagePath);
                            File ff = getFile(bdir, fixed[j]);
                            if (ff.isFile()) {
                                String name = "OSGI-OPT/src/" + packagePath + "/" + fixed[j];
                                dot.putResource(name, new FileResource(ff));
                                break;
                            }
                        }
                    }
                }
                if (packageRef.isDefaultPackage())
                    logger.debug("Package reference is default package");
                dot.putResource("OSGI-OPT/src/" + sourcePath, new FileResource(f));
            }
        }
        if (getSourcePath().isEmpty())
            warning("Including sources but " + SOURCEPATH + " does not contain any source directories ");
    // TODO copy from the jars where they came from
    }
}
Also used : TypeRef(aQute.bnd.osgi.Descriptors.TypeRef) PackageRef(aQute.bnd.osgi.Descriptors.PackageRef) File(java.io.File)

Example 32 with TypeRef

use of aQute.bnd.osgi.Descriptors.TypeRef in project bnd by bndtools.

the class Clazz method doExceptions.

void doExceptions(DataInput in, int access_flags) throws IOException {
    int exception_count = in.readUnsignedShort();
    for (int i = 0; i < exception_count; i++) {
        int index = in.readUnsignedShort();
        ClassConstant cc = (ClassConstant) pool[index];
        TypeRef clazz = analyzer.getTypeRef(cc.getName());
        referTo(clazz, access_flags);
    }
}
Also used : TypeRef(aQute.bnd.osgi.Descriptors.TypeRef)

Example 33 with TypeRef

use of aQute.bnd.osgi.Descriptors.TypeRef in project bnd by bndtools.

the class HeaderReader method reference.

/**
	 * @param info
	 * @param impl TODO
	 * @param descriptors TODO
	 * @param pw
	 * @throws Exception
	 */
void reference(Map<String, String> info, String impl, ComponentDef cd, Map<String, MethodDef> descriptors) throws Exception {
    Collection<String> dynamic = new ArrayList<String>(split(info.get(COMPONENT_DYNAMIC)));
    Collection<String> optional = new ArrayList<String>(split(info.get(COMPONENT_OPTIONAL)));
    Collection<String> multiple = new ArrayList<String>(split(info.get(COMPONENT_MULTIPLE)));
    Collection<String> greedy = new ArrayList<String>(split(info.get(COMPONENT_GREEDY)));
    for (Map.Entry<String, String> entry : info.entrySet()) {
        // Skip directives
        String referenceName = entry.getKey();
        if (referenceName.endsWith(":")) {
            if (!SET_COMPONENT_DIRECTIVES.contains(referenceName))
                error("Unrecognized directive in " + Constants.SERVICE_COMPONENT + " header: %s", referenceName);
            continue;
        }
        // Parse the bind/unbind methods from the name
        // if set. They are separated by '/'
        String bind = null;
        String unbind = null;
        String updated = null;
        boolean bindCalculated = true;
        boolean unbindCalculated = true;
        boolean updatedCalculated = true;
        if (referenceName.indexOf('/') >= 0) {
            String[] parts = referenceName.split("/");
            referenceName = parts[0];
            if (parts[1].length() > 0) {
                bind = parts[1];
                bindCalculated = false;
            } else {
                bind = calculateBind(referenceName);
            }
            bind = parts[1].length() == 0 ? calculateBind(referenceName) : parts[1];
            if (parts.length > 2 && parts[2].length() > 0) {
                unbind = parts[2];
                unbindCalculated = false;
            } else {
                if (bind.startsWith("add"))
                    unbind = bind.replaceAll("add(.+)", "remove$1");
                else
                    unbind = "un" + bind;
            }
            if (parts.length > 3) {
                updated = parts[3];
                updatedCalculated = false;
            }
        } else if (Character.isLowerCase(referenceName.charAt(0))) {
            bind = calculateBind(referenceName);
            unbind = "un" + bind;
            updated = "updated" + Character.toUpperCase(referenceName.charAt(0)) + referenceName.substring(1);
        }
        String interfaceName = entry.getValue();
        if (interfaceName == null || interfaceName.length() == 0) {
            error("Invalid Interface Name for references in Service Component: %s=%s", referenceName, interfaceName);
            continue;
        }
        // So why not check the methods
        if (descriptors.size() > 0) {
            // Verify that the bind method exists
            if (!descriptors.containsKey(bind))
                if (bindCalculated)
                    bind = null;
                else
                    error("In component %s, the bind method %s for %s not defined", cd.effectiveName(), bind, referenceName);
            // Check if the unbind method exists
            if (!descriptors.containsKey(unbind)) {
                if (unbindCalculated)
                    // remove it
                    unbind = null;
                else
                    error("In component %s, the unbind method %s for %s not defined", cd.effectiveName(), unbind, referenceName);
            }
            if (!descriptors.containsKey(updated)) {
                if (updatedCalculated)
                    // remove it
                    updated = null;
                else
                    error("In component %s, the updated method %s for %s is not defined", cd.effectiveName(), updated, referenceName);
            }
        }
        // Check the cardinality by looking at the last
        // character of the value
        char c = interfaceName.charAt(interfaceName.length() - 1);
        if ("?+*~".indexOf(c) >= 0) {
            if (c == '?' || c == '*' || c == '~')
                optional.add(referenceName);
            if (c == '+' || c == '*')
                multiple.add(referenceName);
            if (c == '+' || c == '*' || c == '?')
                dynamic.add(referenceName);
            interfaceName = interfaceName.substring(0, interfaceName.length() - 1);
        }
        // Parse the target from the interface name
        // The target is a filter.
        String target = null;
        Matcher m = REFERENCE.matcher(interfaceName);
        if (m.matches()) {
            interfaceName = m.group(1);
            target = m.group(2);
        }
        TypeRef ref = analyzer.getTypeRefFromFQN(interfaceName);
        analyzer.referTo(ref);
        ReferenceDef rd = new ReferenceDef(null);
        rd.name = referenceName;
        rd.service = interfaceName;
        if (optional.contains(referenceName)) {
            if (multiple.contains(referenceName)) {
                rd.cardinality = ReferenceCardinality.MULTIPLE;
            } else {
                rd.cardinality = ReferenceCardinality.OPTIONAL;
            }
        } else {
            if (multiple.contains(referenceName)) {
                rd.cardinality = ReferenceCardinality.AT_LEAST_ONE;
            } else {
                rd.cardinality = ReferenceCardinality.MANDATORY;
            }
        }
        if (bind != null) {
            rd.bind = bind;
            if (unbind != null) {
                rd.unbind = unbind;
            }
            if (updated != null) {
                rd.updated = updated;
            }
        }
        if (dynamic.contains(referenceName)) {
            rd.policy = ReferencePolicy.DYNAMIC;
            if (rd.unbind == null)
                error("In component %s, reference %s is dynamic but has no unbind method.", cd.effectiveName(), rd.name).details(new DeclarativeServicesAnnotationError(cd.implementation.getFQN(), null, null, ErrorType.DYNAMIC_REFERENCE_WITHOUT_UNBIND));
        }
        if (greedy.contains(referenceName)) {
            rd.policyOption = ReferencePolicyOption.GREEDY;
        }
        if (target != null) {
            rd.target = target;
        }
        cd.references.put(referenceName, rd);
    }
}
Also used : Matcher(java.util.regex.Matcher) TypeRef(aQute.bnd.osgi.Descriptors.TypeRef) DeclarativeServicesAnnotationError(aQute.bnd.component.error.DeclarativeServicesAnnotationError) ArrayList(java.util.ArrayList) HashMap(java.util.HashMap) Map(java.util.Map)

Example 34 with TypeRef

use of aQute.bnd.osgi.Descriptors.TypeRef 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 TypeRef

use of aQute.bnd.osgi.Descriptors.TypeRef in project bnd by bndtools.

the class Analyzer method isProvider.

private boolean isProvider(TypeRef t) throws Exception {
    Clazz c = findClass(t);
    if (c == null)
        return false;
    if (c.annotations == null)
        return false;
    TypeRef r6pt = getTypeRefFromFQN("org.osgi.annotation.versioning.ProviderType");
    if (c.annotations.contains(r6pt)) {
        return true;
    }
    TypeRef pt = getTypeRefFromFQN("aQute.bnd.annotation.ProviderType");
    if (c.annotations.contains(pt)) {
        warning("%s annotation used in class %s. Bnd versioning annotations are deprecated as of Bnd 3.2 and support will be removed in Bnd 4.0. Please change to use OSGi versioning annotations.", "aQute.bnd.annotation.ProviderType", c);
        return true;
    }
    return false;
}
Also used : TypeRef(aQute.bnd.osgi.Descriptors.TypeRef)

Aggregations

TypeRef (aQute.bnd.osgi.Descriptors.TypeRef)42 Clazz (aQute.bnd.osgi.Clazz)12 PackageRef (aQute.bnd.osgi.Descriptors.PackageRef)7 HashMap (java.util.HashMap)6 LinkedHashMap (java.util.LinkedHashMap)6 Map (java.util.Map)6 Analyzer (aQute.bnd.osgi.Analyzer)5 ClassDataCollector (aQute.bnd.osgi.ClassDataCollector)5 IOException (java.io.IOException)5 ArrayList (java.util.ArrayList)5 HashSet (java.util.HashSet)5 Matcher (java.util.regex.Matcher)5 DeclarativeServicesAnnotationError (aQute.bnd.component.error.DeclarativeServicesAnnotationError)4 Attrs (aQute.bnd.header.Attrs)4 Annotation (aQute.bnd.osgi.Annotation)4 MultiMap (aQute.lib.collections.MultiMap)4 MethodDef (aQute.bnd.osgi.Clazz.MethodDef)3 Instructions (aQute.bnd.osgi.Instructions)3 Resource (aQute.bnd.osgi.Resource)3 Tag (aQute.lib.tag.Tag)3