Java tutorial
/** * Copyright (C) 2010-2018 Structr GmbH * * This file is part of Structr <http://structr.org>. * * Structr is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * Structr is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Structr. If not, see <http://www.gnu.org/licenses/>. */ package org.structr.javaparser; import com.github.javaparser.JavaParser; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.PackageDeclaration; import com.github.javaparser.ast.body.BodyDeclaration; import com.github.javaparser.ast.body.CallableDeclaration; import com.github.javaparser.ast.body.ConstructorDeclaration; import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.body.TypeDeclaration; import com.github.javaparser.ast.nodeTypes.NodeWithModifiers; import com.github.javaparser.ast.nodeTypes.NodeWithOptionalBlockStmt; import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName; import com.github.javaparser.ast.stmt.BlockStmt; import com.github.javaparser.ast.type.Type; import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver; import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver; import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.structr.api.service.LicenseManager; import org.structr.common.SecurityContext; import org.structr.common.error.FrameworkException; import org.structr.core.GraphObject; import org.structr.core.app.App; import org.structr.core.app.StructrApp; import org.structr.core.entity.AbstractSchemaNode; import org.structr.core.function.Functions; import org.structr.core.property.PropertyMap; import org.structr.javaparser.entity.AddJarsToIndexFunction; import org.structr.javaparser.entity.ClassOrInterface; import org.structr.javaparser.entity.JavaInterface; import org.structr.javaparser.entity.JavaClass; import org.structr.javaparser.entity.Method; import org.structr.javaparser.entity.Module; import org.structr.javaparser.entity.Package; import org.structr.module.StructrModule; import org.structr.schema.action.Actions; import org.structr.web.entity.File; import org.structr.web.entity.Folder; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * */ public class JavaParserModule implements StructrModule { protected static final Logger logger = LoggerFactory.getLogger(JavaParserModule.class.getName()); private final StructrJavaTypeSolver structrTypeSolver; private JavaParserFacade facade; private App app; private boolean ignoreTests = true; public JavaParserModule() { structrTypeSolver = StructrJavaTypeSolver.getInstance(); } public JavaParserModule(final App app) { this.app = app; structrTypeSolver = StructrJavaTypeSolver.getInstance(); } @Override public void onLoad(final LicenseManager licenseManager) { // final boolean basicEdition = licenseManager == null || licenseManager.isEdition(LicenseManager.Basic); // final boolean smallBusinessEdition = licenseManager == null || licenseManager.isEdition(LicenseManager.SmallBusiness); final boolean enterpriseEdition = licenseManager == null || licenseManager.isEdition(LicenseManager.Enterprise); // Enterprise only Functions.put(enterpriseEdition, LicenseManager.Enterprise, "index_source_tree", new IndexSourceTreeFunction()); Functions.put(enterpriseEdition, LicenseManager.Enterprise, "parse_source_tree", new ParseSourceTreeFunction()); Functions.put(enterpriseEdition, LicenseManager.Enterprise, "analyze_source_tree", new AnalyzeSourceTreeFunction()); Functions.put(enterpriseEdition, LicenseManager.Enterprise, "parse_java", new ParseJavaFunction()); Functions.put(enterpriseEdition, LicenseManager.Enterprise, "analyze_java", new AnalyzeJavaFunction()); Functions.put(enterpriseEdition, LicenseManager.Enterprise, "add_jars_to_index", new AddJarsToIndexFunction()); } /** * Create an index containing all compilation units of Java files from * the source tree under the given root folder. * * @param rootFolder */ public void indexSourceTree(final Folder rootFolder) { logger.info("Starting indexing of source tree " + rootFolder.getPath()); final SecurityContext securityContext = rootFolder.getSecurityContext(); app = StructrApp.getInstance(securityContext); structrTypeSolver.parseRoot(rootFolder); final CombinedTypeSolver typeSolver = new CombinedTypeSolver(); typeSolver.add(new ReflectionTypeSolver()); typeSolver.add(structrTypeSolver); facade = JavaParserFacade.get(typeSolver); logger.info("Done with indexing of source tree " + rootFolder.getPath()); } /** * Add compilation units of all jar files found in the given folder to the index. * * @param folderPath */ public void addJarsToIndex(final String folderPath) { logger.info("Starting adding jar files in " + folderPath); final CombinedTypeSolver typeSolver = new CombinedTypeSolver(); typeSolver.add(new ReflectionTypeSolver()); final AtomicLong count = new AtomicLong(0); try { Files.newDirectoryStream(Paths.get(folderPath), path -> path.toString().endsWith(".jar")) .forEach((file) -> { try { typeSolver.add(new JarTypeSolver(new FileInputStream(file.toFile()))); count.addAndGet(1L); } catch (IOException ex) { } }); } catch (IOException ex) { } logger.info("Added " + count.toString() + " jar files to the type solver"); typeSolver.add(structrTypeSolver); facade = JavaParserFacade.get(typeSolver); logger.info("Done with adding jar files in " + folderPath); } /** * Analyze the source tree under the given root folder. * * @param rootFolder */ public void analyzeSourceTree(final Folder rootFolder) { logger.info("Starting analysis of source tree " + rootFolder.getPath()); final SecurityContext securityContext = rootFolder.getSecurityContext(); app = StructrApp.getInstance(securityContext); final CombinedTypeSolver typeSolver = new CombinedTypeSolver(); typeSolver.add(new ReflectionTypeSolver()); typeSolver.add(structrTypeSolver); facade = JavaParserFacade.get(typeSolver); analyzeFolder(rootFolder, 0, null); logger.info("Done with analysis of source tree " + rootFolder.getPath()); } /** * Parse the source tree under the given root folder. * * @param rootFolder */ public void parseSourceTree(final Folder rootFolder) { logger.info("Starting parsing of source tree " + rootFolder.getPath()); final SecurityContext securityContext = rootFolder.getSecurityContext(); app = StructrApp.getInstance(securityContext); final CombinedTypeSolver typeSolver = new CombinedTypeSolver(); typeSolver.add(new ReflectionTypeSolver()); typeSolver.add(structrTypeSolver); facade = JavaParserFacade.get(typeSolver); parseFolder(rootFolder, 0, null); logger.info("Done with parsing of source tree " + rootFolder.getPath()); } public JsonResult parse(final String javaCode) { return toJson(JavaParser.parse(javaCode)); } public JsonResult parse(final InputStream javaCode) { return toJson(JavaParser.parse(javaCode)); } /** * Get or create on object with given properties. * * Try to find an object of given type matching all of the given identifying properties. * If none found, create one with all given properties. * * @param type * @param identifyingProperties * @param allProperties * @return */ private GraphObject getOrCreate(final Class type, final PropertyMap identifyingProperties, final PropertyMap allProperties) { try { final GraphObject obj = app.nodeQuery(type).disableSorting().pageSize(1).and(identifyingProperties) .getFirst(); if (obj != null) { // return existing object return obj; } // create new object return app.create(type, allProperties); } catch (FrameworkException ex) { logger.error("Unable to create new graph object", type, allProperties, ex); } return null; } private Module createModule(final String moduleName, final Folder moduleFolder) { final PropertyMap identifyingProperties = new PropertyMap(); identifyingProperties.put(Module.name, moduleName); final PropertyMap allProperties = new PropertyMap(); allProperties.putAll(identifyingProperties); allProperties.put(Module.folder, moduleFolder); return (Module) getOrCreate(Module.class, identifyingProperties, allProperties); } private void parseFolder(final Folder folder, final int depth, final Folder parentFolder) { logger.info("Parsing folder " + folder.getName() + ", depth " + depth); // Handle folder itself readPomAndPackageInfoFile(folder, parentFolder); // Handle all direct file children of this folder parseJavaFilesAndSolveTypes(folder); // Handle subfolders of this folder for (final Folder subfolder : folder.getFolders()) { parseFolder(subfolder, depth + 1, folder); } } private void analyzeFolder(final Folder folder, final int depth, final Folder parentFolder) { logger.info("Analyzing folder " + folder.getName() + ", depth " + depth); // Handle folder itself //handleAnalyzeFolder(folder, parentFolder); // Handle all direct file children of this folder analyzeMethodsInJavaFiles(folder); // Handle subfolders of this folder folder.getFolders().forEach((final Folder subfolder) -> { analyzeFolder(subfolder, depth + 1, folder); }); } private void readPomAndPackageInfoFile(final Folder folder, final Folder parentFolder) { try { final File pomFile = app.nodeQuery(File.class).andName("pom.xml") .and(StructrApp.key(File.class, "parent"), folder).getFirst(); if (pomFile != null) { handlePomFile(pomFile, folder, parentFolder); } final File packageFile = app.nodeQuery(File.class).andName("package-info.java") .and(StructrApp.key(Folder.class, "parent"), folder).getFirst(); if (packageFile != null) { handlePackageFolder(folder, parentFolder); } } catch (FrameworkException ex) { logger.error("Error in node query", ex); } } private void parseJavaFilesAndSolveTypes(final Folder folder) { if (ignoreTests && "test".equals(folder.getName())) { return; } for (final File file : folder.getFiles()) { if (file.getContentType().equals("text/x-java")) { final String javaFileName = file.getName(); if (javaFileName.equals("package-info.java") || javaFileName.equals("testPackage-info.java")) { } else { final String javaContent = file.getFavoriteContent(); ClassOrInterface clsOrIface = null; CompilationUnit cu = null; try { cu = JavaParser.parse(javaContent); for (final TypeDeclaration type : cu.findAll(TypeDeclaration.class)) { SymbolReference<? extends ResolvedValueDeclaration> decl = facade.solve(type.getName()); if (type.isClassOrInterfaceDeclaration()) { org.structr.javaparser.entity.Package pkg = null; if (cu.getPackageDeclaration().isPresent()) { pkg = handlePackage(cu.getPackageDeclaration().get()); } clsOrIface = handleClassOrInterface(type, pkg); } } for (final BodyDeclaration t : cu.findAll(BodyDeclaration.class)) { // if (t instanceof FieldDeclaration) { // // final FieldDeclaration fd = t.asFieldDeclaration(); // // final String fieldName = fd.getVariable(0).getNameAsString(); // logger.info("Field found: " + fieldName); // // final SymbolReference<ResolvedReferenceTypeDeclaration> fieldRef = typeSolver.tryToSolveType(fieldName); // if (fieldRef.isSolved()) { // // final ResolvedReferenceTypeDeclaration decl = fieldRef.getCorrespondingDeclaration(); // if (decl.isField()) { // // final ResolvedFieldDeclaration field = decl.asField(); // if (field.isMethod()) { // // logger.info("Solved method found: " + field.asMethod().getName()); // // } else if (field.isField()) { // // logger.info("Solved field found: " + field.getName() + ", declared by", field.declaringType().getName()); // } // } // } // } if (t instanceof CallableDeclaration) { final CallableDeclaration callable = t.asCallableDeclaration(); if (t instanceof ConstructorDeclaration) { // final ConstructorDeclaration cd = t.asConstructorDeclaration(); // logger.info("Constructor found: " + cd.getNameAsString()); // // final SymbolReference<ResolvedReferenceTypeDeclaration> constructorRef = typeSolver.tryToSolveType(cd.getNameAsString()); // if (constructorRef.isSolved()) { // // logger.info("Solved constructor: " + cd.getNameAsString()); // //final ResolvedReferenceTypeDeclaration decl = constructorRef.getCorrespondingDeclaration(); // } } else if (t instanceof MethodDeclaration) { final MethodDeclaration md = t.asMethodDeclaration(); final String methodName = md.getNameAsString(); logger.info("Method found: " + methodName); // Create methods and link to class final PropertyMap identifyingMethodProperties = new PropertyMap(); identifyingMethodProperties.put(Method.name, methodName); final PropertyMap methodProperties = new PropertyMap(); methodProperties.putAll(identifyingMethodProperties); methodProperties.put(Method.classOrInterface, clsOrIface); methodProperties.put(Method.declaration, md.getDeclarationAsString()); final Optional<BlockStmt> block = md.getBody(); if (block.isPresent()) { methodProperties.put(Method.body, block.get().toString()); } final String symbolName = StringUtils.substringAfterLast(clsOrIface.getName(), ".") + "." + md.getNameAsString(); //final String fullQualifiedSymbolName = cls.getProperty(JavaClass.packageProp).getName() + "." + symbolName; try { final SymbolReference<? extends ResolvedValueDeclaration> methodRef = facade .solve(md.getName()); if (methodRef.isSolved()) { final ResolvedValueDeclaration decl = methodRef .getCorrespondingDeclaration(); if (decl.isMethod()) { final String mName = decl.asMethod().getName(); final String signature = decl.asMethod().getSignature(); logger.info("Solved method: " + methodRef.toString() + ", signature: " + signature); methodProperties.put(Method.resolved, true); } } } catch (final UnsolvedSymbolException ignore) { } getOrCreate(Method.class, identifyingMethodProperties, methodProperties); logger.info("Created (or found) method " + symbolName); } // final NodeList<Parameter> parameters = callable.getParameters(); // // List<JsonResult> parameterList = new ArrayList<>(); // // parameters.forEach((p) -> { // // JsonResult param = new JsonResult(); // // param.addName(p); // param.addType(p.getType()); // param.addModifiers(p); // // parameterList.add(param); // }); } } } catch (Throwable ignore) { } } } } } public void analyzeMethodsInJavaFile(final String code, String clsName) { try { final CompilationUnit cu = JavaParser.parse(code); final Map<String, Object> params = new HashMap<>(); if (facade == null) { final CombinedTypeSolver typeSolver = new CombinedTypeSolver(); typeSolver.add(new ReflectionTypeSolver()); typeSolver.add(structrTypeSolver); facade = JavaParserFacade.get(typeSolver); } if (clsName == null) { try { clsName = cu.getType(0).getNameAsString(); } catch (final Exception ignore) { } } params.put("clsName", clsName); params.put("facade", facade); params.put("app", app); final MethodVisitorAdapter adapter = new MethodVisitorAdapter(); adapter.visit(cu, params); } catch (Throwable ignore) { } } public void analyzeMethodsInJavaFile(final String code) { analyzeMethodsInJavaFile(code, null); } private void analyzeMethodsInJavaFiles(final Folder folder) { if (ignoreTests && "test".equals(folder.getName())) { return; } for (final File file : folder.getFiles()) { if (file.getContentType().equals("text/x-java")) { final String javaFileName = file.getName(); if (!(javaFileName.equals("package-info.java") || javaFileName.equals("testPackage-info.java"))) { final String clsName = StringUtils.substringBeforeLast(javaFileName, ".java"); final String javaContent = file.getFavoriteContent(); analyzeMethodsInJavaFile(javaContent, clsName); } } } } private void handlePomFile(final File file, final Folder folder, final Folder parentFolder) { final XPath xpath = XPathFactory.newInstance().newXPath(); QName returnType = XPathConstants.STRING; final String content = file.getFavoriteContent(); final String projectName; try { projectName = (String) xpath.evaluate("/project/name", parseXml(content), returnType); final Module newMod = createModule(projectName, folder); logger.info("Created module '" + projectName + "' in folder " + folder.getPath()); // Check if we are child of a parent module // Find the closest ancestor folder which has a module Module mod = null; Folder possibleModuleParentFolder = parentFolder; // Continue until root folder or a module was found while (possibleModuleParentFolder != null && mod == null) { try { mod = app.nodeQuery(Module.class).and(Module.folder, possibleModuleParentFolder).getFirst(); } catch (FrameworkException ignore) { } if (mod != null) { newMod.setProperty(Module.parent, mod); break; } // Continue while loop possibleModuleParentFolder = possibleModuleParentFolder.getParent(); } } catch (ParserConfigurationException | SAXException | IOException | XPathExpressionException | FrameworkException ex) { logger.warn("Exception exception occured", ex); } } private ClassOrInterface handleClassOrInterface(final TypeDeclaration type, final org.structr.javaparser.entity.Package pkg) { final String name = (pkg != null ? pkg.getName() + "." : "") + type.getNameAsString(); logger.info("Parsing class or interface " + name); final PropertyMap identifyingProperties = new PropertyMap(); identifyingProperties.put(ClassOrInterface.name, name); if (pkg != null) { identifyingProperties.put(ClassOrInterface.packageProp, pkg); } ClassOrInterface clsOrIface = null; boolean isInterface = type.asClassOrInterfaceDeclaration().isInterface(); if (isInterface) { // Create Java interface clsOrIface = (JavaInterface) getOrCreate(JavaInterface.class, identifyingProperties, identifyingProperties); logger.info("Created (or found) interface " + clsOrIface.getName()); } else { // Create Java class clsOrIface = (JavaClass) getOrCreate(JavaClass.class, identifyingProperties, identifyingProperties); logger.info("Created (or found) class " + clsOrIface.getName()); } return clsOrIface; } private org.structr.javaparser.entity.Package handlePackage(final PackageDeclaration pkg) { final PropertyMap packageIdentifyingProperties = new PropertyMap(); packageIdentifyingProperties.put(org.structr.javaparser.entity.Package.name, pkg.getNameAsString()); org.structr.javaparser.entity.Package clsPackage = (org.structr.javaparser.entity.Package) getOrCreate( Package.class, packageIdentifyingProperties, packageIdentifyingProperties); if (clsPackage != null) { try { // Find corresponding folder final Folder packageFolder = app.nodeQuery(Folder.class).and(StructrApp.key(Folder.class, "path"), StringUtils.replaceAll(clsPackage.getName(), ".", "/")).getFirst(); if (packageFolder != null) { clsPackage.setProperty(Package.folder, packageFolder); } } catch (final FrameworkException ex) { } ; } return clsPackage; } private void handlePackageFolder(final Folder folder, final Folder parentFolder) { // Folder contains a package-info.java so it must be a package String[] parts = folder.getPath().split("src/main/java/"); // We look for the part after "src/main/java" if (parts.length > 1) { final PropertyMap identifyingProperties = new PropertyMap(); final PropertyMap allProperties = new PropertyMap(); // Convert path to package path String path = StringUtils.replaceAll(parts[1], "/", "."); identifyingProperties.put(Package.name, path); allProperties.putAll(identifyingProperties); allProperties.put(Package.folder, folder); // Check if we are contained in a module: // Find the closest ancestor folder which has a module Module mod = null; Package pkg = null; Folder possibleModuleParentFolder = parentFolder; // Continue until root folder or a module was found while (possibleModuleParentFolder != null && mod == null) { try { mod = app.nodeQuery(Module.class).and(Module.folder, possibleModuleParentFolder).getFirst(); pkg = app.nodeQuery(Package.class).and(Module.folder, possibleModuleParentFolder).getFirst(); } catch (FrameworkException ignore) { } if (pkg != null) { // Parent folder contains a package allProperties.put(Package.parent, pkg); } else if (mod != null) { // Parent folder contains a module allProperties.put(Package.module, mod); break; } // Continue while loop possibleModuleParentFolder = possibleModuleParentFolder.getParent(); } getOrCreate(Package.class, identifyingProperties, allProperties); logger.info("Created or found package '" + path + "' in folder " + folder.getPath()); } } private JsonResult toJson(final CompilationUnit cu) { final JsonResult jsonResult = new JsonResult(); final NodeList<TypeDeclaration<?>> types = cu.getTypes(); if (types.isEmpty()) { return jsonResult; } final TypeDeclaration<?> type = types.get(0); jsonResult.addName(type); jsonResult.addModifiers(type); final Optional<PackageDeclaration> pkg = cu.getPackageDeclaration(); if (pkg.isPresent()) { jsonResult.addPackage(pkg.get()); } final List<BodyDeclaration<?>> members = type.getMembers(); final List<JsonResult> membersList = new ArrayList<>(); members.forEach((t) -> { final JsonResult member = new JsonResult(); if (t instanceof FieldDeclaration) { final FieldDeclaration fd = t.asFieldDeclaration(); member.addName(fd.getVariable(0)); member.addType(fd.getVariable(0).getType()); member.addModifiers(fd); } else if (t instanceof CallableDeclaration) { final CallableDeclaration callable = t.asCallableDeclaration(); if (t instanceof ConstructorDeclaration) { final ConstructorDeclaration cd = t.asConstructorDeclaration(); member.addName(cd); member.isConstructor(); member.addModifiers(cd); } else if (t instanceof MethodDeclaration) { final MethodDeclaration md = t.asMethodDeclaration(); member.addName(md); member.isMethod(); member.addReturnType(md.getType()); member.addModifiers(md); member.addBody(md); } final NodeList<Parameter> parameters = callable.getParameters(); List<JsonResult> parameterList = new ArrayList<>(); parameters.forEach((p) -> { JsonResult param = new JsonResult(); param.addName(p); param.addType(p.getType()); param.addModifiers(p); parameterList.add(param); }); member.addParameters(parameterList); } membersList.add(member); }); jsonResult.addMembers(membersList); return jsonResult; } @Override public String getName() { return "java-parser"; } @Override public Set<String> getDependencies() { return new LinkedHashSet<>(); } @Override public Set<String> getFeatures() { return null; } @Override public void insertImportStatements(final AbstractSchemaNode schemaNode, final StringBuilder buf) { } @Override public void insertSourceCode(final AbstractSchemaNode schemaNode, final StringBuilder buf) { } @Override public Set<String> getInterfacesForType(final AbstractSchemaNode schemaNode) { return null; } @Override public void insertSaveAction(final AbstractSchemaNode schemaNode, final StringBuilder buf, final Actions.Type type) { } public class JsonResult { private JsonObject obj = new JsonObject(); private void addPackage(final PackageDeclaration pkg) { obj.add("package", new JsonPrimitive(getMemberName(pkg.getNameAsString()))); } private void addName(final NodeWithSimpleName<?> namedNode) { obj.add("name", new JsonPrimitive(namedNode.getNameAsString())); } private void addType(final Type type) { obj.add("type", new JsonPrimitive(type.asString())); } private void addReturnType(final Type type) { obj.add("returnType", new JsonPrimitive(type.asString())); } private void isConstructor() { obj.add("type", new JsonPrimitive("constructor")); } private void isMethod() { obj.add("type", new JsonPrimitive("method")); } private void addBody(final NodeWithOptionalBlockStmt node) { Optional<BlockStmt> block = node.getBody(); if (block.isPresent()) { obj.add("body", new JsonPrimitive(block.get().toString())); } } private void addModifiers(final NodeWithModifiers<?> type) { final JsonArray modifiers = new JsonArray(); type.getModifiers().forEach((m) -> { modifiers.add(new JsonPrimitive(m.asString())); }); obj.add("modifiers", modifiers); } private void addMembers(final List<JsonResult> list) { final JsonArray members = new JsonArray(); list.forEach((m) -> { members.add(m.get()); }); obj.add("members", members); } private void addParameters(final List<JsonResult> list) { final JsonArray parameters = new JsonArray(); list.forEach((m) -> { parameters.add(m.get()); }); obj.add("parameters", parameters); } private void add(final JsonResult obj) { obj.add(obj); } public JsonObject get() { return obj; } } private String getMemberName(final String rawName) { final String[] parts = StringUtils.split(rawName, " "); return StringUtils.strip(StringUtils.remove(parts[parts.length - 1], ";")); } private Document parseXml(final String xml) throws ParserConfigurationException, SAXException, IOException { final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); if (builder != null) { final StringReader reader = new StringReader(xml); final InputSource src = new InputSource(reader); return builder.parse(src); } return null; } }