@@ -126,14 +126,55 @@ public int hashCode() {
126126 private static final Pattern METHOD_NAME_PATTERN = Pattern .compile ("^[_a-zA-Z][_a-zA-Z0-9]*$" );
127127 private static final Pattern FIELD_NAME_PATTERN = Pattern .compile ("^[_a-zA-Z][_a-zA-Z0-9]*$" );
128128
129- private final List <Whitelist > whitelists ;
129+ public static PainlessLookup buildFromWhitelists (List <Whitelist > whitelists ) {
130+ PainlessLookupBuilder painlessLookupBuilder = new PainlessLookupBuilder ();
131+ String origin = "internal error" ;
132+
133+ try {
134+ for (Whitelist whitelist : whitelists ) {
135+ for (WhitelistClass whitelistClass : whitelist .whitelistStructs ) {
136+ origin = whitelistClass .origin ;
137+ painlessLookupBuilder .addPainlessClass (
138+ whitelist .javaClassLoader , whitelistClass .javaClassName , whitelistClass .onlyFQNJavaClassName == false );
139+ }
140+ }
141+
142+ for (Whitelist whitelist : whitelists ) {
143+ for (WhitelistClass whitelistClass : whitelist .whitelistStructs ) {
144+ String targetCanonicalClassName = whitelistClass .javaClassName .replace ('$' , '.' );
145+
146+ for (WhitelistConstructor whitelistConstructor : whitelistClass .whitelistConstructors ) {
147+ origin = whitelistConstructor .origin ;
148+ painlessLookupBuilder .addPainlessConstructor (
149+ targetCanonicalClassName , whitelistConstructor .painlessParameterTypeNames );
150+ }
151+
152+ for (WhitelistMethod whitelistMethod : whitelistClass .whitelistMethods ) {
153+ origin = whitelistMethod .origin ;
154+ painlessLookupBuilder .addPainlessMethod (
155+ whitelist .javaClassLoader , targetCanonicalClassName , whitelistMethod .javaAugmentedClassName ,
156+ whitelistMethod .javaMethodName , whitelistMethod .painlessReturnTypeName ,
157+ whitelistMethod .painlessParameterTypeNames );
158+ }
159+
160+ for (WhitelistField whitelistField : whitelistClass .whitelistFields ) {
161+ origin = whitelistField .origin ;
162+ painlessLookupBuilder .addPainlessField (
163+ targetCanonicalClassName , whitelistField .javaFieldName , whitelistField .painlessFieldTypeName );
164+ }
165+ }
166+ }
167+ } catch (Exception exception ) {
168+ throw new IllegalArgumentException ("error loading whitelist(s) " + origin , exception );
169+ }
170+
171+ return painlessLookupBuilder .build ();
172+ }
130173
131174 private final Map <String , Class <?>> canonicalClassNamesToClasses ;
132175 private final Map <Class <?>, PainlessClassBuilder > classesToPainlessClassBuilders ;
133176
134- public PainlessLookupBuilder (List <Whitelist > whitelists ) {
135- this .whitelists = whitelists ;
136-
177+ public PainlessLookupBuilder () {
137178 canonicalClassNamesToClasses = new HashMap <>();
138179 classesToPainlessClassBuilders = new HashMap <>();
139180
@@ -666,60 +707,6 @@ public void addPainlessField(Class<?> targetClass, String fieldName, Class<?> ty
666707 }
667708
668709 public PainlessLookup build () {
669- String origin = "internal error" ;
670-
671- try {
672- // first iteration collects all the Painless type names that
673- // are used for validation during the second iteration
674- for (Whitelist whitelist : whitelists ) {
675- for (WhitelistClass whitelistStruct : whitelist .whitelistStructs ) {
676- String painlessTypeName = whitelistStruct .javaClassName .replace ('$' , '.' );
677- PainlessClassBuilder painlessStruct =
678- classesToPainlessClassBuilders .get (canonicalClassNamesToClasses .get (painlessTypeName ));
679-
680- if (painlessStruct != null && painlessStruct .clazz .getName ().equals (whitelistStruct .javaClassName ) == false ) {
681- throw new IllegalArgumentException ("struct [" + painlessStruct .name + "] cannot represent multiple classes " +
682- "[" + painlessStruct .clazz .getName () + "] and [" + whitelistStruct .javaClassName + "]" );
683- }
684-
685- origin = whitelistStruct .origin ;
686- addPainlessClass (
687- whitelist .javaClassLoader , whitelistStruct .javaClassName , whitelistStruct .onlyFQNJavaClassName == false );
688-
689- painlessStruct = classesToPainlessClassBuilders .get (canonicalClassNamesToClasses .get (painlessTypeName ));
690- classesToPainlessClassBuilders .put (painlessStruct .clazz , painlessStruct );
691- }
692- }
693-
694- // second iteration adds all the constructors, methods, and fields that will
695- // be available in Painless along with validating they exist and all their types have
696- // been white-listed during the first iteration
697- for (Whitelist whitelist : whitelists ) {
698- for (WhitelistClass whitelistStruct : whitelist .whitelistStructs ) {
699- String painlessTypeName = whitelistStruct .javaClassName .replace ('$' , '.' );
700-
701- for (WhitelistConstructor whitelistConstructor : whitelistStruct .whitelistConstructors ) {
702- origin = whitelistConstructor .origin ;
703- addPainlessConstructor (painlessTypeName , whitelistConstructor .painlessParameterTypeNames );
704- }
705-
706- for (WhitelistMethod whitelistMethod : whitelistStruct .whitelistMethods ) {
707- origin = whitelistMethod .origin ;
708- addPainlessMethod (whitelist .javaClassLoader , painlessTypeName , whitelistMethod .javaAugmentedClassName ,
709- whitelistMethod .javaMethodName , whitelistMethod .painlessReturnTypeName ,
710- whitelistMethod .painlessParameterTypeNames );
711- }
712-
713- for (WhitelistField whitelistField : whitelistStruct .whitelistFields ) {
714- origin = whitelistField .origin ;
715- addPainlessField (painlessTypeName , whitelistField .javaFieldName , whitelistField .painlessFieldTypeName );
716- }
717- }
718- }
719- } catch (Exception exception ) {
720- throw new IllegalArgumentException ("error loading whitelist(s) " + origin , exception );
721- }
722-
723710 copyPainlessClassMembers ();
724711 cacheRuntimeHandles ();
725712 setFunctionalInterfaceMethods ();
0 commit comments