Return the preferred native library configuration options for the given class. First attempts to load any field of the interface type within the interface mapping, then checks the cache for any specified library options. If none found, a set of library options will be generated from the fields (by
(Class<?> type)
| 819 | * @return The options map |
| 820 | */ |
| 821 | public static Map<String, Object> getLibraryOptions(Class<?> type) { |
| 822 | Map<String, Object> libraryOptions; |
| 823 | // cached already ? |
| 824 | libraryOptions = typeOptions.get(type); |
| 825 | if (libraryOptions != null) { |
| 826 | return libraryOptions; |
| 827 | } |
| 828 | |
| 829 | Class<?> mappingClass = findEnclosingLibraryClass(type); |
| 830 | if (mappingClass != null) { |
| 831 | loadLibraryInstance(mappingClass); |
| 832 | } else { |
| 833 | mappingClass = type; |
| 834 | } |
| 835 | |
| 836 | libraryOptions = typeOptions.get(mappingClass); |
| 837 | if (libraryOptions != null) { |
| 838 | typeOptions.put(type, libraryOptions); // cache for next time |
| 839 | return libraryOptions; |
| 840 | } |
| 841 | |
| 842 | try { |
| 843 | Field field = mappingClass.getField("OPTIONS"); |
| 844 | field.setAccessible(true); |
| 845 | libraryOptions = (Map<String, Object>) field.get(null); |
| 846 | if (libraryOptions == null) { |
| 847 | throw new IllegalStateException("Null options field"); |
| 848 | } |
| 849 | } catch (NoSuchFieldException e) { |
| 850 | libraryOptions = Collections.<String, Object>emptyMap(); |
| 851 | } catch (Exception e) { |
| 852 | throw new IllegalArgumentException("OPTIONS must be a public field of type java.util.Map (" + e + "): " + mappingClass); |
| 853 | } |
| 854 | // Make a clone of the original options |
| 855 | libraryOptions = new HashMap<>(libraryOptions); |
| 856 | if (!libraryOptions.containsKey(Library.OPTION_TYPE_MAPPER)) { |
| 857 | libraryOptions.put(Library.OPTION_TYPE_MAPPER, lookupField(mappingClass, "TYPE_MAPPER", TypeMapper.class)); |
| 858 | } |
| 859 | if (!libraryOptions.containsKey(Library.OPTION_STRUCTURE_ALIGNMENT)) { |
| 860 | libraryOptions.put(Library.OPTION_STRUCTURE_ALIGNMENT, lookupField(mappingClass, "STRUCTURE_ALIGNMENT", Integer.class)); |
| 861 | } |
| 862 | if (!libraryOptions.containsKey(Library.OPTION_STRING_ENCODING)) { |
| 863 | libraryOptions.put(Library.OPTION_STRING_ENCODING, lookupField(mappingClass, "STRING_ENCODING", String.class)); |
| 864 | } |
| 865 | libraryOptions = cacheOptions(mappingClass, libraryOptions, null); |
| 866 | // Store the original lookup class, if different from the mapping class |
| 867 | if (type != mappingClass) { |
| 868 | typeOptions.put(type, libraryOptions); |
| 869 | } |
| 870 | return libraryOptions; |
| 871 | } |
| 872 | |
| 873 | private static Object lookupField(Class<?> mappingClass, String fieldName, Class<?> resultClass) { |
| 874 | try { |