diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/util/AnnotationUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/util/AnnotationUtil.java index 621de443721..8941ad03125 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/util/AnnotationUtil.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/util/AnnotationUtil.java @@ -35,6 +35,9 @@ import javax.ws.rs.HttpMethod; import javax.ws.rs.OPTIONS; import javax.ws.rs.POST; import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; @@ -61,7 +64,8 @@ public class AnnotationUtil { private static final String PACKAGE_ORG_SPRINGFRAMEWORK = "org.springframework"; public static final String STRING_ARR = "string_arr"; public static final String STRING = "string"; - private Class featureClazz; + private Class + featureAnnotationClazz; private ClassLoader classLoader; private ServletContext servletContext; @@ -108,7 +112,7 @@ public class AnnotationUtil { if (deviceTypeAnno != null) { Method[] deviceTypeMethod = deviceTypeClazz.getMethods(); String deviceType = invokeMethod(deviceTypeMethod[0], deviceTypeAnno, STRING); - featureClazz = + featureAnnotationClazz = (Class) classLoader.loadClass( org.wso2.carbon.device.mgt.extensions.feature.mgt @@ -130,80 +134,120 @@ public class AnnotationUtil { return features; } - private List getFeatures(Method[] annotatedMethods) throws Throwable { + private List getFeatures(Method[] methodsList) throws Throwable { List featureList = new ArrayList<>(); - for (Method method : annotatedMethods) { - Annotation methodAnnotation = method.getAnnotation(featureClazz); - if (methodAnnotation != null) { - Annotation[] annotations = method.getDeclaredAnnotations(); + for (Method currentMethod : methodsList) { + Annotation featureAnnotation = currentMethod.getAnnotation(featureAnnotationClazz); + if (featureAnnotation != null) { + Feature feature = new Feature(); + feature = processFeatureAnnotation(feature, currentMethod); + Annotation[] annotations = currentMethod.getDeclaredAnnotations(); + Feature.MetadataEntry metadataEntry = new Feature.MetadataEntry(); + metadataEntry.setId(-1); + Map apiParams = new HashMap<>(); for (int i = 0; i < annotations.length; i++) { - if (annotations[i].annotationType().getName().equals( - org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature.class.getName())) { - Feature feature = new Feature(); - Method[] featureAnnoMethods = featureClazz.getMethods(); - Annotation featureAnno = method.getAnnotation(featureClazz); - - for (int k = 0; k < featureAnnoMethods.length; k++) { - switch (featureAnnoMethods[k].getName()) { - case "name": - feature.setName(invokeMethod(featureAnnoMethods[k], featureAnno, STRING)); - break; - case "code": - feature.setCode(invokeMethod(featureAnnoMethods[k], featureAnno, STRING)); - break; - case "description": - feature.setDescription(invokeMethod(featureAnnoMethods[k], featureAnno, STRING)); - break; - case "type": - feature.setType(invokeMethod(featureAnnoMethods[k], featureAnno, STRING)); - break; - } - } - //Extracting method with which feature is exposed - if (annotations[i].annotationType().getName().equals(GET.class.getName())) { - feature.setMethod(HttpMethod.GET); - } - if (annotations[i].annotationType().getName().equals(POST.class.getName())) { - feature.setMethod(HttpMethod.POST); - } - if (annotations[i].annotationType().getName().equals(OPTIONS.class.getName())) { - feature.setMethod(HttpMethod.OPTIONS); - } - if (annotations[i].annotationType().getName().equals(DELETE.class.getName())) { - feature.setMethod(HttpMethod.DELETE); - } - if (annotations[i].annotationType().getName().equals(PUT.class.getName())) { - feature.setMethod(HttpMethod.PUT); - } - try { - Class formParamClazz = (Class) classLoader.loadClass( - FormParam.class.getName()); - Method[] formMethods = formParamClazz.getMethods(); - //Extract method parameter information and store same as feature meta info - List metaInfoList = new ArrayList<>(); - Annotation[][] paramAnnotations = method.getParameterAnnotations(); - for (int j = 0; j < paramAnnotations.length; j++) { - for (Annotation anno : paramAnnotations[j]) { - if (anno.annotationType().getName().equals(FormParam.class.getName())) { - Feature.MetadataEntry metadataEntry = new Feature.MetadataEntry(); - metadataEntry.setId(j); - metadataEntry.setValue(invokeMethod(formMethods[0], anno, STRING)); - metaInfoList.add(metadataEntry); - } - } - } - feature.setMetadataEntries(metaInfoList); - } catch (ClassNotFoundException e) { - log.debug("No Form Param found for class " + featureClazz.getName()); - } - featureList.add(feature); + Annotation currentAnnotation = annotations[i]; + feature = processHttpMethodAnnotation(feature, currentAnnotation); + if (currentAnnotation.annotationType().getName().equals(Path.class.getName())) { + String uri = getPathAnnotationValue(currentMethod); + apiParams.put("uri", uri); } + apiParams = processParamAnnotations(apiParams, currentMethod); } + metadataEntry.setValue(apiParams); + List metaInfoList = new ArrayList<>(); + metaInfoList.add(metadataEntry); + feature.setMetadataEntries(metaInfoList); + featureList.add(feature); } } return featureList; } + private Map processParamAnnotations(Map apiParams, Method currentMethod) throws Throwable{ + try { + apiParams.put("pathParams", processParamAnnotations(currentMethod, PathParam.class)); + apiParams.put("queryParams", processParamAnnotations(currentMethod, QueryParam.class)); + apiParams.put("formParams", processParamAnnotations(currentMethod, FormParam.class)); + } catch (ClassNotFoundException e) { + log.debug("No Form Param found for class " + featureAnnotationClazz.getName()); + } + return apiParams; + } + + private List processParamAnnotations(Method currentMethod, Class clazz) throws Throwable{ + List params = new ArrayList<>(); + try { + Class paramClazz = (Class) classLoader.loadClass(clazz.getName()); + Method[] formMethods = paramClazz.getMethods(); + //Extract method parameter information and store same as feature meta info + Annotation[][] paramAnnotations = currentMethod.getParameterAnnotations(); + Method valueMethod = formMethods[0]; + for (int j = 0; j < paramAnnotations.length; j++) { + for (Annotation anno : paramAnnotations[j]) { + if (anno.annotationType().getName().equals(clazz.getName())) { + params.add(invokeMethod(valueMethod, anno, STRING)); + } + } + } + } catch (ClassNotFoundException e) { + log.debug("No "+ clazz.getName() +" Param found for class " + featureAnnotationClazz.getName()); + } + return params; + } + + private Feature processHttpMethodAnnotation(Feature feature, Annotation currentAnnotation) { + //Extracting method with which feature is exposed + if (currentAnnotation.annotationType().getName().equals(GET.class.getName())) { + feature.setMethod(HttpMethod.GET); + } else if (currentAnnotation.annotationType().getName().equals(POST.class.getName())) { + feature.setMethod(HttpMethod.POST); + } else if (currentAnnotation.annotationType().getName().equals(OPTIONS.class.getName())) { + feature.setMethod(HttpMethod.OPTIONS); + } else if (currentAnnotation.annotationType().getName().equals(DELETE.class.getName())) { + feature.setMethod(HttpMethod.DELETE); + } else if (currentAnnotation.annotationType().getName().equals(PUT.class.getName())) { + feature.setMethod(HttpMethod.PUT); + } + return feature; + } + + private Feature processFeatureAnnotation(Feature feature, Method currentMethod) throws Throwable{ + Method[] featureAnnoMethods = featureAnnotationClazz.getMethods(); + Annotation featureAnno = currentMethod.getAnnotation(featureAnnotationClazz); + for (int k = 0; k < featureAnnoMethods.length; k++) { + switch (featureAnnoMethods[k].getName()) { + case "name": + feature.setName(invokeMethod(featureAnnoMethods[k], featureAnno, STRING)); + break; + case "code": + feature.setCode(invokeMethod(featureAnnoMethods[k], featureAnno, STRING)); + break; + case "description": + feature.setDescription(invokeMethod(featureAnnoMethods[k], featureAnno, STRING)); + break; + case "type": + feature.setType(invokeMethod(featureAnnoMethods[k], featureAnno, STRING)); + break; + } + } + return feature; + } + + public String getPathAnnotationValue(Method currentMethod) throws Throwable{ + String uri = ""; + try { + Class pathClazz = (Class) classLoader.loadClass(Path.class.getName()); + Annotation pathAnnno = currentMethod.getAnnotation(pathClazz); + Method[] pathMethods = pathClazz.getMethods(); + Method valueMethod = pathMethods[0]; + uri = invokeMethod(valueMethod, pathAnnno, STRING); + } catch (ClassNotFoundException e) { + log.debug("No Path Param found for class " + featureAnnotationClazz.getName()); + } + return uri; + } + /** * When an annotation and method is passed, this method invokes that executes said method against the annotation */