2 * Copyright (c) 2016 Brocade Communications Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.blueprint.ext;
11 import java.util.Collections;
13 import org.apache.aries.blueprint.ComponentDefinitionRegistry;
14 import org.apache.aries.blueprint.NamespaceHandler;
15 import org.apache.aries.blueprint.ParserContext;
16 import org.apache.aries.blueprint.mutable.MutableBeanMetadata;
17 import org.apache.aries.blueprint.mutable.MutableRefMetadata;
18 import org.apache.aries.blueprint.mutable.MutableReferenceMetadata;
19 import org.apache.aries.blueprint.mutable.MutableValueMetadata;
20 import org.opendaylight.controller.blueprint.BlueprintContainerRestartService;
21 import org.osgi.service.blueprint.container.ComponentDefinitionException;
22 import org.osgi.service.blueprint.reflect.BeanMetadata;
23 import org.osgi.service.blueprint.reflect.ComponentMetadata;
24 import org.osgi.service.blueprint.reflect.Metadata;
25 import org.osgi.service.blueprint.reflect.RefMetadata;
26 import org.osgi.service.blueprint.reflect.ReferenceMetadata;
27 import org.osgi.service.blueprint.reflect.ValueMetadata;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30 import org.w3c.dom.Attr;
31 import org.w3c.dom.Element;
32 import org.w3c.dom.Node;
35 * The NamespaceHandler for Opendaylight blueprint extensions.
37 * @author Thomas Pantelis
39 public class OpendaylightNamespaceHandler implements NamespaceHandler {
40 public static final String NAMESPACE_1_0_0 = "http://opendaylight.org/xmlns/blueprint/v1.0.0";
42 private static final Logger LOG = LoggerFactory.getLogger(OpendaylightNamespaceHandler.class);
43 private static final String COMPONENT_PROCESSOR_NAME = ComponentProcessor.class.getName();
44 private static final String RESTART_DEPENDENTS_ON_UPDATES = "restart-dependents-on-updates";
46 @SuppressWarnings("rawtypes")
48 public Set<Class> getManagedClasses() {
49 return Collections.emptySet();
53 public URL getSchemaLocation(String namespace) {
54 if(NAMESPACE_1_0_0.equals(namespace)) {
55 URL url = getClass().getResource("/opendaylight-blueprint-ext-1.0.0.xsd");
56 LOG.debug("getSchemaLocation for {} returning URL {}", namespace, url);
64 public Metadata parse(Element element, ParserContext context) {
65 LOG.debug("In parse for {}", element);
66 throw new ComponentDefinitionException("Unsupported standalone element: " + element.getNodeName());
70 public ComponentMetadata decorate(Node node, ComponentMetadata component, ParserContext context) {
71 if(node instanceof Attr) {
72 if (nodeNameEquals(node, RESTART_DEPENDENTS_ON_UPDATES)) {
73 return decorateRestartDependentsOnUpdates((Attr)node, component, context);
76 throw new ComponentDefinitionException("Unsupported attribute: " + node.getNodeName());
78 throw new ComponentDefinitionException("Unsupported node type: " + node);
82 private static ComponentMetadata decorateRestartDependentsOnUpdates(Attr attr, ComponentMetadata component,
83 ParserContext context) {
84 if(component != null) {
85 throw new ComponentDefinitionException("Attribute " + attr.getNodeName() +
86 " can only be used on the root <blueprint> element");
89 LOG.debug("decorateRestartDependentsOnUpdates: {}", attr.getValue());
91 if(!Boolean.TRUE.equals(Boolean.valueOf(attr.getValue()))) {
95 MutableBeanMetadata metadata = registerComponentProcessor(context);
96 metadata.addProperty("restartDependentsOnUpdates", createValue(context, "true"));
101 private static MutableBeanMetadata registerComponentProcessor(ParserContext context) {
102 ComponentDefinitionRegistry registry = context.getComponentDefinitionRegistry();
103 MutableBeanMetadata metadata = (MutableBeanMetadata) registry.getComponentDefinition(COMPONENT_PROCESSOR_NAME);
104 if(metadata == null) {
105 metadata = context.createMetadata(MutableBeanMetadata.class);
106 metadata.setProcessor(true);
107 metadata.setId(COMPONENT_PROCESSOR_NAME);
108 metadata.setActivation(BeanMetadata.ACTIVATION_EAGER);
109 metadata.setScope(BeanMetadata.SCOPE_SINGLETON);
110 metadata.setRuntimeClass(ComponentProcessor.class);
111 metadata.setDestroyMethod("destroy");
112 metadata.addProperty("bundle", createRef(context, "blueprintBundle"));
113 metadata.addProperty("blueprintContainerRestartService", createServiceRef(context,
114 BlueprintContainerRestartService.class, null));
116 LOG.debug("Registering ComponentProcessor bean: {}", metadata);
118 registry.registerComponentDefinition(metadata);
124 private static ValueMetadata createValue(ParserContext context, String value) {
125 MutableValueMetadata m = context.createMetadata(MutableValueMetadata.class);
126 m.setStringValue(value);
130 private static MutableReferenceMetadata createServiceRef(ParserContext context, Class<?> cls, String filter) {
131 MutableReferenceMetadata m = context.createMetadata(MutableReferenceMetadata.class);
132 m.setRuntimeInterface(cls);
133 m.setInterface(cls.getName());
134 m.setActivation(ReferenceMetadata.ACTIVATION_EAGER);
135 m.setAvailability(ReferenceMetadata.AVAILABILITY_MANDATORY);
144 private static RefMetadata createRef(ParserContext context, String value) {
145 MutableRefMetadata metadata = context.createMetadata(MutableRefMetadata.class);
146 metadata.setComponentId(value);
150 private static boolean nodeNameEquals(Node node, String name) {
151 return name.equals(node.getNodeName()) || name.equals(node.getLocalName());