001package net.gdface.sdk; 002 003import java.util.Collections; 004import java.util.HashMap; 005import java.util.Iterator; 006import java.util.LinkedHashMap; 007import java.util.LinkedList; 008import java.util.List; 009import java.util.Map; 010import java.util.ServiceLoader; 011 012import net.gdface.utils.Judge; 013import static net.gdface.utils.SimpleLog.log; 014import static net.gdface.sdk.CapacityFieldConstant.C_SDK_VERSION; 015 016/** 017 * FaceApi应用上下文SPIåŠ è½½å·¥å…·ç±» 018 * @author guyadong 019 * 020 */ 021public class ContextLoader { 022 private static final Map<GlobalContextField, Object> globalContext = new HashMap<>(); 023 private final LinkedHashMap<String, FaceApiContext> classMap = new LinkedHashMap<>(); 024 private final LinkedHashMap<String, FaceApiContext> versionMap= new LinkedHashMap<>(); 025 /** 所有找到的 FaceApi 上下文实例 */ 026 public final List<FaceApiContext> CONTEXTS ; 027 // å»¶è¿ŸåŠ è½½çš„å•实例 028 private static class Singleton{ 029 static final ContextLoader INSTANCE = new ContextLoader(); 030 } 031 /** 032 * å…¨å±€ä¸Šä¸‹æ–‡å—æ®µå®šä¹‰ 033 */ 034 public static enum GlobalContextField{ 035 /** å¹¶å‘é™åˆ¶ [int]*/CONCURRENCY, 036 /** 人脸检测倾å‘, [boolean] true:多人脸检测,false:用于帧相关å•人脸检测 */MULIT_FACE_DETECT_TREND 037 } 038 /** 039 * ä¸Šä¸‹æ–‡å—æ®µå®šä¹‰ 040 */ 041 public static enum ContextField{ 042 /** {@link FaceApi}实例 */INSTANCE, 043 /** 授æƒç®¡ç†å™¨(LicenceManager)实例 */LICENCE_MANAGER; 044 @SuppressWarnings("unchecked") 045 public <T>T from(FaceApiContext context){ 046 return (T) context.getContext().get(this); 047 } 048 } 049 public static final ContextLoader getInstance(){ 050 return Singleton.INSTANCE; 051 } 052 private ContextLoader() { 053 // SPI åŠ è½½æ‰€æœ‰ FaceApi 上下文实例 054 ServiceLoader<FaceApiContext> providers = ServiceLoader.load(FaceApiContext.class); 055 LinkedList<FaceApiContext> list = new LinkedList<>(); 056 for(Iterator<FaceApiContext> itor = providers.iterator();itor.hasNext();){ 057 FaceApiContext context = itor.next(); 058 list.add(context); 059 FaceApi instance = ContextLoader.ContextField.INSTANCE.<FaceApi>from(context); 060 if(instance == null){ 061 // 跳过接å£å®žä¾‹ä¸ºç©ºçš„并报错 062 log("ERROR:FaceApi instance of {} is null",context.getClass().getName()); 063 continue; 064 } 065 classMap.put(instance.getClass().getName(), context); 066 String sdkVersion = instance.sdkCapacity().get(C_SDK_VERSION); 067 if(!Judge.isEmpty(sdkVersion)){ 068 versionMap.put(sdkVersion, context); 069 } 070 } 071 CONTEXTS = Collections.unmodifiableList(list); 072 } 073 /** 074 * 返回找到的第一个FaceApi应用上下文实例 075 * @return FaceApi应用上下文实例,找ä¸åˆ°è¿”回{@code null} 076 */ 077 public FaceApiContext getContext(){ 078 try { 079 return CONTEXTS.get(0); 080 } catch (IndexOutOfBoundsException e) { 081 return null; 082 } 083 } 084 /** 085 * 返回找到的第一个FaceApi应用上下文实例 086 * @return FaceApi应用上下文实例 087 * @throws IllegalStateException 找ä¸åˆ°FaceApi应用上下文实例 088 */ 089 public FaceApiContext getContextChecked(){ 090 try { 091 return CONTEXTS.get(0); 092 } catch (IndexOutOfBoundsException e) { 093 throw new IllegalStateException("NOT FOUND any " + FaceApiContext.class.getSimpleName() + " instance"); 094 } 095 } 096 /** 097 * è¿”å›žåŒ…å«æŒ‡å®šFaceApi实例类å的应用上下文 098 * @param className FaceApi实例类å(å…¨å) 099 * @return FaceApi应用上下文实例,找ä¸åˆ°è¿”回{@code null} 100 */ 101 public FaceApiContext getContextByInstnaceClass(String className){ 102 return classMap.get(className); 103 } 104 /** 105 * è¿”å›žåŒ…å«æŒ‡å®šFaceApi实例类å的应用上下文 106 * @param className FaceApi实例类å(å…¨å) 107 * @return FaceApi应用上下文实例 108 * @throws IllegalArgumentException 找ä¸åˆ°æŒ‡å®šçš„上下文实例 109 */ 110 public FaceApiContext getContextByInstnaceClassChecked(String className){ 111 FaceApiContext context = classMap.get(className); 112 if(context == null){ 113 throw new IllegalArgumentException("INVALID instance class name: " + className); 114 } 115 return context; 116 } 117 /** 118 * è¿”å›žæ”¯æŒæŒ‡å®šSDK版本å·çš„应用上下文 119 * @param className SDKç‰ˆæœ¬å· 120 * @return FaceApi应用上下文实例,找ä¸åˆ°è¿”回{@code null} 121 */ 122 public FaceApiContext getContextBySdkVersion(String sdkVersion){ 123 return versionMap.get(sdkVersion); 124 } 125 /** 126 * è¿”å›žæ”¯æŒæŒ‡å®šSDK版本å·çš„应用上下文 127 * @param className SDKç‰ˆæœ¬å· 128 * @return FaceApi应用上下文实例,找ä¸åˆ°è¿”回{@code null} 129 * @throws IllegalArgumentException 找ä¸åˆ°æŒ‡å®šçš„上下文实例 130 */ 131 public FaceApiContext getContextBySdkVersionChecked(String sdkVersion){ 132 FaceApiContext context = versionMap.get(sdkVersion); 133 if(context == null){ 134 throw new IllegalArgumentException("INVALID sdkVersion: " + sdkVersion); 135 } 136 return context; 137 } 138 /** 139 * 设置全局上下文,用于应用层在SDKåˆå§‹åŒ–剿Œ‡å®šåˆå§‹åŒ–傿•°<br> 140 * @param field 141 * @param value 142 */ 143 public static void setGlobalContext(GlobalContextField field,Object value){ 144 if(field != null && value != null){ 145 globalContext.put(field, value); 146 } 147 } 148 @SuppressWarnings("unchecked") 149 public static <T>T getGlobalcontext(GlobalContextField field) { 150 if(field != null ){ 151 return (T) globalContext.get(field); 152 } 153 return null; 154 } 155}