
de.fraunhofer.iese.ind2uce.registry.InterfaceDescriptionDiscovery Maven / Gradle / Ivy
/*-
* =================================LICENSE_START=================================
* IND2UCE
* %%
* Copyright (C) 2016 Fraunhofer IESE (www.iese.fraunhofer.de)
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =================================LICENSE_END=================================
*/
package de.fraunhofer.iese.ind2uce.registry;
import de.fraunhofer.iese.ind2uce.api.component.description.InputParameterDescription;
import de.fraunhofer.iese.ind2uce.api.component.description.MethodInterfaceDescription;
import de.fraunhofer.iese.ind2uce.api.component.identifier.EnforcementScopeId;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Generates a List of {@link MethodInterfaceDescription} by introspecting a
* class.
* Therefor the discovery lists all methods that is annotated with an Annotation
* of Type {@link ActionDescription} and creates an instance of
* {@link MethodInterfaceDescription} with the information provided by the
* MethodSignature, the annotation and the {@link ActionParameterDescription}
* annotations of each method parameter.
* For Example The Method
*
*
*
*
* {@literal @}ActionDescription(description = "Retreives the authority (role) of an user")
* public String getAuthority(@ActionParameterDescription(name = "username", description = "The user the authority should be evaluated for.", mandatory = true) String username) {
* }
*
*
* Results in an InterfaceDescription with:
*
* - name = getAuthority
* - description = Retreives the authority (role) of an user
* - parameter =
*
* - InputParameterDescription: name = username, description = The user the
* authority should be evaluated for, mandatory = true
*
*
*
*/
class InterfaceDescriptionDiscovery {
/**
* Compose interface description.
*
* @param method the method
* @param prefix the prefix
* @param actionDescription the action description
* @param name the name
* @return the interface description
*/
protected MethodInterfaceDescription composeInterfaceDescription(Method method, String prefix, ActionDescription actionDescription, String name) {
return new MethodInterfaceDescription(prefix + ":" + name, method.getReturnType(), actionDescription.description(), this.readParameter(method));
}
/**
* Creates the input parameter description.
*
* @param parameterType the parameter type
* @param annotations the annotations
* @param index the index
* @return the input parameter description
*/
private InputParameterDescription createInputParameterDescription(Class parameterType, Annotation[] annotations, int index) {
final ActionParameterDescription annotation = this.getParameterDescriptionAnnotation(annotations);
if (annotation != null) {
final String parameterName = annotation.name();
final String description = annotation.description();
parameterType = annotation.type().equals(Void.class) ? parameterType : annotation.type();
return new InputParameterDescription(parameterName, description, annotation.pattern(), annotation.mandatory(), parameterType);
}
if (this.isActionParameterDescriptionNecessary(parameterType, index)) {
throw new IllegalStateException("Not all parameters are documented.");
} else {
return null;
}
}
/**
* Creates the interface description from service method.
*
* @param service the service
* @param method the method
* @param prefix the prefix
* @return the map< interface description,? extends pair< method, object>>
*/
protected Map> createInterfaceDescriptionFromServiceMethod(Object service, Method method, String prefix) {
final ActionDescription actionDescription = method.getAnnotation(ActionDescription.class);
final String name = this.readName(method, actionDescription);
this.readParameter(method);
return Collections.singletonMap(this.composeInterfaceDescription(method, prefix, actionDescription, name), new ImmutablePair<>(method, service));
}
/**
* Discover.
*
* @param service the service
* @param type the type
* @param enforcementScopeId the enforcement scope id
* @return the map
*/
Map> discover(Object service, ComponentType type, EnforcementScopeId enforcementScopeId) {
final String enforcementScope = this.getEnforcementScopeId(enforcementScopeId);
final Map> toReturn = new HashMap<>();
for (final Method method : service.getClass().getMethods()) {
if (this.isServiceMethod(method)) {
toReturn.putAll(this.createInterfaceDescriptionFromServiceMethod(service, method, type.getPrefixForInterfaceDescription() + enforcementScope));
}
}
return toReturn;
}
/**
* Gets the enforcement scope id.
*
* @param enforcementScopeId the enforcement scope id
* @return the enforcement scope id
*/
private String getEnforcementScopeId(EnforcementScopeId enforcementScopeId) {
return enforcementScopeId.getIdentifier();
}
/**
* Gets the parameter description annotation.
*
* @param annotations the annotations
* @return the parameter description annotation
*/
private ActionParameterDescription getParameterDescriptionAnnotation(Annotation[] annotations) {
for (final Annotation annotation : annotations) {
if (annotation instanceof ActionParameterDescription) {
return (ActionParameterDescription)annotation;
}
}
return null;
}
/**
* Checks if is action parameter description necessary.
*
* @param parameterType the parameter type
* @param index the index
* @return true, if is action parameter description necessary
*/
protected boolean isActionParameterDescriptionNecessary(Class parameterType, int index) {
return true;
}
/**
* Checks if is service method.
*
* @param method the method
* @return true, if is service method
*/
protected boolean isServiceMethod(Method method) {
return method.isAnnotationPresent(ActionDescription.class);
}
/**
* Read name.
*
* @param method the method
* @param actionDescription the action description
* @return the string
*/
private String readName(Method method, ActionDescription actionDescription) {
return StringUtils.isNotBlank(actionDescription.methodName()) ? actionDescription.methodName() : method.getName();
}
/**
* Read parameter.
*
* @param method the method
* @return the list
*/
private List readParameter(Method method) {
// 1.8 nötig
final Class>[] parameters = method.getParameterTypes();
final Annotation[][] parameterAnnotations = method.getParameterAnnotations();
final List toReturn = new ArrayList<>(parameters.length);
for (int i = 0; i < parameters.length; i++) {
final InputParameterDescription inputParameterDescription = this.createInputParameterDescription(parameters[i], parameterAnnotations[i], i);
if (inputParameterDescription != null) {
toReturn.add(inputParameterDescription);
}
}
return toReturn;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy