001package Torello.Java.JSON; 002 003import Torello.Java.StringParse; 004 005import java.lang.reflect.Array; 006 007import javax.json.JsonArray; 008import javax.json.JsonValue; 009 010import static javax.json.JsonValue.ValueType.*; 011 012public class ProcessMultiDimJsonArray 013{ 014 private ProcessMultiDimJsonArray() { } 015 016 @SuppressWarnings("unchecked") 017 018 /** 019 * This class is invoked by the class {@link RJArrDimN} 020 * 021 * @param <BASIC_TYPE> The "Component Type" of the Output-Array. 022 * 023 * @param <STREAM_TYPE> The "Intermediate Stream Type", which is present before the conversion 024 * to an Array. 025 * 026 * @param <RETURN_ARR_TYPE> The actual Return-Type of the method. This must be an Array-Class, 027 * such as {@code int[][].class} or (in the case of Boxed-Type Arrays) {@code Integer[][]}. 028 * 029 * @param ja Any instance of {@link JsonArray}. The contents sof this array should match the 030 * dimensionality of the expected Output-Array Type, or an exception will likelyy throw. 031 * 032 * @param rec 033 * @param retArrClass 034 * @return 035 */ 036 protected static <BASIC_TYPE, STREAM_TYPE, RETURN_ARR_TYPE> RETURN_ARR_TYPE jsonArrayToJava( 037 final JsonArray ja, 038 final SettingsRec<BASIC_TYPE, STREAM_TYPE> rec, 039 final Class<RETURN_ARR_TYPE> retArrClass 040 ) 041 { 042 // If this is requesting a one-dimensional array, get it using the 1D-Generator, 043 // and simply return that array. This requires a cast because there is no way to prove 044 // to the Java-Compiler that <T> is equal to any return-value at all. 045 // 046 // Remember that this is only guaranteed (it works!) because the helper methods are all 047 // protected or private, and it has been guaranteed through rigorous testing, and 048 // preventing the user from playing with it! 049 050 if (StringParse.countCharacters(retArrClass.getSimpleName(), '[') == 1) 051 return (RETURN_ARR_TYPE) rec.array1DGenerator.apply(ja); 052 053 054 // Otherwise, this is not a single-dimension (1D) array. Instead, the JsonArray needs 055 // to be iterated, and this method called, recursively, on each of the sub-arrays. 056 // 057 // NOTE: 'compClass' will also be an array, but with one fewer dimensions 058 059 final Class<?> compClass = retArrClass.getComponentType(); 060 final int SIZE = ja.size(); 061 final RETURN_ARR_TYPE retArr = (RETURN_ARR_TYPE) Array.newInstance(compClass, SIZE); 062 063 JsonValue jv = null; 064 065 for (int i=0; i < SIZE; i++) 066 067 switch ((jv = ja.get(i)).getValueType()) 068 { 069 // javax.json.JsonValue.ValueType.NULL 070 case NULL: Array.set(retArr, i, null); break; 071 072 // javax.json.JsonValue.ValueType.ARRAY (JsonArray) 073 case ARRAY: 074 075 Array.set( 076 retArr, 077 i, 078 JSON_ARRAY_DIMN.jsonArrayToJava((JsonArray) jv, rec, compClass) 079 ); 080 081 break; 082 083 // javax.json.JsonValue.ValueType.TRUE, FALSE, NUMBER, STRING, OBJECT 084 default: 085 086 if (rec.IN_NSAT) Array.set(retArr, i, null); 087 else if (rec.S_NSAT) continue; 088 else throw new JsonTypeArrException(ja, i, ARRAY, jv, retArrClass); 089 } 090 091 return retArr; 092 } 093}