Search in sources :

Example 6 with TypeRef

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

the class bnd method _xref.

/**
	 * Cross reference every class in the jar file to the files it references
	 */
@Description("Show a cross references for all classes in a set of jars.")
public void _xref(xrefOptions options) throws IOException, Exception {
    Analyzer analyzer = new Analyzer();
    final MultiMap<TypeRef, TypeRef> table = new MultiMap<TypeRef, TypeRef>();
    final MultiMap<PackageRef, PackageRef> packages = new MultiMap<PackageRef, PackageRef>();
    Set<TypeRef> set = Create.set();
    Instructions filter = new Instructions(options.match());
    for (String arg : options._arguments()) {
        try {
            File file = new File(arg);
            try (Jar jar = new Jar(file.getName(), file)) {
                for (Map.Entry<String, Resource> entry : jar.getResources().entrySet()) {
                    String key = entry.getKey();
                    Resource r = entry.getValue();
                    if (key.endsWith(".class")) {
                        TypeRef ref = analyzer.getTypeRefFromPath(key);
                        if (filter.matches(ref.toString())) {
                            set.add(ref);
                            try (InputStream in = r.openInputStream()) {
                                Clazz clazz = new Clazz(analyzer, key, r);
                                // TODO use the proper bcp instead
                                // of using the default layout
                                Set<TypeRef> s = clazz.parseClassFile();
                                for (Iterator<TypeRef> t = s.iterator(); t.hasNext(); ) {
                                    TypeRef tr = t.next();
                                    if (tr.isJava() || tr.isPrimitive())
                                        t.remove();
                                    else
                                        packages.add(ref.getPackageRef(), tr.getPackageRef());
                                }
                                table.addAll(ref, s);
                                set.addAll(s);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    boolean to = options.to();
    boolean from = options.from();
    if (to == false && from == false)
        to = from = true;
    if (options.classes()) {
        if (to)
            printxref(table, ">");
        if (from)
            printxref(table.transpose(), "<");
    } else {
        if (to)
            printxref(packages, ">");
        if (from)
            printxref(packages.transpose(), "<");
    }
}
Also used : TypeRef(aQute.bnd.osgi.Descriptors.TypeRef) JarInputStream(java.util.jar.JarInputStream) InputStream(java.io.InputStream) FileResource(aQute.bnd.osgi.FileResource) Resource(aQute.bnd.osgi.Resource) Instructions(aQute.bnd.osgi.Instructions) Analyzer(aQute.bnd.osgi.Analyzer) InvocationTargetException(java.lang.reflect.InvocationTargetException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) IOException(java.io.IOException) XPathExpressionException(javax.xml.xpath.XPathExpressionException) ZipException(java.util.zip.ZipException) MultiMap(aQute.lib.collections.MultiMap) Jar(aQute.bnd.osgi.Jar) Clazz(aQute.bnd.osgi.Clazz) PackageRef(aQute.bnd.osgi.Descriptors.PackageRef) File(java.io.File) MultiMap(aQute.lib.collections.MultiMap) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) TreeMap(java.util.TreeMap) HashMap(java.util.HashMap) Description(aQute.lib.getopt.Description)

Example 7 with TypeRef

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

the class AnnotationReader method doReference.

/**
	 * @param reference @Reference proxy backed by raw.
	 * @param raw @Reference contents
	 * @throws Exception
	 */
protected void doReference(Reference reference, Annotation raw) throws Exception {
    ReferenceDef def;
    if (member == null)
        def = new ReferenceDef(finder);
    else if (referencesByMember.containsKey(member))
        def = referencesByMember.get(member);
    else {
        def = new ReferenceDef(finder);
        referencesByMember.put(member, def);
    }
    def.className = className.getFQN();
    def.name = reference.name();
    def.bind = reference.bind();
    def.unbind = reference.unbind();
    def.updated = reference.updated();
    def.field = reference.field();
    def.fieldOption = reference.fieldOption();
    def.cardinality = reference.cardinality();
    def.policy = reference.policy();
    def.policyOption = reference.policyOption();
    def.scope = reference.scope();
    // Check if we have a target, this must be a filter
    def.target = reference.target();
    DeclarativeServicesAnnotationError details = getDetails(def, ErrorType.REFERENCE);
    if (def.target != null) {
        String error = Verifier.validateFilter(def.target);
        if (error != null)
            analyzer.error("Invalid target filter %s for %s: %s", def.target, def.name, error).details(getDetails(def, ErrorType.INVALID_TARGET_FILTER));
    }
    String annoService = null;
    TypeRef annoServiceTR = raw.get("service");
    if (annoServiceTR != null)
        annoService = annoServiceTR.getFQN();
    if (member != null) {
        if (member instanceof MethodDef) {
            def.bindDescriptor = member.getDescriptor().toString();
            if (!member.isProtected())
                def.updateVersion(V1_1);
            def.bind = member.getName();
            if (def.name == null) {
                Matcher m = BINDNAME.matcher(member.getName());
                if (m.matches())
                    def.name = m.group(2);
                else
                    analyzer.error("Invalid name for bind method %s", member.getName()).details(getDetails(def, ErrorType.INVALID_REFERENCE_BIND_METHOD_NAME));
            }
            def.service = determineReferenceType(def.bindDescriptor, def, annoService, member.getSignature());
            if (def.service == null)
                analyzer.error("In component %s, method %s,  cannot recognize the signature of the descriptor: %s", component.effectiveName(), def.name, member.getDescriptor());
        } else if (member instanceof FieldDef) {
            def.updateVersion(V1_3);
            def.field = member.getName();
            if (def.name == null)
                def.name = def.field;
            if (def.policy == null && member.isVolatile())
                def.policy = ReferencePolicy.DYNAMIC;
            String sig = member.getSignature();
            if (sig == null)
                // no generics, the descriptor will be the class name.
                sig = member.getDescriptor().toString();
            String[] sigs = sig.split("[<;>]");
            int sigLength = sigs.length;
            int index = 0;
            boolean isCollection = false;
            if ("Ljava/util/Collection".equals(sigs[index]) || "Ljava/util/List".equals(sigs[index])) {
                index++;
                isCollection = true;
            }
            // Along with determining the FieldCollectionType, the following
            // code positions index to read the service type.
            FieldCollectionType fieldCollectionType = null;
            if (sufficientGenerics(index, sigLength, def, sig)) {
                if ("Lorg/osgi/framework/ServiceReference".equals(sigs[index])) {
                    if (sufficientGenerics(index++, sigLength, def, sig)) {
                        fieldCollectionType = FieldCollectionType.reference;
                    }
                } else if ("Lorg/osgi/service/component/ComponentServiceObjects".equals(sigs[index])) {
                    if (sufficientGenerics(index++, sigLength, def, sig)) {
                        fieldCollectionType = FieldCollectionType.serviceobjects;
                    }
                } else if ("Ljava/util/Map".equals(sigs[index])) {
                    if (sufficientGenerics(index++, sigLength, def, sig)) {
                        fieldCollectionType = FieldCollectionType.properties;
                    }
                } else if ("Ljava/util/Map$Entry".equals(sigs[index]) && sufficientGenerics(index++ + 5, sigLength, def, sig)) {
                    if ("Ljava/util/Map".equals(sigs[index++]) && "Ljava/lang/String".equals(sigs[index++])) {
                        if ("Ljava/lang/Object".equals(sigs[index]) || "+Ljava/lang/Object".equals(sigs[index])) {
                            fieldCollectionType = FieldCollectionType.tuple;
                            // ;>;
                            index += 3;
                        } else if ("*".equals(sigs[index])) {
                            fieldCollectionType = FieldCollectionType.tuple;
                            // >;
                            index += 2;
                        } else {
                            // no idea what service might
                            index = sigLength;
                        // be.
                        }
                    }
                } else {
                    fieldCollectionType = FieldCollectionType.service;
                }
            }
            if (isCollection) {
                if (def.cardinality == null)
                    def.cardinality = ReferenceCardinality.MULTIPLE;
                def.fieldCollectionType = fieldCollectionType;
            }
            if (def.policy == ReferencePolicy.DYNAMIC && (def.cardinality == ReferenceCardinality.MULTIPLE || def.cardinality == ReferenceCardinality.AT_LEAST_ONE) && member.isFinal()) {
                if (def.fieldOption == FieldOption.REPLACE)
                    analyzer.error("In component %s, collection type field: %s is final and dynamic but marked with 'replace' fieldOption. Changing this to 'update'.", className, def.field).details(getDetails(def, ErrorType.DYNAMIC_FINAL_FIELD_WITH_REPLACE));
                def.fieldOption = FieldOption.UPDATE;
            }
            if (annoService == null && index < sigs.length) {
                annoService = sigs[index].substring(1).replace('/', '.');
            }
            def.service = annoService;
            if (def.service == null)
                analyzer.error("In component %s, method %s,  cannot recognize the signature of the descriptor: %s", component.effectiveName(), def.name, member.getDescriptor()).details(details);
        }
    // end field
    } else {
        // not a member
        def.service = annoService;
        if (def.name == null) {
            analyzer.error("Name must be supplied for a @Reference specified in the @Component annotation. Service: %s", def.service).details(getDetails(def, ErrorType.MISSING_REFERENCE_NAME));
            return;
        }
    }
    if (component.references.containsKey(def.name))
        analyzer.error("In component %s, multiple references with the same name: %s. Previous def: %s, this def: %s", className, component.references.get(def.name), def.service, "").details(getDetails(def, ErrorType.MULTIPLE_REFERENCES_SAME_NAME));
    else
        component.references.put(def.name, def);
}
Also used : FieldDef(aQute.bnd.osgi.Clazz.FieldDef) MethodDef(aQute.bnd.osgi.Clazz.MethodDef) Matcher(java.util.regex.Matcher) DeclarativeServicesAnnotationError(aQute.bnd.component.error.DeclarativeServicesAnnotationError) TypeRef(aQute.bnd.osgi.Descriptors.TypeRef)

Example 8 with TypeRef

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

the class Verifier method verifyActivator.

private void verifyActivator() throws Exception {
    String bactivator = main.get(Constants.BUNDLE_ACTIVATOR);
    if (bactivator != null) {
        if (!PACKAGEPATTERN.matcher(bactivator).matches()) {
            boolean allElementsAreTypes = true;
            for (String element : split(bactivator)) {
                if (!PACKAGEPATTERN.matcher(element.trim()).matches()) {
                    allElementsAreTypes = false;
                    break;
                }
            }
            if (allElementsAreTypes) {
                registerActivatorErrorLocation(error("The Bundle-Activator header only supports a single type. The following types were found: %s. This usually happens when a macro resolves to multiple types", bactivator), bactivator, ActivatorErrorType.MULTIPLE_TYPES);
            } else {
                registerActivatorErrorLocation(error("A Bundle-Activator header is present and its value is not a valid type name %s", bactivator), bactivator, ActivatorErrorType.INVALID_TYPE_NAME);
            }
            return;
        }
        TypeRef ref = analyzer.getTypeRefFromFQN(bactivator);
        if (analyzer.getClassspace().containsKey(ref)) {
            Clazz activatorClazz = analyzer.getClassspace().get(ref);
            if (activatorClazz.isInterface()) {
                registerActivatorErrorLocation(error("The Bundle Activator %s is an interface and therefore cannot be instantiated.", bactivator), bactivator, ActivatorErrorType.IS_INTERFACE);
            } else {
                if (activatorClazz.isAbstract()) {
                    registerActivatorErrorLocation(error("The Bundle Activator %s is abstract and therefore cannot be instantiated.", bactivator), bactivator, ActivatorErrorType.IS_ABSTRACT);
                }
                if (!activatorClazz.isPublic()) {
                    registerActivatorErrorLocation(error("Bundle Activator classes must be public, and %s is not.", bactivator), bactivator, ActivatorErrorType.NOT_PUBLIC);
                }
                if (!activatorClazz.hasPublicNoArgsConstructor()) {
                    registerActivatorErrorLocation(error("Bundle Activator classes must have a public zero-argument constructor and %s does not.", bactivator), bactivator, ActivatorErrorType.NO_SUITABLE_CONSTRUCTOR);
                }
                if (!analyzer.assignable(activatorClazz.getFQN(), "org.osgi.framework.BundleActivator")) {
                    registerActivatorErrorLocation(error("The Bundle Activator %s does not implement BundleActivator.", bactivator), bactivator, ActivatorErrorType.NOT_AN_ACTIVATOR);
                }
            }
            return;
        }
        PackageRef packageRef = ref.getPackageRef();
        if (packageRef.isDefaultPackage())
            registerActivatorErrorLocation(error("The Bundle Activator is not in the bundle and it is in the default package "), bactivator, ActivatorErrorType.DEFAULT_PACKAGE);
        else if (!analyzer.isImported(packageRef)) {
            registerActivatorErrorLocation(error(Constants.BUNDLE_ACTIVATOR + " not found on the bundle class path nor in imports: %s", bactivator), bactivator, ActivatorErrorType.NOT_ACCESSIBLE);
        } else {
            registerActivatorErrorLocation(warning(Constants.BUNDLE_ACTIVATOR + " %s is being imported into the bundle rather than being contained inside it. This is usually a bundle packaging error", bactivator), bactivator, ActivatorErrorType.IS_IMPORTED);
        }
    } else if (parent != null) {
        // If we have access to the parent we can do deeper checking
        String raw = parent.getUnprocessedProperty(BUNDLE_ACTIVATOR, null);
        if (raw != null) {
            // The activator was specified, but nothing showed up.
            if (raw.isEmpty()) {
                registerActivatorErrorLocation(warning("A Bundle-Activator header was present but no activator class was defined"), "", ActivatorErrorType.NOT_SET);
            } else {
                registerActivatorErrorLocation(error("A Bundle-Activator header is present but no activator class was found using the macro %s", raw), raw, ActivatorErrorType.NO_RESULT_FROM_MACRO);
            }
            return;
        }
    }
}
Also used : TypeRef(aQute.bnd.osgi.Descriptors.TypeRef) PackageRef(aQute.bnd.osgi.Descriptors.PackageRef)

Example 9 with TypeRef

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

the class Clazz method doAnnotation.

// annotation {
// u2 type_index;
// u2 num_element_value_pairs; {
// u2 element_name_index;
// element_value value;
// }
// element_value_pairs[num_element_value_pairs];
// }
private Annotation doAnnotation(DataInput in, ElementType member, RetentionPolicy policy, boolean collect, int access_flags) throws IOException {
    int type_index = in.readUnsignedShort();
    if (annotations == null)
        annotations = new HashSet<TypeRef>();
    String typeName = (String) pool[type_index];
    TypeRef typeRef = null;
    if (typeName != null) {
        typeRef = analyzer.getTypeRef(typeName);
        annotations.add(typeRef);
        if (policy == RetentionPolicy.RUNTIME) {
            referTo(type_index, 0);
            hasRuntimeAnnotations = true;
            if (api != null && (Modifier.isPublic(access_flags) || Modifier.isProtected(access_flags)))
                api.add(typeRef.getPackageRef());
        } else {
            hasClassAnnotations = true;
        }
    }
    int num_element_value_pairs = in.readUnsignedShort();
    Map<String, Object> elements = null;
    for (int v = 0; v < num_element_value_pairs; v++) {
        int element_name_index = in.readUnsignedShort();
        String element = (String) pool[element_name_index];
        Object value = doElementValue(in, member, policy, collect, access_flags);
        if (collect) {
            if (elements == null)
                elements = new LinkedHashMap<String, Object>();
            elements.put(element, value);
        }
    }
    if (collect)
        return new Annotation(typeRef, elements, member, policy);
    return null;
}
Also used : TypeRef(aQute.bnd.osgi.Descriptors.TypeRef) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap)

Example 10 with TypeRef

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

the class Clazz method doElementValue.

private Object doElementValue(DataInput in, ElementType member, RetentionPolicy policy, boolean collect, int access_flags) throws IOException {
    char tag = (char) in.readUnsignedByte();
    switch(tag) {
        // Byte
        case 'B':
        // Character
        case 'C':
        // Integer
        case 'I':
        case // Short
        'S':
            int const_value_index = in.readUnsignedShort();
            return intPool[const_value_index];
        // Double
        case 'D':
        // Float
        case 'F':
        // String
        case 's':
        case // Long
        'J':
            const_value_index = in.readUnsignedShort();
            return pool[const_value_index];
        case // Boolean
        'Z':
            const_value_index = in.readUnsignedShort();
            return pool[const_value_index] == null || pool[const_value_index].equals(0) ? false : true;
        case // enum constant
        'e':
            int type_name_index = in.readUnsignedShort();
            if (policy == RetentionPolicy.RUNTIME) {
                referTo(type_name_index, 0);
                if (api != null && (Modifier.isPublic(access_flags) || Modifier.isProtected(access_flags))) {
                    TypeRef name = analyzer.getTypeRef((String) pool[type_name_index]);
                    api.add(name.getPackageRef());
                }
            }
            int const_name_index = in.readUnsignedShort();
            return pool[const_name_index];
        case // Class
        'c':
            int class_info_index = in.readUnsignedShort();
            TypeRef name = analyzer.getTypeRef((String) pool[class_info_index]);
            if (policy == RetentionPolicy.RUNTIME) {
                referTo(class_info_index, 0);
                if (api != null && (Modifier.isPublic(access_flags) || Modifier.isProtected(access_flags))) {
                    api.add(name.getPackageRef());
                }
            }
            return name;
        case // Annotation type
        '@':
            return doAnnotation(in, member, policy, collect, access_flags);
        case // Array
        '[':
            int num_values = in.readUnsignedShort();
            Object[] result = new Object[num_values];
            for (int i = 0; i < num_values; i++) {
                result[i] = doElementValue(in, member, policy, collect, access_flags);
            }
            return result;
        default:
            throw new IllegalArgumentException("Invalid value for Annotation ElementValue tag " + tag);
    }
}
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