use of org.jboss.forge.roaster.model.source.JavaClassSource in project herd by FINRAOS.
the class RestControllerProcessor method processRestControllerMethod.
/**
* Processes a method in a REST controller which represents an endpoint, that is, it is annotated with RequestMapping.
*
* @param method the method.
* @param classRequestMapping the parent.
* @param tagName the tag name.
* @param methodSource the method source information.
*
* @throws MojoExecutionException if any errors were encountered.
*/
// CollectionUtils doesn't work with generics.
@SuppressWarnings("unchecked")
private void processRestControllerMethod(Method method, RequestMapping classRequestMapping, String tagName, MethodSource<JavaClassSource> methodSource) throws MojoExecutionException {
log.debug("Processing method \"" + method.getName() + "\".");
// Build a map of each parameter name to its description from the method Javadoc (i.e. all @param and @return values).
Map<String, String> methodParamDescriptions = new HashMap<>();
JavaDocSource<MethodSource<JavaClassSource>> javaDocSource = methodSource.getJavaDoc();
List<JavaDocTag> tags = javaDocSource.getTags();
for (JavaDocTag javaDocTag : tags) {
processJavaDocTag(javaDocTag, methodParamDescriptions);
}
List<String> produces = Collections.emptyList();
List<String> consumes = Collections.emptyList();
List<RequestMethod> requestMethods = Collections.emptyList();
List<String> uris = Collections.emptyList();
// If a class request mapping exists, use it as the default.
if (classRequestMapping != null) {
produces = CollectionUtils.arrayToList(classRequestMapping.produces());
consumes = CollectionUtils.arrayToList(classRequestMapping.consumes());
requestMethods = CollectionUtils.arrayToList(classRequestMapping.method());
uris = CollectionUtils.arrayToList(classRequestMapping.value());
}
// Get the API Operation and see if this endpoint is hidden.
ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
boolean hidden = apiOperation != null && apiOperation.hidden();
// Only process methods that have a RequestMapping annotation.
RequestMapping methodRequestMapping = method.getAnnotation(RequestMapping.class);
if ((methodRequestMapping != null) && (!hidden)) {
log.debug("Method \"" + method.getName() + "\" is a RequestMapping.");
// Override values with method level ones if present.
requestMethods = getClassOrMethodValue(requestMethods, CollectionUtils.arrayToList(methodRequestMapping.method()));
uris = getClassOrMethodValue(uris, CollectionUtils.arrayToList(methodRequestMapping.value()));
produces = getClassOrMethodValue(produces, CollectionUtils.arrayToList(methodRequestMapping.produces()));
consumes = getClassOrMethodValue(consumes, CollectionUtils.arrayToList(methodRequestMapping.consumes()));
// Perform validation.
if (requestMethods.isEmpty()) {
log.warn("No request method defined for method \"" + method.getName() + "\". Skipping...");
return;
}
if (uris.isEmpty()) {
log.warn("No URI defined for method \"" + method.getName() + "\". Skipping...");
return;
}
if (uris.size() > 1) {
log.warn(uris.size() + " URI's found for method \"" + method.getName() + "\". Only processing the first one.");
}
if (requestMethods.size() > 1) {
log.warn(uris.size() + " request methods found for method \"" + method.getName() + "\". Only processing the first one.");
}
String uri = uris.get(0).trim();
Path path = swagger.getPath(uri);
if (path == null) {
path = new Path();
swagger.path(uri, path);
}
// Get the method summary from the ApiOperation annotation or use the method name if the annotation doesn't exist.
String methodSummary = method.getName();
if (apiOperation != null) {
methodSummary = apiOperation.value();
}
Operation operation = new Operation();
operation.tag(tagName);
operation.summary(methodSummary);
if (javaDocSource.getText() != null) {
// Process the method description.
Javadoc javadoc = (Javadoc) javaDocSource.getInternal();
List<TagElement> tagList = javadoc.tags();
StringBuilder stringBuilder = new StringBuilder();
for (TagElement tagElement : tagList) {
// else available (e.g. @link, etc.).
if (tagElement.getTagName() == null) {
processFragments(tagElement.fragments(), stringBuilder);
}
}
// The string builder has the final method text to use.
operation.description(stringBuilder.toString());
setOperationId(tagName, method, operation);
}
if (!produces.isEmpty()) {
operation.setProduces(produces);
}
if (!consumes.isEmpty()) {
operation.setConsumes(consumes);
}
// HTTP method MUST be lower cased
path.set(requestMethods.get(0).name().toLowerCase(), operation);
// names.
for (ParameterSource<JavaClassSource> parameterSource : methodSource.getParameters()) {
processRestMethodParameter(parameterSource, operation, methodParamDescriptions);
}
// Process the return value.
processRestMethodReturnValue(method.getReturnType(), operation, methodParamDescriptions.get("@return"));
} else {
log.debug("Skipping method \"" + method.getName() + "\" because it is either not a RequestMapping or it is hidden.");
}
}
use of org.jboss.forge.roaster.model.source.JavaClassSource in project kie-wb-common by kiegroup.
the class DataModelerServiceImpl method updateJavaSource.
private Pair<String, List<DataModelerError>> updateJavaSource(String originalSource, DataObject dataObject, Map<String, String> renames, List<String> deletions, ClassLoader classLoader) throws Exception {
String newSource;
ClassTypeResolver classTypeResolver;
List<DataModelerError> errors = new ArrayList<DataModelerError>();
if (logger.isDebugEnabled()) {
logger.debug("Starting java source update for class: " + dataObject.getClassName());
}
if (logger.isDebugEnabled()) {
logger.debug("original source is: " + originalSource);
}
JavaType<?> javaType = Roaster.parse(originalSource);
if (javaType.isClass()) {
if (javaType.getSyntaxErrors() != null && !javaType.getSyntaxErrors().isEmpty()) {
// if a file has parsing errors it will be skipped.
errors.addAll(serviceHelper.toDataModelerError(javaType.getSyntaxErrors(), null));
newSource = originalSource;
} else {
JavaClassSource javaClassSource = (JavaClassSource) javaType;
classTypeResolver = DriverUtils.createClassTypeResolver(javaClassSource, classLoader);
updateJavaClassSource(dataObject, javaClassSource, renames, deletions, classTypeResolver);
newSource = javaClassSource.toString();
}
} else {
logger.debug("No Class definition was found for source: " + originalSource + ", original source won't be modified.");
newSource = originalSource;
}
if (logger.isDebugEnabled()) {
logger.debug("updated source is: " + newSource);
}
return new Pair<String, List<DataModelerError>>(newSource, errors);
}
use of org.jboss.forge.roaster.model.source.JavaClassSource in project kie-wb-common by kiegroup.
the class JavaRoasterModelDriver method parseDataObject.
private Pair<DataObject, List<ObjectProperty>> parseDataObject(JavaClassSource javaClassSource) throws ModelDriverException {
String className;
String packageName;
String superClass;
String qualifiedName;
ClassTypeResolver classTypeResolver;
className = javaClassSource.getName();
packageName = javaClassSource.getPackage();
qualifiedName = NamingUtils.createQualifiedName(packageName, className);
if (logger.isDebugEnabled()) {
logger.debug("Building DataObject for, packageName: " + packageName + ", className: " + className);
}
classTypeResolver = DriverUtils.createClassTypeResolver(javaClassSource, classLoader);
Visibility visibility = DriverUtils.buildVisibility(javaClassSource.getVisibility());
DataObject dataObject = new DataObjectImpl(packageName, className, visibility, javaClassSource.isAbstract(), javaClassSource.isFinal());
List<ObjectProperty> unmanagedProperties = new ArrayList<ObjectProperty>();
try {
if (javaClassSource.getSuperType() != null) {
superClass = resolveTypeName(classTypeResolver, javaClassSource.getSuperType());
dataObject.setSuperClassName(superClass);
}
List<AnnotationSource<JavaClassSource>> annotations = javaClassSource.getAnnotations();
if (annotations != null) {
for (AnnotationSource annotation : annotations) {
addJavaClassAnnotation(dataObject, annotation, classTypeResolver);
}
}
List<MethodSource<JavaClassSource>> classMethods = javaClassSource.getMethods();
if (classMethods != null) {
for (MethodSource<JavaClassSource> classMethod : classMethods) {
if (isAccepted(classMethod)) {
addMethod(dataObject, classMethod, classTypeResolver);
}
}
}
List<JavaSource<?>> nestedTypes = javaClassSource.getNestedTypes();
if (nestedTypes != null) {
for (JavaSource nestedType : nestedTypes) {
if (isAccepted(nestedType)) {
if (nestedType instanceof JavaClassSource) {
JavaClassImpl nestedJavaClass = new JavaClassImpl("", nestedType.getName(), DriverUtils.buildVisibility(nestedType.getVisibility()));
dataObject.addNestedClass(nestedJavaClass);
if (javaClassSource.getInterfaces() != null) {
for (String interfaceDefinition : ((JavaClassSource) nestedType).getInterfaces()) {
nestedJavaClass.addInterface(interfaceDefinition);
}
}
List<AnnotationSource<JavaClassSource>> nestedClassAnnotations = nestedType.getAnnotations();
if (nestedClassAnnotations != null) {
for (AnnotationSource annotation : nestedClassAnnotations) {
addJavaClassAnnotation(nestedJavaClass, annotation, classTypeResolver);
}
}
List<MethodSource<JavaClassSource>> nestedClassMethods = ((JavaClassSource) nestedType).getMethods();
if (nestedClassMethods != null) {
for (Method nestedClassMethod : nestedClassMethods) {
if (isAccepted(nestedClassMethod)) {
addMethod(nestedJavaClass, nestedClassMethod, classTypeResolver);
}
}
}
}
}
}
}
List<FieldSource<JavaClassSource>> fields = javaClassSource.getFields();
if (fields != null) {
for (FieldSource<JavaClassSource> field : fields) {
if (DriverUtils.isManagedType(field.getType(), classTypeResolver)) {
addProperty(dataObject, field, classTypeResolver);
} else {
logger.debug("field: " + field + "with fieldName: " + field.getName() + " won't be loaded by the diver because type: " + field.getType().getName() + " isn't a managed type.");
unmanagedProperties.add(new ObjectPropertyImpl(field.getName(), field.getType().toString(), false, DriverUtils.buildVisibility(field.getVisibility()), field.isStatic(), field.isFinal()));
}
}
}
List<Import> imports = javaClassSource.getImports();
if (imports != null) {
for (Import _import : imports) {
dataObject.addImport(new ImportImpl(_import.getQualifiedName()));
}
}
return new Pair<DataObject, List<ObjectProperty>>(dataObject, unmanagedProperties);
} catch (ClassNotFoundException e) {
logger.error(errorMessage(DATA_OBJECT_LOAD_ERROR, qualifiedName), e);
throw new ModelDriverException(errorMessage(DATA_OBJECT_LOAD_ERROR, qualifiedName), e);
} catch (ModelDriverException e) {
logger.error(errorMessage(DATA_OBJECT_LOAD_ERROR, qualifiedName), e);
throw new ModelDriverException(errorMessage(DATA_OBJECT_LOAD_ERROR, qualifiedName), e);
}
}
use of org.jboss.forge.roaster.model.source.JavaClassSource in project kie-wb-common by kiegroup.
the class JavaRoasterModelDriver method updateField.
public void updateField(JavaClassSource javaClassSource, String fieldName, ObjectProperty property, ClassTypeResolver classTypeResolver) throws Exception {
GenerationTools genTools = new GenerationTools();
GenerationEngine engine = GenerationEngine.getInstance();
GenerationContext context = new GenerationContext(null);
boolean updateAccessors = false;
FieldSource<JavaClassSource> field;
field = javaClassSource.getField(fieldName);
Type oldType = field.getType();
if (hasChangedToCollectionType(field, property, classTypeResolver)) {
// fields that changed to a collection like java.util.List<SomeEntity>
// needs to be removed and created again due to Roaster. Ideally it shouldn't be so.
updateCollectionField(javaClassSource, fieldName, property, classTypeResolver);
} else {
if (!fieldName.equals(property.getName())) {
field.setName(property.getName());
// the field was renamed, accessors must be updated.
updateAccessors = true;
}
if (DriverUtils.isManagedType(field.getType(), classTypeResolver) && !DriverUtils.equalsType(field.getType(), property.getClassName(), property.isMultiple(), property.getBag(), classTypeResolver)) {
// the has type changed, and not to a collection type.
String newClassName = property.getClassName();
field.setType(newClassName);
if (field.getLiteralInitializer() != null) {
// valid for the new type.
if (NamingUtils.isPrimitiveTypeId(newClassName)) {
setPrimitiveTypeDefaultInitializer(field, newClassName);
} else {
field.setLiteralInitializer(null);
}
}
updateAccessors = true;
}
updateAnnotations(field, property.getAnnotations(), classTypeResolver);
if (updateAccessors) {
String accessorName;
String methodSource;
String oldClassName;
// remove old accessors
// TODO check primitive types
Class<?> oldClass = classTypeResolver.resolveType(oldType.getName());
oldClassName = oldClass.getName();
accessorName = genTools.toJavaGetter(fieldName, oldClassName);
removeMethodByParamsClass(javaClassSource, accessorName);
accessorName = genTools.toJavaSetter(fieldName);
removeMethodByParamsClass(javaClassSource, accessorName, oldClass);
// and generate the new ones
methodSource = genTools.indent(engine.generateFieldGetterString(context, property));
javaClassSource.addMethod(methodSource);
methodSource = genTools.indent(engine.generateFieldSetterString(context, property));
javaClassSource.addMethod(methodSource);
}
}
}
use of org.jboss.forge.roaster.model.source.JavaClassSource in project kie-wb-common by kiegroup.
the class JavaRoasterModelDriver method loadModel.
@Override
public ModelDriverResult loadModel() throws ModelDriverException {
ModelDriverResult result = new ModelDriverResult();
DataModel dataModel;
String fileContent;
dataModel = createModel();
result.setDataModel(dataModel);
List<Path> rootPaths = new ArrayList<Path>();
rootPaths.add(javaRootPath);
Collection<FileUtils.ScanResult> scanResults = FileUtils.getInstance().scan(ioService, rootPaths, ".java", true);
if (scanResults != null) {
for (FileUtils.ScanResult scanResult : scanResults) {
logger.debug("Starting file loading into model, file: " + scanResult.getFile());
fileContent = ioService.readAllString(scanResult.getFile());
if (fileContent == null || "".equals(fileContent)) {
logger.debug("file: " + scanResult.getFile() + " is empty.");
result.addError(new DriverError("File has no content", Paths.convert(scanResult.getFile())));
continue;
}
try {
JavaType<?> javaType = Roaster.parse(fileContent);
final boolean isManaged = isManagedJavaType(javaType);
final boolean vetoed = (isManaged ? isVetoed(javaType) : false);
if (isManaged && !vetoed) {
if (javaType.getSyntaxErrors() != null && !javaType.getSyntaxErrors().isEmpty()) {
// if a file has parsing errors it will be skipped.
addSyntaxErrors(result, scanResult.getFile(), javaType.getSyntaxErrors());
} else if (javaType.isEnum()) {
loadFromJavaEnum((JavaEnumSource) javaType, scanResult.getFile(), dataModel, result);
} else {
loadFromJavaClass((JavaClassSource) javaType, scanResult.getFile(), dataModel, result);
}
} else if (vetoed) {
logger.debug("The class, {}, in the file, {}, was vetoed and will be skipped.", javaType.getQualifiedName(), scanResult.getFile());
} else {
logger.debug("File: " + scanResult.getFile() + " do not contain a managed java type, it will be skipped.");
}
} catch (ParserException e) {
result.addError(new DriverError(e.getMessage(), Paths.convert(scanResult.getFile())));
} catch (Exception e) {
// Unexpected error.
logger.error(errorMessage(MODEL_LOAD_GENERIC_ERROR, javaRootPath.toUri()), e);
throw new ModelDriverException(errorMessage(MODEL_LOAD_GENERIC_ERROR, javaRootPath.toUri()), e);
}
}
}
return result;
}
Aggregations