Search in sources :

Example 1 with SCRDescriptorException

use of org.apache.felix.scrplugin.SCRDescriptorException in project felix by apache.

the class DSAnnotationProcessor method createComponent.

/**
 * Create a component description.
 *
 * @param cad The component annotation for the class.
 * @param scannedClass The scanned class.
 */
private ComponentDescription createComponent(final ClassAnnotation cad, final ClassDescription describedClass, final ScannedClass scannedClass) throws SCRDescriptorException {
    final ComponentDescription component = new ComponentDescription(cad);
    describedClass.add(component);
    // Although not defined in the spec, we support abstract classes.
    final boolean classIsAbstract = Modifier.isAbstract(scannedClass.getClass().getModifiers());
    component.setAbstract(classIsAbstract);
    // name
    component.setName(cad.getStringValue("name", scannedClass.getScannedClass().getName()));
    // services
    final List<String> listedInterfaces = new ArrayList<String>();
    if (cad.hasValue("service")) {
        final String[] interfaces = (String[]) cad.getValue("service");
        if (interfaces != null) {
            for (final String t : interfaces) {
                listedInterfaces.add(t);
            }
        }
    } else {
        // scan directly implemented interfaces
        this.searchInterfaces(listedInterfaces, scannedClass.getScannedClass());
    }
    if (listedInterfaces.size() > 0) {
        final ServiceDescription serviceDesc = new ServiceDescription(cad);
        describedClass.add(serviceDesc);
        for (final String name : listedInterfaces) {
            serviceDesc.addInterface(name);
        }
        serviceDesc.setServiceFactory(cad.getBooleanValue("servicefactory", false));
    }
    // factory
    component.setFactory(cad.getStringValue("factory", null));
    // enabled
    if (cad.getValue("enabled") != null) {
        component.setEnabled(cad.getBooleanValue("enabled", true));
    }
    // immediate
    if (cad.getValue("immediate") != null) {
        component.setImmediate(cad.getBooleanValue("immediate", false));
    }
    // property
    final String[] property = (String[]) cad.getValue("property");
    if (property != null) {
        // TODO - what do we do if the value is invalid?
        for (final String propDef : property) {
            final int pos = propDef.indexOf('=');
            if (pos != -1) {
                final String prefix = propDef.substring(0, pos);
                final String value = propDef.substring(pos + 1);
                final int typeSep = prefix.indexOf(':');
                final String key = (typeSep == -1 ? prefix : prefix.substring(0, typeSep));
                final String type = (typeSep == -1 ? PropertyType.String.name() : prefix.substring(typeSep + 1));
                final PropertyType propType = PropertyType.valueOf(type);
                // FELIX-4159 : check if this is a multi value prop
                final List<PropertyDescription> existingProps = describedClass.getDescriptions(PropertyDescription.class);
                PropertyDescription found = null;
                for (final PropertyDescription current : existingProps) {
                    if (current.getName().equals(key)) {
                        found = current;
                        break;
                    }
                }
                if (found == null) {
                    final PropertyDescription pd = new PropertyDescription(cad);
                    describedClass.add(pd);
                    pd.setName(key);
                    pd.setValue(value);
                    pd.setType(propType);
                    pd.setUnbounded(PropertyUnbounded.DEFAULT);
                } else {
                    if (propType != found.getType()) {
                        throw new SCRDescriptorException("Multi value property '" + key + "' has different types: " + found.getType() + " & " + propType, describedClass.getSource());
                    }
                    if (found.getValue() != null) {
                        final String[] values = new String[2];
                        values[0] = found.getValue();
                        values[1] = value;
                        found.setMultiValue(values);
                    } else {
                        final String[] oldValues = found.getMultiValue();
                        final String[] newValues = new String[oldValues.length + 1];
                        System.arraycopy(oldValues, 0, newValues, 0, oldValues.length);
                        newValues[oldValues.length] = value;
                        found.setMultiValue(newValues);
                    }
                }
            }
        }
    }
    // xmlns
    if (cad.getValue("xmlns") != null) {
        final SpecVersion spec = SpecVersion.fromNamespaceUrl(cad.getValue("xmlns").toString());
        if (spec == null) {
            throw new SCRDescriptorException("Unknown xmlns attribute value: " + cad.getValue("xmlns"), describedClass.getSource());
        }
        component.setSpecVersion(spec);
    }
    // configuration policy
    component.setConfigurationPolicy(ComponentConfigurationPolicy.valueOf(cad.getEnumValue("configurationPolicy", ComponentConfigurationPolicy.OPTIONAL.name())));
    // configuration pid
    Object configPid = cad.getValue("configurationPid");
    if (configPid instanceof String) {
        component.setConfigurationPid((String) configPid);
    } else if (configPid instanceof String[] && ((String[]) configPid).length == 1) {
        component.setConfigurationPid(((String[]) configPid)[0]);
    } else {
        component.setConfigurationPid(null);
    }
    component.setCreatePid(false);
    // no inheritance
    component.setInherit(false);
    return component;
}
Also used : ComponentDescription(org.apache.felix.scrplugin.description.ComponentDescription) ServiceDescription(org.apache.felix.scrplugin.description.ServiceDescription) ArrayList(java.util.ArrayList) PropertyType(org.apache.felix.scrplugin.description.PropertyType) PropertyDescription(org.apache.felix.scrplugin.description.PropertyDescription) SpecVersion(org.apache.felix.scrplugin.SpecVersion) SCRDescriptorException(org.apache.felix.scrplugin.SCRDescriptorException)

Example 2 with SCRDescriptorException

use of org.apache.felix.scrplugin.SCRDescriptorException in project felix by apache.

the class ClassScanner method extractAnnotation.

/**
 * Extract annotations
 */
private final List<ScannedAnnotation> extractAnnotation(final ClassNode classNode, final Class<?> annotatedClass) throws SCRDescriptorException {
    final List<ScannedAnnotation> descriptions = new ArrayList<ScannedAnnotation>();
    // first parse class annotations
    @SuppressWarnings("unchecked") final List<AnnotationNode> annotations = getAllAnnotations(classNode.invisibleAnnotations, classNode.visibleAnnotations);
    if (annotations != null) {
        for (final AnnotationNode annotation : annotations) {
            this.parseAnnotation(descriptions, annotation, annotatedClass);
        }
        // second parse method annotations
        @SuppressWarnings("unchecked") final List<MethodNode> methods = classNode.methods;
        if (methods != null) {
            for (final MethodNode method : methods) {
                final String name = method.name;
                // check for constructor
                if (!"<init>".equals(name)) {
                    @SuppressWarnings("unchecked") final List<AnnotationNode> annos = getAllAnnotations(method.invisibleAnnotations, method.visibleAnnotations);
                    if (annos != null) {
                        final Type[] signature = Type.getArgumentTypes(method.desc);
                        final Method[] allMethods = annotatedClass.getDeclaredMethods();
                        Method found = null;
                        for (final Method m : allMethods) {
                            if (m.getName().equals(name)) {
                                if (m.getParameterTypes().length == 0 && (signature == null || signature.length == 0)) {
                                    found = m;
                                }
                                if (m.getParameterTypes().length > 0 && signature != null && m.getParameterTypes().length == signature.length) {
                                    found = m;
                                    for (int index = 0; index < m.getParameterTypes().length; index++) {
                                        String parameterTypeName = m.getParameterTypes()[index].getName();
                                        // Name of array parameters is returned with syntax [L<name>;, convert to <name>[]
                                        Matcher matcher = ARRAY_PARAM_TYPE_NAME.matcher(parameterTypeName);
                                        if (matcher.matches()) {
                                            parameterTypeName = matcher.group(1) + "[]";
                                        }
                                        if (!parameterTypeName.equals(signature[index].getClassName()) && !m.getParameterTypes()[index].getSimpleName().equals(signature[index].getClassName())) {
                                            found = null;
                                        }
                                    }
                                }
                                // if method is found return it now, to avoid resetting 'found' to null if next method has same name but different parameters
                                if (found != null) {
                                    break;
                                }
                            }
                        }
                        if (found == null) {
                            throw new SCRDescriptorException("Annotated method " + name + " not found.", annotatedClass.getName());
                        }
                        for (final AnnotationNode annotation : annos) {
                            parseAnnotation(descriptions, annotation, found);
                        }
                    }
                }
            }
        }
        // third parse field annotations
        @SuppressWarnings("unchecked") final List<FieldNode> fields = classNode.fields;
        if (fields != null) {
            for (final FieldNode field : fields) {
                @SuppressWarnings("unchecked") final List<AnnotationNode> annos = getAllAnnotations(field.invisibleAnnotations, field.visibleAnnotations);
                if (annos != null) {
                    final String name = field.name;
                    final Field[] allFields = annotatedClass.getDeclaredFields();
                    Field found = null;
                    for (final Field f : allFields) {
                        if (f.getName().equals(name)) {
                            found = f;
                            break;
                        }
                    }
                    if (found == null) {
                        throw new SCRDescriptorException("Annotated field " + name + " not found.", annotatedClass.getName());
                    }
                    for (final AnnotationNode annotation : annos) {
                        parseAnnotation(descriptions, annotation, found);
                    }
                }
            }
        }
    }
    return descriptions;
}
Also used : FieldNode(org.objectweb.asm.tree.FieldNode) Matcher(java.util.regex.Matcher) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) Field(java.lang.reflect.Field) Type(org.objectweb.asm.Type) MethodNode(org.objectweb.asm.tree.MethodNode) AnnotationNode(org.objectweb.asm.tree.AnnotationNode) ScannedAnnotation(org.apache.felix.scrplugin.annotations.ScannedAnnotation) SCRDescriptorException(org.apache.felix.scrplugin.SCRDescriptorException)

Example 3 with SCRDescriptorException

use of org.apache.felix.scrplugin.SCRDescriptorException in project felix by apache.

the class Validator method findMethod.

/**
 * Find the method and the required spec version
 * @throws SCRDescriptorException If the class can't be found
 */
public static MethodResult findMethod(final Project project, final Options options, final ClassDescription cd, final ReferenceDescription ref, final String methodName) throws SCRDescriptorException {
    if ("-".equals(methodName)) {
        return null;
    }
    SpecVersion requiredVersion = SpecVersion.VERSION_1_0;
    try {
        final Class<?>[] sig = new Class<?>[] { project.getClassLoader().loadClass(TYPE_SERVICE_REFERENCE) };
        final Class<?>[] sig2 = new Class<?>[] { project.getClassLoader().loadClass(ref.getInterfaceName()) };
        final Class<?>[] sig3 = new Class<?>[] { project.getClassLoader().loadClass(ref.getInterfaceName()), Map.class };
        // service interface or ServiceReference first
        String realMethodName = methodName;
        Method method = getMethod(cd, realMethodName, sig);
        if (method == null) {
            method = getMethod(cd, realMethodName, sig2);
            if (method == null && (options.getSpecVersion() == null || options.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal())) {
                method = getMethod(cd, realMethodName, sig3);
                requiredVersion = SpecVersion.VERSION_1_1;
            }
        }
        // append reference name with service interface and ServiceReference
        if (method == null) {
            final String info;
            if (StringUtils.isEmpty(ref.getName())) {
                final String interfaceName = ref.getInterfaceName();
                final int pos = interfaceName.lastIndexOf('.');
                info = interfaceName.substring(pos + 1);
            } else {
                info = ref.getName();
            }
            realMethodName = methodName + Character.toUpperCase(info.charAt(0)) + info.substring(1);
            method = getMethod(cd, realMethodName, sig);
        }
        if (method == null) {
            method = getMethod(cd, realMethodName, sig2);
            if (method == null && (options.getSpecVersion() == null || options.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal())) {
                method = getMethod(cd, realMethodName, sig3);
                requiredVersion = SpecVersion.VERSION_1_1;
            }
        }
        // append type name with service interface and ServiceReference
        if (method == null) {
            int lastDot = ref.getInterfaceName().lastIndexOf('.');
            realMethodName = methodName + ref.getInterfaceName().substring(lastDot + 1);
            method = getMethod(cd, realMethodName, sig);
        }
        if (method == null) {
            method = getMethod(cd, realMethodName, sig2);
            if (method == null && (options.getSpecVersion() == null || options.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal())) {
                method = getMethod(cd, realMethodName, sig3);
                requiredVersion = SpecVersion.VERSION_1_1;
            }
        }
        if (method == null) {
            return null;
        }
        final MethodResult result = new MethodResult();
        result.method = method;
        result.requiredSpecVersion = requiredVersion;
        return result;
    } catch (final ClassNotFoundException cnfe) {
        throw new SCRDescriptorException("Unable to load class!", cnfe);
    }
}
Also used : SpecVersion(org.apache.felix.scrplugin.SpecVersion) Method(java.lang.reflect.Method) Map(java.util.Map) SCRDescriptorException(org.apache.felix.scrplugin.SCRDescriptorException)

Example 4 with SCRDescriptorException

use of org.apache.felix.scrplugin.SCRDescriptorException in project felix by apache.

the class ComponentDescriptorIO method read.

public static List<ClassDescription> read(final InputStream file, final ClassLoader classLoader, final IssueLog iLog, final String location) throws SCRDescriptorException {
    try {
        final XmlHandler xmlHandler = new XmlHandler(classLoader, iLog, location);
        IOUtils.parse(file, xmlHandler);
        return xmlHandler.components;
    } catch (final TransformerException e) {
        throw new SCRDescriptorException("Unable to read xml", location, e);
    }
}
Also used : TransformerException(javax.xml.transform.TransformerException) SCRDescriptorException(org.apache.felix.scrplugin.SCRDescriptorException)

Example 5 with SCRDescriptorException

use of org.apache.felix.scrplugin.SCRDescriptorException in project felix by apache.

the class MetaTypeIO method write.

/**
 * Generate the xml top level element and start streaming
 * the meta data.
 * @param metaData
 * @param contentHandler
 * @throws SAXException
 */
private static void write(final DescriptionContainer metaData, final List<ComponentContainer> components, final File file, final String localization) throws SCRDescriptorException {
    final String namespace = detectMetatypeVersion(metaData);
    try {
        FileOutputStream fos = new FileOutputStream(file);
        try {
            final ContentHandler contentHandler = IOUtils.getSerializer(fos);
            contentHandler.startDocument();
            contentHandler.startPrefixMapping(PREFIX, namespace);
            final AttributesImpl ai = new AttributesImpl();
            IOUtils.addAttribute(ai, "localization", localization);
            contentHandler.startElement(namespace, METADATA_ELEMENT, METADATA_ELEMENT_QNAME, ai);
            IOUtils.newline(contentHandler);
            for (final ComponentContainer comp : components) {
                if (comp.getMetatypeContainer() != null) {
                    generateOCDXML(comp.getMetatypeContainer(), contentHandler);
                    generateDesignateXML(comp.getMetatypeContainer(), contentHandler);
                }
            }
            // end wrapper element
            contentHandler.endElement(namespace, METADATA_ELEMENT, METADATA_ELEMENT_QNAME);
            IOUtils.newline(contentHandler);
            contentHandler.endPrefixMapping(PREFIX);
            contentHandler.endDocument();
        } finally {
            fos.close();
        }
    } catch (final IOException e) {
        throw new SCRDescriptorException("Unable to generate xml", file.toString(), e);
    } catch (final TransformerException e) {
        throw new SCRDescriptorException("Unable to generate xml", file.toString(), e);
    } catch (final SAXException e) {
        throw new SCRDescriptorException("Unable to generate xml", file.toString(), e);
    }
}
Also used : AttributesImpl(org.xml.sax.helpers.AttributesImpl) FileOutputStream(java.io.FileOutputStream) ComponentContainer(org.apache.felix.scrplugin.helper.ComponentContainer) IOException(java.io.IOException) ContentHandler(org.xml.sax.ContentHandler) SCRDescriptorException(org.apache.felix.scrplugin.SCRDescriptorException) TransformerException(javax.xml.transform.TransformerException) SAXException(org.xml.sax.SAXException)

Aggregations

SCRDescriptorException (org.apache.felix.scrplugin.SCRDescriptorException)14 IOException (java.io.IOException)6 ArrayList (java.util.ArrayList)5 FileInputStream (java.io.FileInputStream)4 File (java.io.File)3 FileOutputStream (java.io.FileOutputStream)3 FilterInputStream (java.io.FilterInputStream)3 InputStream (java.io.InputStream)3 TransformerException (javax.xml.transform.TransformerException)3 SCRDescriptorFailureException (org.apache.felix.scrplugin.SCRDescriptorFailureException)3 SpecVersion (org.apache.felix.scrplugin.SpecVersion)3 ClassDescription (org.apache.felix.scrplugin.description.ClassDescription)3 ComponentContainer (org.apache.felix.scrplugin.helper.ComponentContainer)3 Method (java.lang.reflect.Method)2 Options (org.apache.felix.scrplugin.Options)2 SCRDescriptorGenerator (org.apache.felix.scrplugin.SCRDescriptorGenerator)2 ScannedAnnotation (org.apache.felix.scrplugin.annotations.ScannedAnnotation)2 ComponentContainerContainer (org.apache.felix.scrplugin.helper.ComponentContainerUtil.ComponentContainerContainer)2 ClassReader (org.objectweb.asm.ClassReader)2 ClassNode (org.objectweb.asm.tree.ClassNode)2