Skip to content

Commit

Permalink
Merge pull request #522 from Fioooooooo/master
Browse files Browse the repository at this point in the history
packageFilters 参数支持到方法级别
  • Loading branch information
shalousun authored Jun 19, 2023
2 parents a931c04 + 34caa60 commit 2d09784
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 20 deletions.
2 changes: 2 additions & 0 deletions src/main/java/com/power/doc/constants/DocGlobalConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,6 @@ public interface DocGlobalConstants {
String SWAGGER_FILE_TAG = "formData";

String OPENAPI_TAG = "default";

String DEFAULT_FILTER_METHOD = "*";
}
13 changes: 9 additions & 4 deletions src/main/java/com/power/doc/template/IRestDocTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ default List<ApiDoc> processApiData(ProjectDocConfigBuilder projectBuilder, Fram
for (JavaClass cls : classes) {
if (StringUtil.isNotEmpty(apiConfig.getPackageFilters())) {
// from smart config
if (!DocUtil.isMatch(apiConfig.getPackageFilters(), cls.getCanonicalName())) {
if (!DocUtil.isMatch(apiConfig.getPackageFilters(), cls)) {
continue;
}
}
Expand All @@ -62,6 +62,7 @@ default List<ApiDoc> processApiData(ProjectDocConfigBuilder projectBuilder, Fram
setCustomOrder = true;
order = Integer.parseInt(strOrder);
}

List<ApiMethodDoc> apiMethodDocs = buildEntryPointMethod(cls, apiConfig, projectBuilder,
frameworkAnnotations, configApiReqParams, baseMappingHandler, headerHandler);
this.handleApiDoc(cls, apiDocList, apiMethodDocs, order, apiConfig.isMd5EncryptedHtmlName());
Expand Down Expand Up @@ -277,8 +278,7 @@ default List<ApiMethodDoc> buildEntryPointMethod(
FrameworkAnnotations frameworkAnnotations,
List<ApiReqParam> configApiReqParams,
IRequestMappingHandler baseMappingHandler,
IHeaderHandler headerHandler
) {
IHeaderHandler headerHandler) {
String clazName = cls.getCanonicalName();
boolean paramsDataToTree = projectBuilder.getApiConfig().isParamsDataToTree();
String group = JavaClassUtil.getClassTagsValue(cls, DocTags.GROUP, Boolean.TRUE);
Expand Down Expand Up @@ -306,6 +306,9 @@ default List<ApiMethodDoc> buildEntryPointMethod(
}
}

Set<String> filterMethods = DocUtil.findFilterMethods(clazName);
boolean needAllMethods = filterMethods.contains(DocGlobalConstants.DEFAULT_FILTER_METHOD);

List<JavaMethod> methods = cls.getMethods();
List<DocJavaMethod> docJavaMethods = new ArrayList<>(methods.size());
for (JavaMethod method : methods) {
Expand All @@ -315,7 +318,9 @@ default List<ApiMethodDoc> buildEntryPointMethod(
if (Objects.nonNull(method.getTagByName(IGNORE))) {
continue;
}
docJavaMethods.add(convertToDocJavaMethod(apiConfig, projectBuilder, method, null));
if (needAllMethods || filterMethods.contains(method.getName())) {
docJavaMethods.add(convertToDocJavaMethod(apiConfig, projectBuilder, method, null));
}
}
// add parent class methods
docJavaMethods.addAll(getParentsClassMethods(apiConfig, projectBuilder, cls));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public List<ApiDoc> getApiData(ProjectDocConfigBuilder projectBuilder) {
for (JavaClass cls : classes) {
if (StringUtil.isNotEmpty(apiConfig.getPackageFilters())) {
// from smart config
if (!DocUtil.isMatch(apiConfig.getPackageFilters(), cls.getCanonicalName())) {
if (!DocUtil.isMatch(apiConfig.getPackageFilters(), cls)) {
continue;
}
}
Expand Down Expand Up @@ -147,14 +147,19 @@ private List<ApiMethodDoc> buildControllerMethod(final JavaClass cls, ApiConfig
}
}

Set<String> filterMethods = DocUtil.findFilterMethods(clzName);
boolean needAllMethods = filterMethods.contains(DocGlobalConstants.DEFAULT_FILTER_METHOD);

List<JavaMethod> methods = cls.getMethods();
List<DocJavaMethod> docJavaMethods = new ArrayList<>(methods.size());
// filter private method
for (JavaMethod method : methods) {
if (method.isPrivate()) {
continue;
}
docJavaMethods.add(convertToDocJavaMethod(apiConfig, projectBuilder, method, null));
if (needAllMethods || filterMethods.contains(method.getName())) {
docJavaMethods.add(convertToDocJavaMethod(apiConfig, projectBuilder, method, null));
}
}
// add parent class methods
docJavaMethods.addAll(getParentsClassMethods(apiConfig, projectBuilder, cls));
Expand Down
12 changes: 9 additions & 3 deletions src/main/java/com/power/doc/template/RpcDocBuildTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public List<RpcApiDoc> getApiData(ProjectDocConfigBuilder projectBuilder) {
for (JavaClass cls : projectBuilder.getJavaProjectBuilder().getClasses()) {
if (StringUtil.isNotEmpty(apiConfig.getPackageFilters())) {
// check package
if (!DocUtil.isMatch(apiConfig.getPackageFilters(), cls.getCanonicalName())) {
if (!DocUtil.isMatch(apiConfig.getPackageFilters(), cls)) {
continue;
}
}
Expand Down Expand Up @@ -119,6 +119,10 @@ private List<RpcJavaMethod> buildServiceMethod(final JavaClass cls, ApiConfig ap
String clazName = cls.getCanonicalName();
List<JavaMethod> methods = cls.getMethods();
List<RpcJavaMethod> methodDocList = new ArrayList<>(methods.size());

Set<String> filterMethods = DocUtil.findFilterMethods(clazName);
boolean needAllMethods = filterMethods.contains(DocGlobalConstants.DEFAULT_FILTER_METHOD);

for (JavaMethod method : methods) {
if (method.isPrivate()) {
continue;
Expand All @@ -129,8 +133,10 @@ private List<RpcJavaMethod> buildServiceMethod(final JavaClass cls, ApiConfig ap
if (StringUtil.isEmpty(method.getComment()) && apiConfig.isStrict()) {
throw new RuntimeException("Unable to find comment for method " + method.getName() + " in " + cls.getCanonicalName());
}
RpcJavaMethod apiMethodDoc = convertToRpcJavaMethod(apiConfig, method, null);
methodDocList.add(apiMethodDoc);
if (needAllMethods || filterMethods.contains(method.getName())) {
RpcJavaMethod apiMethodDoc = convertToRpcJavaMethod(apiConfig, method, null);
methodDocList.add(apiMethodDoc);
}


}
Expand Down
130 changes: 119 additions & 11 deletions src/main/java/com/power/doc/utils/DocUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@
import org.apache.commons.lang3.StringUtils;

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Pattern;
Expand All @@ -58,10 +56,10 @@
*/
public class DocUtil {

private static Faker faker = new Faker(new Locale("en-US"));
private static Faker enFaker = new Faker(new Locale("en-US"));
private static final Faker faker = new Faker(new Locale("en-US"));
private static final Faker enFaker = new Faker(new Locale("en-US"));

private static Map<String, String> fieldValue = new LinkedHashMap<>();
private static final Map<String, String> fieldValue = new LinkedHashMap<>();

static {
fieldValue.put("uuid-string", UUID.randomUUID().toString());
Expand Down Expand Up @@ -126,6 +124,16 @@ public class DocUtil {
fieldValue.put("version-string", enFaker.app().version());
}

/**
* Cache the regex and its pattern object
*/
private static final Map<String, Pattern> patternCache = new HashMap<>();

/**
* "packageFilters" cache
*/
private static final Map<String, Set<String>> filterMethodCache = new HashMap<>();

/**
* Generate a random value based on java type name.
*
Expand All @@ -147,9 +155,7 @@ public static String jsonValueByType(String typeName) {
} else if ("Void".equals(type)) {
return "null";
} else {
StringBuilder builder = new StringBuilder();
builder.append("\"").append(value).append("\"");
return builder.toString();
return "\"" + value + "\"";
}
}

Expand Down Expand Up @@ -238,6 +244,110 @@ public static boolean isMatch(String packageFilters, String controllerName) {
return false;
}

/**
* match the controller package
*
* @param packageFilters package filter
* @param controllerClass controller class
* @return boolean
*/
public static boolean isMatch(String packageFilters, JavaClass controllerClass) {
if (StringUtil.isEmpty(packageFilters)) {
return false;
}

String controllerName = controllerClass.getCanonicalName();

String[] filters = packageFilters.split(",");

for (String filter : filters) {
if (filter.contains("*")) {
Pattern pattern = getPattern(filter);

// if the pattern matches the controller canonical name,
// that means the user want all methods in this controller
boolean matchControllerName = pattern.matcher(controllerName).matches();
if (matchControllerName) {
cacheFilterMethods(controllerName, Collections.singleton(DocGlobalConstants.DEFAULT_FILTER_METHOD));
return true;
} else {
// try to match the methods in this controller
List<String> controllerMethods = controllerClass.getMethods()
.stream()
.map(JavaMember::getName)
.collect(Collectors.toList());
Set<String> methodsMatch = controllerMethods.stream()
.filter(method -> pattern.matcher(controllerName + "." + method).matches())
.collect(Collectors.toSet());
if (!methodsMatch.isEmpty()) {
cacheFilterMethods(controllerName, methodsMatch);
return true;
}
}
} else if (controllerName.equals(filter) || controllerName.contains(filter)) {
// the filter is just the controller canonical name,
// or the controller is in a sub package
cacheFilterMethods(controllerName, Collections.singleton(DocGlobalConstants.DEFAULT_FILTER_METHOD));
return true;
} else if (filter.contains(controllerName)) {
// the filter is point to a method
String method = filter.replace(controllerName, "").replace(".", "");
cacheFilterMethods(controllerName, Collections.singleton(method));
return true;
}
}

return false;
}

/**
* Get pattern from the cache by a regex string.
* If there is no cache, then compile a new pattern object and put it into cache
*
* @param regex a regex string
* @return a usable pattern object
*/
private static Pattern getPattern(String regex) {
Pattern pattern = patternCache.get(regex);
if (pattern == null) {
pattern = Pattern.compile(regex);
patternCache.put(regex, pattern);
}
return pattern;
}

/**
* Put the specified method names into a cache.
*
* @param controller the controller canonical name
* @param methods the methods will be cached
*/
private static void cacheFilterMethods(String controller, Set<String> methods) {
filterMethodCache.put(controller, methods);
}

/**
* Get filter method name from cache, no cache will return "*", which means all methods.
*
* @param controller the controller canonical name
* @return the cached methods or "*"
*/
private static Set<String> getFilterMethodsCache(String controller) {
return filterMethodCache.getOrDefault(controller, Collections.singleton(DocGlobalConstants.DEFAULT_FILTER_METHOD));
}

/**
* Find methods if the user specified in "packageFilters".
* If not specified, return "*" by default, which means need all methods.
*
* @param controllerName controllerName
* @return the methods user specified
* @see #cacheFilterMethods(String, Set)
* @see #isMatch(String, JavaClass)
*/
public static Set<String> findFilterMethods(String controllerName) {
return getFilterMethodsCache(controllerName);
}

/**
* An interpreter for strings with named placeholders.
Expand Down Expand Up @@ -541,9 +651,7 @@ public static String replaceNewLineToHtmlBr(String content) {
}

public static String handleJsonStr(String content) {
StringBuilder builder = new StringBuilder();
builder.append("\"").append(content).append("\"");
return builder.toString();
return "\"" + content + "\"";
}

public static Map<String, String> formDataToMap(List<FormData> formDataList) {
Expand Down

0 comments on commit 2d09784

Please sign in to comment.