private static void loadProperties() {
        Map<String, ClassID> knownClassIds = new HashMap<>();
        for (TikaNameIdChunks.PredefinedPropertySet set : TikaNameIdChunks.PredefinedPropertySet.values()) {
            knownClassIds.put(set
                    .getClassID()
                    .toUUIDString(), set.getClassID());
        }
        for (TikaNameIdChunks.PropertySetType setType : TikaNameIdChunks.PropertySetType.values()) {
            knownClassIds.put(setType
                    .getClassID()
                    .toUUIDString(), setType.getClassID());
        }
        try (BufferedReader r = new BufferedReader(
                new InputStreamReader(ExtendedMetadataExtractor.class.getResourceAsStream("/org/apache/tika/parser/microsoft/msg/props_table.txt"), UTF_8))) {
            String line = r.readLine();
            while (line != null) {
                if (line.isBlank() || line.startsWith("#")) {
                    line = r.readLine();
                    continue;
                }
                String[] cols = line.split("\\|");
                if (cols.length != 11) {
                    throw new IllegalArgumentException("column count must == 11: " + line);
                }
                String name = cols[1].trim();
                ClassID classID = parseClassId(cols[3], knownClassIds);
                List<Types.MAPIType> types = parseDataTypes(cols[7].split(";"));
                String ref = cols[10];

                String shortId = cols[5];
                String longId = cols[6];
                if (!StringUtils.isBlank(shortId)) {
                    int id = Integer.parseInt(shortId.substring(2), 16);
                    List<TikaMapiProperty> props = TIKA_MAPI_PROPERTIES.computeIfAbsent(id, k -> new ArrayList<>());
                    props.add(new TikaMapiProperty(name, classID, types, ref));
                } else if (!StringUtils.isBlank(longId)) {
                    //remove leading "0x"
                    long id = Long.parseLong(longId.substring(2), 16);
                    if (id > Integer.MAX_VALUE) {
                        throw new IllegalArgumentException("id must actually be within int range");
                    }
                    int intId = (int) id;
                    List<TikaMapiProperty> props = TIKA_MAPI_LONG_PROPERTIES.computeIfAbsent(intId, k -> new ArrayList<>());
                    props.add(new TikaMapiProperty(name, classID, types, ref));
                } else {
                    // some properties don't have an id
                }

                line = r.readLine();
            }
        } catch (IOException e) {
            throw new IllegalStateException("can't find props_table.txt?!");
        }
    }
This class extracts mapi properties as defined in the props_table.txt, which was generated from MS-OXPROPS.
For now, this ignores binary and unknown property types.
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/msg/ExtendedMetadataExtractor.java