2 * Copyright (c) 2013, 2017 Cisco 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.config.manager.impl.dynamicmbean;
10 import java.lang.reflect.Method;
11 import java.util.HashSet;
12 import java.util.List;
14 import javax.annotation.Nullable;
15 import javax.annotation.concurrent.Immutable;
16 import javax.management.MBeanAttributeInfo;
17 import javax.management.ObjectName;
18 import org.opendaylight.controller.config.api.annotations.Description;
19 import org.opendaylight.controller.config.api.annotations.RequireInterface;
22 class AttributeHolder {
24 private final String name;
25 private final String description;
26 private final Object object;
27 private final boolean writable;
30 private final RequireInterface requireInterfaceAnnotation;
31 private final String attributeType;
33 protected static final Set<Class<?>> PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER = new HashSet<>();
36 PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.add(ObjectName.class);
37 PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.add(ObjectName[].class);
38 PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.add(List.class);
41 AttributeHolder(final String name, final Object object, final String returnType, final boolean writable,
42 @Nullable final RequireInterface requireInterfaceAnnotation, final String description) {
44 throw new NullPointerException();
48 throw new NullPointerException();
51 this.writable = writable;
52 this.requireInterfaceAnnotation = requireInterfaceAnnotation;
53 this.attributeType = returnType;
54 this.description = description;
57 public MBeanAttributeInfo toMBeanAttributeInfo() {
58 return new MBeanAttributeInfo(name, attributeType, description, true, true, false);
64 * @return annotation if setter sets ObjectName or ObjectName[], and is
65 * annotated. Return null otherwise.
67 RequireInterface getRequireInterfaceOrNull() {
68 return requireInterfaceAnnotation;
71 public String getName() {
75 public Object getObject() {
79 public String getAttributeType() {
83 public boolean isWritable() {
87 public String getDescription() {
92 * Find @Description annotations in method class and all its exported
95 * @param setter setter method
96 * @param jmxInterfaces JMX interfaces
97 * @return empty string if no annotation is found, or list of descriptions
98 * separated by newline
100 static String findDescription(final Method setter, final Set<Class<?>> jmxInterfaces) {
101 List<Description> descriptions = AnnotationsHelper.findMethodAnnotationInSuperClassesAndIfcs(setter,
102 Description.class, jmxInterfaces);
103 return AnnotationsHelper.aggregateDescriptions(descriptions);
107 * Find @RequireInterface annotation by searching method class and all exported
110 * @param setter setter method
111 * @param inspectedInterfaces interfaces
112 * @return null if no annotation is found, otherwise return the annotation
113 * @throws IllegalStateException
114 * if more than one value is specified by found annotations
115 * @throws IllegalArgumentException
116 * if set of exported interfaces contains non interface type
118 static RequireInterface findRequireInterfaceAnnotation(final Method setter,
119 final Set<Class<?>> inspectedInterfaces) {
121 // only allow setX(ObjectName y) or setX(ObjectName[] y) or
122 // setX(List<ObjectName> y) to continue
124 if (setter.getParameterTypes().length > 1
125 || !PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.contains(setter.getParameterTypes()[0])) {
129 List<RequireInterface> foundRequireInterfaces = AnnotationsHelper
130 .findMethodAnnotationInSuperClassesAndIfcs(setter, RequireInterface.class, inspectedInterfaces);
131 // make sure the list if not empty contains always annotation with same
133 Set<Class<?>> foundValues = new HashSet<>();
134 for (RequireInterface ri : foundRequireInterfaces) {
135 foundValues.add(ri.value());
137 if (foundValues.isEmpty()) {
139 } else if (foundValues.size() > 1) {
140 throw new IllegalStateException(
141 "Error finding @RequireInterface. " + "More than one value specified as required interface "
142 + foundValues + " of " + setter + " of " + setter.getDeclaringClass());
144 return foundRequireInterfaces.get(0);