/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package com.emc.apidocs.processing; import com.emc.apidocs.generating.ExampleLoader; import com.emc.apidocs.model.ApiField; import com.emc.apidocs.model.ApiMethod; import com.emc.apidocs.model.ApiService; import com.google.common.collect.Maps; import org.apache.commons.io.IOUtils; import java.io.File; import java.io.FileInputStream; import java.util.Collection; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Look for Play! Route files and parse out the ApiService information */ public class PlayRoutesParser { private static Pattern docPattern = Pattern.compile("##begin\n" + "((## .*\n)*)" + // this is groups 1 and 2 "## @brief (.*)\n" + "(## @param (.*)\n)*" + "## @prereq (.*)\n" + "##end\n" + "([^\\s]*)\\s*([^\\s]*)\\s*(.*)"); private static Pattern paramPattern = Pattern.compile("## @param ([^ ]*)\\s(.*)"); public static Collection<ApiService> getPortalServices(String portalSrcRoot) { try { Map<String, ApiService> apiServices = Maps.newHashMap(); parse(new File(portalSrcRoot + "/conf/routes"), apiServices, ""); return apiServices.values(); } catch (Exception e) { throw new RuntimeException("Error reading portal services", e); } } private static void parse(File routeFile, Map<String, ApiService> services, String moduleRoot) throws Exception { byte[] bytes = IOUtils.toByteArray(new FileInputStream(routeFile)); String file = new String(bytes); Matcher serviceMatcher = docPattern.matcher(file); while (serviceMatcher.find()) { int groupCount = serviceMatcher.groupCount(); String className = getClassName(serviceMatcher.group(groupCount)); String packageName = getPackage(serviceMatcher.group(groupCount)); ApiService apiService = null; if (services.containsKey(className)) { apiService = services.get(className); } else { apiService = new ApiService(); apiService.packageName = packageName; apiService.javaClassName = className; apiService.description = ""; apiService.path = moduleRoot + "/api"; services.put(className, apiService); } if (!serviceMatcher.group(groupCount - 1).endsWith("{<json|xml>format}")) { ApiMethod apiMethod = new ApiMethod(); apiMethod.javaMethodName = getMethodName(serviceMatcher.group(serviceMatcher.groupCount())); apiMethod.httpMethod = serviceMatcher.group(groupCount - 2); apiMethod.path = moduleRoot + serviceMatcher.group(groupCount - 1); apiMethod.description = serviceMatcher.group(1).replaceAll("## ", ""); apiMethod.brief = serviceMatcher.group(3); apiMethod.apiService = apiService; apiMethod.alert = "<b>Note:</b> Hosted on HTTPS port 443"; apiMethod.xmlExample = ExampleLoader.loadExample(apiMethod.getXmlExampleFilename()); apiMethod.jsonExample = ExampleLoader.loadExample(apiMethod.getJsonExampleFilename()); addParameterInfo(serviceMatcher.group(0), apiMethod); apiService.addMethod(apiMethod); } } } private static void addParameterInfo(String javadocText, ApiMethod method) { Matcher paramMatcher = paramPattern.matcher(javadocText); while (paramMatcher.find()) { if (paramMatcher.group(1).equals("response")) { method.responseDescription = paramMatcher.group(2); } else { ApiField field = new ApiField(); field.name = paramMatcher.group(1); field.description = paramMatcher.group(2); if (method.path.contains("{" + field.name + "}")) { method.pathParameters.add(field); } else { method.queryParameters.add(field); } } } } private static String getClassName(String qualifiedName) { String[] parts = qualifiedName.split("\\."); return parts[parts.length - 2].replace("Api", "Service"); } private static String getMethodName(String qualifiedName) { String[] parts = qualifiedName.split("\\."); return parts[parts.length - 1]; } private static String getPackage(String qualifiedName) { return qualifiedName.substring(0, qualifiedName.lastIndexOf(".")); } }