private ComponentMetadata parseManagedServiceFactory()

in blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java [371:475]


    private ComponentMetadata parseManagedServiceFactory(ParserContext context, Element element) {
        String id = getId(context, element);

        MutableBeanMetadata factoryMetadata = context.createMetadata(MutableBeanMetadata.class);
        generateIdIfNeeded(context, factoryMetadata);
        factoryMetadata.addProperty("id", createValue(context, factoryMetadata.getId()));
        factoryMetadata.setScope(BeanMetadata.SCOPE_SINGLETON);
        factoryMetadata.setRuntimeClass(CmManagedServiceFactory.class);
        factoryMetadata.setInitMethod("init");
        factoryMetadata.setDestroyMethod("destroy");
        factoryMetadata.addArgument(createRef(context, "blueprintContainer"), null, 0);
        factoryMetadata.addProperty("factoryPid", createValue(context, element.getAttribute(FACTORY_PID_ATTRIBUTE)));
        String autoExport = element.hasAttribute(AUTO_EXPORT_ATTRIBUTE) ? element.getAttribute(AUTO_EXPORT_ATTRIBUTE) : AUTO_EXPORT_DEFAULT;
        if (AUTO_EXPORT_DISABLED.equals(autoExport)) {
            autoExport = Integer.toString(ServiceMetadata.AUTO_EXPORT_DISABLED);
        } else if (AUTO_EXPORT_INTERFACES.equals(autoExport)) {
            autoExport = Integer.toString(ServiceMetadata.AUTO_EXPORT_INTERFACES);
        } else if (AUTO_EXPORT_CLASS_HIERARCHY.equals(autoExport)) {
            autoExport = Integer.toString(ServiceMetadata.AUTO_EXPORT_CLASS_HIERARCHY);
        } else if (AUTO_EXPORT_ALL.equals(autoExport)) {
            autoExport = Integer.toString(ServiceMetadata.AUTO_EXPORT_ALL_CLASSES);
        } else {
            throw new ComponentDefinitionException("Illegal value (" + autoExport + ") for " + AUTO_EXPORT_ATTRIBUTE + " attribute");
        }
        factoryMetadata.addProperty("autoExport", createValue(context, autoExport));
        String ranking = element.hasAttribute(RANKING_ATTRIBUTE) ? element.getAttribute(RANKING_ATTRIBUTE) : RANKING_DEFAULT;
        factoryMetadata.addProperty("ranking", createValue(context, ranking));

        List<String> interfaces = null;
        if (element.hasAttribute(INTERFACE_ATTRIBUTE)) {
            interfaces = Collections.singletonList(element.getAttribute(INTERFACE_ATTRIBUTE));
            factoryMetadata.addProperty("interfaces", createList(context, interfaces));
        }
       
        // Parse elements
        List<RegistrationListener> listeners = new ArrayList<RegistrationListener>();
        NodeList nl = element.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            if (node instanceof Element) {
                Element e = (Element) node;
                if (isBlueprintNamespace(e.getNamespaceURI())) {
                    if (nodeNameEquals(e, INTERFACES_ELEMENT)) {
                        if (interfaces != null) {
                            throw new ComponentDefinitionException("Only one of " + INTERFACE_ATTRIBUTE + " attribute or " + INTERFACES_ELEMENT + " element must be used");
                        }
                        interfaces = parseInterfaceNames(e);
                        factoryMetadata.addProperty("interfaces", createList(context, interfaces));                    
                    } else if (nodeNameEquals(e, SERVICE_PROPERTIES_ELEMENT)) { 
                        MapMetadata map = context.parseElement(MapMetadata.class,
                            factoryMetadata, e);
                        factoryMetadata.addProperty("serviceProperties", map);
                        NodeList enl = e.getChildNodes();
                        for (int j = 0; j < enl.getLength(); j++) {
                            Node enode = enl.item(j);
                            if (enode instanceof Element) {
                                if (isCmNamespace(enode.getNamespaceURI()) && nodeNameEquals(enode, CM_PROPERTIES_ELEMENT)) {
                                    decorateCmProperties(context, (Element) enode, factoryMetadata);
                                }
                            }
                        }
                    } else if (nodeNameEquals(e, REGISTRATION_LISTENER_ELEMENT)) {
                        listeners.add(context.parseElement(RegistrationListener.class,
                            factoryMetadata, e));
                    }
                } else if (isCmNamespace(e.getNamespaceURI())) {
                    if (nodeNameEquals(e, MANAGED_COMPONENT_ELEMENT)) {
                        MutableBeanMetadata managedComponent = context.parseElement(MutableBeanMetadata.class, null, e);
                        generateIdIfNeeded(context, managedComponent);
                        managedComponent.setScope(BeanMetadata.SCOPE_PROTOTYPE);
                        // destroy-method on managed-component has different signature than on regular beans
                        // so we'll handle it differently
                        String destroyMethod = managedComponent.getDestroyMethod();
                        if (destroyMethod != null) {
                            factoryMetadata.addProperty("componentDestroyMethod", createValue(context, destroyMethod));
                            managedComponent.setDestroyMethod(null);
                        }
                        context.getComponentDefinitionRegistry().registerComponentDefinition(managedComponent);
                        factoryMetadata.addProperty("managedComponentName", createIdRef(context, managedComponent.getId()));
                    }
                }
            }
        }

        MutableCollectionMetadata listenerCollection = context.createMetadata(MutableCollectionMetadata.class);
        listenerCollection.setCollectionClass(List.class);
        for (RegistrationListener listener : listeners) {
            MutableBeanMetadata bean = context.createMetadata(MutableBeanMetadata.class);
            bean.setRuntimeClass(ServiceListener.class);
            bean.addProperty("listener", listener.getListenerComponent());
            bean.addProperty("registerMethod", createValue(context, listener.getRegistrationMethod()));
            bean.addProperty("unregisterMethod", createValue(context, listener.getUnregistrationMethod()));
            listenerCollection.addValue(bean);
        }
        factoryMetadata.addProperty("listeners", listenerCollection);
        
        context.getComponentDefinitionRegistry().registerComponentDefinition(factoryMetadata);
        
        MutableBeanMetadata mapMetadata = context.createMetadata(MutableBeanMetadata.class);
        mapMetadata.setScope(BeanMetadata.SCOPE_SINGLETON);
        mapMetadata.setId(id);
        mapMetadata.setFactoryComponent(createRef(context, factoryMetadata.getId()));
        mapMetadata.setFactoryMethod("getServiceMap");
        return mapMetadata;
    }