Files
Aria/AriaCompiler/src/main/java/com/arialyy/compiler/ParamObtainUtil.java
2024-08-20 16:54:35 +08:00

277 lines
11 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* 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.
*/
package com.arialyy.compiler;
import com.arialyy.annotations.Download;
import com.arialyy.annotations.DownloadGroup;
import com.arialyy.annotations.TaskEnum;
import com.arialyy.annotations.Upload;
import java.lang.annotation.Annotation;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.Elements;
/**
* Created by lyy on 2017/9/6.
* 构建代理文件的参数获取工具
*/
class ParamObtainUtil {
private Map<String, ProxyClassParam> mMethodParams = new HashMap<>();
private Elements mElementUtil;
ParamObtainUtil(Elements elements) {
mElementUtil = elements;
}
/**
* 获取搜索到的代理方法参数
*/
Map<String, ProxyClassParam> getMethodParams() {
return mMethodParams;
}
/**
* 查找并保存扫描到的方法
*/
void saveMethod(TaskEnum taskEnum, RoundEnvironment roundEnv,
Class<? extends Annotation> annotationClazz, int annotationType) {
for (Element element : roundEnv.getElementsAnnotatedWith(annotationClazz)) {
ElementKind kind = element.getKind();
if (kind == ElementKind.METHOD) {
ExecutableElement method = (ExecutableElement) element;
TypeElement classElement = (TypeElement) method.getEnclosingElement();
PackageElement packageElement = mElementUtil.getPackageOf(classElement);
String methodName = method.getSimpleName().toString();
String className = method.getEnclosingElement().toString(); //全类名
String key = className + taskEnum.proxySuffix;
ProxyClassParam proxyEntity = mMethodParams.get(key);
MethodInfo methodInfo = new MethodInfo();
methodInfo.methodName = methodName;
methodInfo.params = (List<VariableElement>) method.getParameters();
if (taskEnum == TaskEnum.M3U8_PEER) {
checkM3U8PeerMethod(method, methodInfo.params);
} else {
checkTaskMethod(taskEnum, method, annotationClazz, methodInfo.params);
}
if (proxyEntity == null) {
proxyEntity = new ProxyClassParam();
proxyEntity.taskEnums = new HashSet<>();
proxyEntity.packageName = packageElement.getQualifiedName().toString();
proxyEntity.className = classElement.getSimpleName().toString();
proxyEntity.proxyClassName = proxyEntity.className + taskEnum.proxySuffix;
proxyEntity.mainTaskEnum = taskEnum;
if (taskEnum == TaskEnum.DOWNLOAD_GROUP_SUB || taskEnum == TaskEnum.DOWNLOAD_GROUP) {
proxyEntity.subTaskEnum = EntityInfo.DOWNLOAD;
}
mMethodParams.put(key, proxyEntity);
}
proxyEntity.taskEnums.add(taskEnum);
if (proxyEntity.methods.get(taskEnum) == null) {
proxyEntity.methods.put(taskEnum, new HashMap<Class<? extends Annotation>, MethodInfo>());
}
proxyEntity.methods.get(taskEnum).put(annotationClazz, methodInfo);
proxyEntity.keyMappings.put(methodName, getValues(taskEnum, method, annotationType));
}
}
}
/**
* 获取注解的内容
*/
private Set<String> getValues(TaskEnum taskEnum, ExecutableElement method, int annotationType) {
String[] keys = null;
switch (taskEnum) {
case DOWNLOAD:
keys = ValuesUtil.getDownloadValues(method, annotationType);
break;
case UPLOAD:
keys = ValuesUtil.getUploadValues(method, annotationType);
break;
case DOWNLOAD_GROUP:
keys = ValuesUtil.getDownloadGroupValues(method, annotationType);
break;
case DOWNLOAD_GROUP_SUB:
keys = ValuesUtil.getDownloadGroupSubValues(method, annotationType);
break;
case M3U8_PEER:
keys = ValuesUtil.getM3U8PeerValues(method, annotationType);
break;
}
return keys == null ? null : convertSet(keys);
}
/**
* 检查m3u8注解方法参数
*/
private void checkM3U8PeerMethod(ExecutableElement method, List<VariableElement> params) {
String methodName = method.getSimpleName().toString();
String className = method.getEnclosingElement().toString();
Set<Modifier> modifiers = method.getModifiers();
if (modifiers.contains(Modifier.PRIVATE)) {
throw new IllegalAccessError(String.format("%s.%s, 不能为private方法", className, methodName));
}
if (params.size() != 3
|| !params.get(0).asType().toString().equals(String.class.getName())
|| !params.get(1).asType().toString().equals(String.class.getName())
|| !params.get(2).asType().toString().equals("int")) {
throw new IllegalArgumentException(
String.format("%s.%s 的参数错误该方法需要的参数为String, String, int", className,
methodName));
}
}
/**
* 检查任务注解的相关参数如果被注解的方法为private或参数不合法或参数错误停止任务
*/
private void checkTaskMethod(TaskEnum taskEnum, ExecutableElement method,
Class<? extends Annotation> annotationClazz, List<VariableElement> params) {
String methodName = method.getSimpleName().toString();
String className = method.getEnclosingElement().toString();
Set<Modifier> modifiers = method.getModifiers();
if (modifiers.contains(Modifier.PRIVATE)) {
throw new IllegalAccessError(String.format("%s.%s, 不能为private方法", className, methodName));
}
if (taskEnum == TaskEnum.DOWNLOAD_GROUP_SUB) {
if (isFailAnnotation(annotationClazz)) {
if (params.size() < 2 || params.size() > 3) {
throw new IllegalArgumentException(
String.format("%s.%s参数错误, 参数只能是两个或三个,第一个参数是:%s第二个参数是%s第三个参数可选%s", className,
methodName,
getCheckParams(taskEnum), getCheckSubParams(taskEnum),
Exception.class.getSimpleName()));
}
if (params.size() == 2
&& (!params.get(0).asType().toString().equals(getCheckParams(taskEnum))
|| !params.get(1).asType().toString().equals(getCheckSubParams(taskEnum)))) {
throw new IllegalArgumentException(
String.format("%s.%s参数错误, 参数只能是两个或三个,第一个参数是:%s第二个参数是%s第三个参数可选%s", className,
methodName,
getCheckParams(taskEnum), getCheckSubParams(taskEnum),
Exception.class.getSimpleName()));
}
if (params.size() == 3
&& (!params.get(0).asType().toString().equals(getCheckParams(taskEnum))
|| !params.get(1).asType().toString().equals(getCheckSubParams(taskEnum))
|| !params.get(2).asType().toString().equals(Exception.class.getName()))) {
throw new IllegalArgumentException(
String.format("%s.%s参数错误, 参数只能是两个或三个,第一个参数是:%s第二个参数是%s第三个参数可选%s", className,
methodName,
getCheckParams(taskEnum), getCheckSubParams(taskEnum),
Exception.class.getSimpleName()));
}
} else {
if (params.size() == 2
&& (!params.get(0).asType().toString().equals(getCheckParams(taskEnum))
|| !params.get(1).asType().toString().equals(getCheckSubParams(taskEnum)))) {
throw new IllegalArgumentException(
String.format("%s.%s参数错误, 参数只能是两个或三个,第一个参数是:%s第二个参数是%s", className,
methodName,
getCheckParams(taskEnum), getCheckSubParams(taskEnum)));
}
}
} else {
if (isFailAnnotation(annotationClazz)) {
if (params.size() < 1 || params.size() > 2) {
throw new IllegalArgumentException(
String.format("%s.%s参数错误, 参数只能有一个或两个,第一个参数是:%s第二个参数可选%s", className, methodName,
getCheckParams(taskEnum), Exception.class.getSimpleName()));
}
if (params.size() == 1
&& (!params.get(0).asType().toString().equals(getCheckParams(taskEnum)))) {
throw new IllegalArgumentException(
String.format("%s.%s参数错误, 参数只能有一个或两个,第一个参数是:%s第二个参数可选%s", className, methodName,
getCheckParams(taskEnum), Exception.class.getSimpleName()));
}
if (params.size() == 2
&& (!params.get(0).asType().toString().equals(getCheckParams(taskEnum))
|| !params.get(1).asType().toString().equals(Exception.class.getName()))) {
throw new IllegalArgumentException(
String.format("%s.%s参数错误, 参数只能有一个或两个,第一个参数是:%s第二个参数可选%s", className, methodName,
getCheckParams(taskEnum), Exception.class.getSimpleName()));
}
} else {
if (params.size() != 1
&& !params.get(0).asType().toString().equals(getCheckParams(taskEnum))) {
throw new IllegalArgumentException(
String.format("%s.%s参数错误, 参数只能有一个,且参数必须是:%s", className, methodName,
getCheckParams(taskEnum)));
}
}
}
}
/**
* 判断是否是任务失败的回调注解
*
* @return @code true是任务失败的回调注解
*/
private boolean isFailAnnotation(Class<? extends Annotation> annotationClazz) {
return annotationClazz == Download.onTaskFail.class
|| annotationClazz == DownloadGroup.onTaskFail.class
|| annotationClazz == DownloadGroup.onSubTaskFail.class
|| annotationClazz == Upload.onTaskFail.class;
}
/**
* 字符串数组转set
*
* @param keys 注解中查到的key
*/
private Set<String> convertSet(final String[] keys) {
if (keys == null || keys.length == 0) {
return null;
}
if (keys[0].isEmpty()) return null;
Set<String> set = new HashSet<>();
Collections.addAll(set, keys);
return set;
}
private String getCheckParams(TaskEnum taskEnum) {
return taskEnum.pkg + "." + taskEnum.className;
}
/**
* 检查任务组子任务第二个参数
*/
private String getCheckSubParams(TaskEnum taskEnum) {
if (taskEnum == TaskEnum.DOWNLOAD_GROUP_SUB) {
return EntityInfo.DOWNLOAD.pkg + "." + EntityInfo.DOWNLOAD.className;
}
return "";
}
}