private Metadata parseService()

in blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiNamespaceHandler.java [144:270]


    private Metadata parseService(Element element, ParserContext context) {
        MutableServiceMetadata metadata = context.createMetadata(MutableServiceMetadata.class);
        // Parse attributes
        if (element.hasAttribute(ID_ATTRIBUTE)) {
            metadata.setId(element.getAttribute(ID_ATTRIBUTE));
        } else {
            metadata.setId(generateId(context));
        }
        if (nonEmpty(element.getAttribute(REF_ATTRIBUTE)) != null) {
            MutableRefMetadata ref = context.createMetadata(MutableRefMetadata.class);
            ref.setComponentId(element.getAttribute(REF_ATTRIBUTE));
            metadata.setServiceComponent(ref);
        }
        metadata.setRanking(nonEmpty(element.getAttribute(RANKING_ATTRIBUTE)) != null
                ? Integer.parseInt(element.getAttribute(RANKING_ATTRIBUTE))
                : 0);
        String itf = nonEmpty(element.getAttribute(INTERFACE_ATTRIBUTE));
        if (itf != null) {
            metadata.addInterface(itf);
        }
        String[] dependsOn = StringUtils.tokenizeToStringArray(nonEmpty(element.getAttribute(DEPENDS_ON_ATTRIBUTE)), ",; ");
        metadata.setDependsOn(dependsOn != null ? Arrays.asList(dependsOn) : null);
        String autoExp = nonEmpty(element.getAttribute(AUTO_EXPORT_ATTRIBUTE));
        if (AUTO_EXPORT_INTERFACES.equals(autoExp)) {
            metadata.setAutoExport(ServiceMetadata.AUTO_EXPORT_INTERFACES);
        } else if (AUTO_EXPORT_CLASS_HIERARCHY.equals(autoExp)) {
            metadata.setAutoExport(ServiceMetadata.AUTO_EXPORT_CLASS_HIERARCHY);
        } else if (AUTO_EXPORT_ALL_CLASSES.equals(autoExp)) {
            metadata.setAutoExport(ServiceMetadata.AUTO_EXPORT_ALL_CLASSES);
        } else {
            metadata.setAutoExport(ServiceMetadata.AUTO_EXPORT_DISABLED);
        }
        // TODO: @context-class-loader
        // Parse child elements
        for (Element child : getChildren(element)) {
            if (element.getNamespaceURI().equals(child.getNamespaceURI())) {
                if (INTERFACES_ELEMENT.equals(child.getLocalName())) {
                    List<String> itfs = parseInterfaces(child);
                    for (String intf : itfs) {
                        metadata.addInterface(intf);
                    }
                }
                else if (REGISTRATION_LISTENER_ELEMENT.equals(child.getLocalName())) {
                    String regMethod = nonEmpty(child.getAttribute(REGISTRATION_METHOD_ATTRIBUTE));
                    String unregMethod = nonEmpty(child.getAttribute(UNREGISTRATION_METHOD_ATTRIBUTE));
                    String refStr = nonEmpty(child.getAttribute(REF_ATTRIBUTE));
                    Target listenerComponent = null;
                    if (refStr != null) {
                        MutableRefMetadata ref = context.createMetadata(MutableRefMetadata.class);
                        ref.setComponentId(refStr);
                        listenerComponent = ref;
                    }
                    for (Element cchild : getChildren(child)) {
                        if (listenerComponent != null) {
                            throw new IllegalArgumentException("Only one of @ref attribute or inlined bean definition element is allowed");
                        }
                        listenerComponent = parseInlinedTarget(context, metadata, cchild);
                    }
                    if (listenerComponent == null) {
                        throw new IllegalArgumentException("Missing @ref attribute or inlined bean definition element");
                    }
                    metadata.addRegistrationListener(listenerComponent, regMethod, unregMethod);
                }
                else if (SERVICE_PROPERTIES_ELEMENT.equals(child.getLocalName())) {
                    // TODO: @key-type
                    for (Element e : getChildren(child)) {
                        if (ENTRY_ELEMENT.equals(e.getLocalName())) {
                            NonNullMetadata key;
                            Metadata val;
                            boolean hasKeyAttribute = e.hasAttribute(KEY_ATTRIBUTE);
                            boolean hasKeyRefAttribute = e.hasAttribute(KEY_REF_ATTRIBUTE);
                            if (hasKeyRefAttribute && !hasKeyAttribute) {
                                MutableRefMetadata r = context.createMetadata(MutableRefMetadata.class);
                                r.setComponentId(e.getAttribute(KEY_REF_ATTRIBUTE));
                                key = r;
                            } else if (hasKeyAttribute && !hasKeyRefAttribute) {
                                MutableValueMetadata v = context.createMetadata(MutableValueMetadata.class);
                                v.setStringValue(e.getAttribute(KEY_ATTRIBUTE));
                                key = v;
                            } else {
                                throw new IllegalStateException("Either key or key-ref must be specified");
                            }
                            // TODO: support key
                            boolean hasValAttribute = e.hasAttribute(VALUE_ATTRIBUTE);
                            boolean hasValRefAttribute = e.hasAttribute(VALUE_REF_ATTRIBUTE);
                            if (hasValRefAttribute && !hasValAttribute) {
                                MutableRefMetadata r = context.createMetadata(MutableRefMetadata.class);
                                r.setComponentId(e.getAttribute(VALUE_REF_ATTRIBUTE));
                                val = r;
                            } else if (hasValAttribute && !hasValRefAttribute) {
                                MutableValueMetadata v = context.createMetadata(MutableValueMetadata.class);
                                v.setStringValue(e.getAttribute(VALUE_ATTRIBUTE));
                                val = v;
                            } else {
                                throw new IllegalStateException("Either val or val-ref must be specified");
                            }
                            // TODO: support children elements ?
                            metadata.addServiceProperty(key, val);
                        }
                    }
                }
            }
            else if (BLUEPRINT_NAMESPACE.equals(child.getNamespaceURI())
                    && BEAN_ELEMENT.equals(child.getLocalName())) {
                if (metadata.getServiceComponent() != null) {
                    throw new IllegalArgumentException("Only one of @ref attribute and bean element is allowed");
                }
                Target bean = context.parseElement(BeanMetadata.class, metadata, child);
                metadata.setServiceComponent(bean);
            }
            else {
                if (metadata.getServiceComponent() != null) {
                    throw new IllegalArgumentException("Only one of @ref attribute or inlined bean definition element is allowed");
                }
                NamespaceHandler handler = context.getNamespaceHandler(URI.create(child.getNamespaceURI()));
                if (handler == null) {
                    throw new IllegalStateException("No NamespaceHandler found for " + child.getNamespaceURI());
                }
                Metadata md = handler.parse(child, context);
                if (!(md instanceof Target)) {
                    throw new IllegalStateException("NamespaceHandler did not return a Target instance but " + md);
                }
                metadata.setServiceComponent((Target) md);
            }
        }
        return metadata;
    }